#clojure log - Mar 24 2010

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:01 psykotic: seriously. torus trooper.

0:02 tomoj: mabes: in the solitaire I know, you can only see the cards that get turned face up, not the whole deck

0:03 that paper discusses "Thoughtful Solitaire" where you can see the whole deck?

0:04 defn: Licenser: you around?

0:06 mabes: tomoj: right with Thoughful Solitaire you can see every card.. no matter where it is. That way you can try to strategize your moves and it leaves things less up to chance

0:10 hrm.. so if I rename my protocol to IStupid it works.. maybe there is an issue with the type being Card and the protocol being ICard?

0:19 Raynes: clojurebot: sexp > you

0:19 clojurebot: <monads> is "yea, though I should walk in the valley of imperative code, I shall fear no evil, for your monad comforts me" - seen in #haskell

0:19 Raynes: sexpbot*

0:46 rem7: at the beginig of the "Programming Clojure" book there is an exercise where you say "hello back" to a user when he is already in a ref. You can 'alter' the ref with 'conj'... how do you do the opposite? say I wanna remove a user...

0:46 technomancy: rem7: depends on what's inside the ref

0:46 psykotic: rem7: if you use a set, you can use disj

0:47 rem7: another ref...

1:03 psykotic: thanks that worked

1:44 joshua-choi: Is anyone using a bare REPL with JLine and no IDE? I'm encountering a weird bug where (assuming I have a history) if I press up twice and down once, my cursor skips to the left and starts overwriting incorrectly.

1:45 defn: ahhh, to parse 300MB of text for IP addresses and then count the number of occurrences for each unique

1:45 any tips?

1:46 joshua-choi: I know how I'd try doing it in Java (with Scanners)...but I don't know if there are any better Clojure ways.

1:46 defn: that's sort of the path im looking at (doing it in pure clojure)

1:46 joshua-choi: I should really look at clojure.contrib carefully someday

1:47 defn: ive read through alex osbourne's widefinder 2 implementation, and while it looks like it works beautifully -- im not comfortable using that code without knowing how it all works. there is a lot of java going on which I don't fully understand

1:47 I'm trying to do something "good enough" with just clojure and a sprinkle of java

1:48 joshua-choi: Have you looked at clojure.contrib.io/read-lines?

1:48 It seems to create a lazy sequence of a file's lines

1:48 Though I don't know how that'll perform with 300 MB

1:50 defn: *nod*

1:51 my main problem so far has been tallying uniques

1:52 (count (read-lines (java.io.File. "myfile"))) is enough to hang me it seems

1:52 joshua-choi: That's unfortunate...I wonder why—if it's lazy, shouldn't it be fine?

1:53 Oh, you're using count.

1:53 defn: Is there a better way to know the length?

1:53 joshua-choi: Well, hang on...does count hold onto the head?

1:53 Chousuke: it shouldn't.

1:53 joshua-choi: Hmm

1:53 defn: im running 1.1.0 FWIW

1:54 it's definitely a lazy-seq

1:55 joshua-choi: How does count work anyway? Does it increment a number while discarding each element?

1:55 I can't tell from the source

1:58 defn: perhaps I need a line-seq

2:00 joshua-choi: What do you mean?

2:00 defn: I'm just grasping at straws here :)

2:01 psykotic: joshua-choi: it's technically container specific. LazySeq does the equivalent of (loop [s (seq coll), n 0] (if s (recur (next s) (inc n)) n))

2:01 defn: ,(< 0 (.indexOf "abc" "b"))

2:01 clojurebot: true

2:01 defn: ,(< 0 (.indexOf "abc" "q"))

2:01 clojurebot: false

2:01 joshua-choi: Okay, so LazySeq's count method does increment and discard.

2:02 Why would it hang, then?

2:02 defn: Does your JVM run out of memory?

2:02 ynef: newbie question: I want to return the number of days in a month for a given year. I already have a function called "is-leap-year?". How should I write the "(defn days-in-month [year month] ..." function? (this is not homework, btw: I'm learning Clojure by doing ProjectEuler problems)

2:03 defn: joshua-choi: i think it may just break my REPL -- it's not clear what is going wrong -- I just get "Evaulation Aborted" in my REPL after awhile

2:03 I've sent *print-length* sufficiently low to avoid the printer from going nuts and killing something

2:03 s/sent/set

2:05 ynef: my idea way "make a list of numbers and for february do a (if (is-leap-year? year) (29) (28)) and return 'eval' on (nth month) on that list" -- however, that did not work, since "year" cannot be referenced at that point(?)

2:05 s/way/was

2:05 (also, pardon my English, not a native speaker)

2:06 psykotic: defn: how big is 'myfile'?

2:06 defn: 300MB

2:06 joshua-choi: ynef: I'd (def regular-month-days {1 31, 3 31, 4 30, ...}) (defn february-days [year] ...) (defn days-in-month [year month] (or (regular-month-days month) (february-days year)).

2:07 psykotic: defn: i posted my trace-seq on the mailing list. did you see that?

2:07 it always use it for things like this, to monitor progress.

2:07 defn: psykotic: i did not see that but i will check it out immediately

2:08 psykotic: i'll gist it

2:08 ynef: joshua-choi: that's really nice, thanks!

2:08 defn: psykotic: thanks buddy

2:09 noidi: bleh, freenode sucks

2:09 Irssi: Your nick is owned by (my name)

2:09 #clojure Cannot change nickname while banned on channel

2:09 defn: yeah i find that a bit annoying as well noidi

2:09 noidi: and I couldn't identify as myself for having the wrong nick

2:11 for the guy asking about his date functions, you could build the map in the function, then you could use the year variable in your map

2:11 (I lost my lastlog when freenode made me part the channel) :P

2:14 defn: psykotic: ping me when you've gisted please

2:14 psykotic: ok

2:15 joshua-choi: I am now fully convinced of the REPL's usefulness after having used it with JLine for a week

2:15 I don't know how I survived by running tests repeatedly

2:15 defn: ill be more convinced of the REPL's usefulness once it quits breaking on me ;)

2:16 joshua-choi: Is there a way to monitor the JVM's memory in realtime?

2:17 defn: good question

2:18 bobo_: jconsole/jvisualvm

2:18 joshua-choi: Ah

2:24 defn: psykotic: any luck? I can't seem to find it with google

2:24 ynef: noidi: how would I do that (I'm the date function guy)? I'm a complete newbie in all things related to LISP :-)

2:24 psykotic: defn: i'm having a bad internet connection right now, so gist is difficult. i'll privmsg you, it's only a few lines

2:31 noidi: ynef, (defn days-in-month [month year] ({1 31, 2 (if (is-leap-year? year) 29 28), 3 31, ...} month))

2:31 or something like that

2:32 joshua-choi: I have a question on iterate and lazy-seq, at http://github.com/richhickey/clojure/blob/49a7d6b8e14050a45df5332e768ba6647752215d/src/clj/clojure/core.clj#L2012

2:32 iterate calls itself within a lazy-seq form. Does iterate increase the stack for every element in the sequence it's called with?

2:32 noidi: ynef, of course you could extract the map generation into its own function and just do ((days-in-months 2010) 3)

2:37 psykotic: joshua-choi: no. think about when the lazy-seq thunk is actually called.

2:37 joshua-choi: in effect, the "stack" is reified as the lists that cache the lazy-seq cells. if you throw away the head as you traverse it, there's no increasing memory consumption.

2:39 joshua-choi: psykotic: Yeah, I see. Thansk.

2:39 Well, calling (->> 3 (iterate inc) (drop 100000000) first) still seems to freeze my REPL. I wonder if it's because of memory or if it's just taking a long time for some reason.

2:39 psykotic: i can see why that isn't totally obvious because of lazy-seq's implicit thunking

2:40 joshua-choi: you're having to traverse a 100 hundred cons cells and associated lazy generation logic.

2:40 err, 100 million

2:40 joshua-choi: I see

2:40 It's because of object creation

2:41 Wait, no...um, is that right?

2:41 psykotic: well, even if there was no heap allocation, you're still looking at a hundred million iterations of something

2:41 even adding a hundred million numbers takes a bit of time, and this is heavier weight

2:41 joshua-choi: I see

2:42 I've been trying to figure out how to create my own lazy sequences

2:42 psykotic: it's not that different from creating eager sequences.

2:42 joshua-choi: Namely, I have a parser, and I want to be able to get a lazy sequence of all the matches inside a string.

2:42 I don't want to have to resort to state monads.

2:43 I'm going to sleep now. Thanks a lot for your help.

2:43 psykotic: sounds like... the list monad :)

2:43 joshua-choi: Well...

2:43 What does the list monad do?

2:43 psykotic: the usual parser monad is state + list, but you can retain the list part and be explicit about the state plumbing (the remaining chars to parse)

2:43 it effectively does backtracking search

2:43 joshua-choi: Oh

2:44 Yeah, that's what I'm talking about

2:44 Though it's vectors in clojure.contrib.monads, I think

2:44 psykotic: clojure's for macro is basically 'do' notation for the list monad

2:44 joshua-choi: Wait, no

2:44 Ah

2:44 You're talking about the seq monad

2:44 psykotic: yes

2:44 joshua-choi: Which is...the same thing, right

2:44 :)

2:44 psykotic: modulo the abstraction, yeah,

2:44 i was trying to use a term you might have heard elsewhere

2:45 anyway, you don't need to use the monadic magic for this, you can do it manually.

2:45 joshua-choi: Yeah

2:45 Though I'm going to have to sketch this out yeargh

2:45 Thanks a lot; have a good night

2:45 psykotic: for example, let's say you write your parser functions as taking the sequence of outstanding characters and returning a vector of the result and the new outstanding characters (i.e. with the consumed ones unconsed)

2:45 then you can do something like this:

2:46 joshua-choi: Hmm

2:46 psykotic: (for [[m s] (parse-number s)

2:46 [n s] (parse-number s)]

2:46 [(+ m n) s)

2:46 that would parse two successive numbers and return their sum, while consuming the parsed characters

2:46 joshua-choi: What does parse-number return?

2:47 psykotic: with something like parsec in haskell, the 'threading' of the s value would be implicit (that's what the state monad does).

2:47 joshua-choi: Ah, I never realized that

2:47 psykotic: like i said, a vector of two elements: the first the integer it parsed (assuming success), and the second the remainder of the parsed string

2:47 joshua-choi: Well, I know about that—but I never thought about the list monad in that way

2:47 psykotic: hehe

2:48 Chousuke: heh

2:48 joshua-choi: Well, I'm actually not seeing how your code works

2:48 psykotic: it annoys me when people poo poo monad. they're not some crutch, they're an abstracting way of very common boilerplate patterns like this.

2:48 Chousuke: I wrote a toy monad implementation which allowed extending ISeq to the monad protocol:P

2:48 joshua-choi: It looks like it would return something like ([1 (3 2)] [3 (2)] [2 nil])

2:48 Chousuke: it was fun to write ((lift +) '(1 2) '(3 4))

2:49 psykotic: joshua-choi: here's a quick example.

2:49 let's say the initial s is "42 8"

2:49 ynef: noidi: when I tried that with lists (sorry for the late response) rather than a map, it didn't work -- is that because lists are evaluated immediately and maps aren't or something?

2:49 psykotic: after binding [m s] (parse-number s), m would be 42 (the integer, not the string containing 42), and s would be " 8"

2:49 after binding [n s] (parse-number s), n would be 8, and s would be ""

2:49 Chousuke: ynef: it's the other way usually.

2:49 psykotic: get it?

2:50 Chousuke: ynef: lists can actually be lazy sequences, maps can't

2:51 psykotic: chousuke: although i think there is a map implementation in contrib that has lazy values. (lazy keys aren't useful since any operation on a map requires forcing all keys).

2:51 ynef: Chousuke: ok, thank you :-)

2:51 I'm already learning a lot here :-)

2:52 joshua-choi: Hang on, sorry. Let's say (parse-number "32 1") returns [32 " 1"]. Shouldn't the for macro iterate over both 32 and " 1"?

2:52 psykotic: sorry, i should emphasize that these functions actually return _seqs_ of parses

2:53 so in the case of an unambiguous parse, it would return [[32 " 1"]]

2:53 in which case the 'for binding' is really the same as a let

2:53 but when there are multiple parses, it tries all of them

2:53 joshua-choi: Oh, we're dealing with ambiguous grammars now. Yay. :P

2:53 psykotic: well, you mentioned you wanted to return a lazy seq of all parsers

2:54 joshua-choi: Ah, I was unclear

2:54 psykotic: err parses

2:54 joshua-choi: More in the vein of regular expressions

2:54 As in...

2:54 psykotic: ah. yeah, that's somewhat different. :)

2:54 joshua-choi: (find parse-number "32astienrat1aienrsitenst5") -> (32 1 5)

2:55 That would be the first step to...

2:56 substitutions like (substitute inc parse-number "s32arsien5##2") -> (\s 33 \a \r ...)

2:56 Someone actually requested that I implement something like that, like regexes

2:56 psykotic: right, i understand, the usual rex thing

2:56 joshua-choi: It's hard, though :(

2:56 psykotic: well, you can just try parsing starting at each prefix, et

2:56 although it depends on whether you accept overlapping parses

2:57 joshua-choi: I don't want to do it at every character, though

2:57 Yeah, no overlapping

2:57 I don't think that's what's usually wanted

2:57 So I was thinking that I'd have to use a state monad

2:57 psykotic: you never _need_ to use a state monad :)

2:58 usually explicit threading (e.g. the usual tail-recursive accumulator pattern) is better, if it suffices

2:58 joshua-choi: Yeah...

2:58 Yeah.

2:58 defn: im getting some really radically variable (time ...) results from a function... it is operating on the same data but still manages to jump between 0.5ms to 18.0ms

2:58 even with successive calls, so the JVM should be primsed

2:58 joshua-choi: Are you using -server? :P

2:58 noidi: ynef, vectors can be used as functions, but lists can not

2:58 * joshua-choi doesn't know what he's talking about

2:58 noidi: ,([1 2 (+ 2 2)] 2)

2:58 clojurebot: 4

2:58 psykotic: joshua-choi: anyway, i have to do some stuff, i'm sorry i rambled on this stuff with minimal relevance to your actual problem, as it turns out

2:58 noidi: ,((list 1 2 (+ 2 2)) 2)

2:58 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

2:58 joshua-choi: No, it's fine

2:58 You helped a lot

2:59 Have a good night

2:59 If that's where you live.

2:59 psykotic: i'm in bali right now, it's 3 pm :)

2:59 joshua-choi: Okay. Good day.

2:59 psykotic: later.

3:00 defn: from a performance standpoint should I be treating IPs as numbers or as strings?

3:01 Chousuke: I think usually they're stored as numbers, but of course you need the string representation sometimes

3:01 noidi: numbers are easier to validate

3:02 defn: im parsing from a logfile, so i need to have them as strings at first

3:02 but im wondering if at a certain point it makes sense to turn them into numbers

3:02 Chousuke: if you're going to do any processing on them, then yes.

3:03 but if you're just reading and counting occurrences or collecting other stats, maybe not.

3:03 though numbers take up less space than strings

3:03 psykotic: defn: my answer would be, sequences of numbers :)

3:03 Chousuke: psykotic: actually an IP address is a single number. :/

3:04 defn: here's basically the problem im struggling with... i have a big 300MB logfile. I go through and create a lazy-seq of lines which contain the word "Deny", now I would like to find all of the unique IPs which have been denied, so I think I am planning on creating a set which contains all of the uniques in the collection, finally, I am going to create a map where the keys are all of the elements of that resulting set

3:04 psykotic: Chousuke: yeah, i guess storing 4 bytes is just base 256 and not much more useful than base 2 :)

3:04 defn: then i am going to go back through the original data before it was turned into a set, and add up the occurrences in the map

3:04 does that sound like a good way to go about it or am I crazy?

3:05 Chousuke: why create a set? you could just create a map.

3:05 a key in a map is unique

3:05 defn: actually i dont think that's true

3:06 Chousuke: and if you need to associate data with it anyway, the set is kind of redundant.

3:06 defn: ,{:a 1 :a 2 :b 3}

3:06 clojurebot: {:a 1, :a 2, :b 3}

3:06 psykotic: he's trying to count duplicates/uniques

3:06 Chousuke: defn: that's not a valid map

3:06 psykotic: i think you want a multimap/multiset

3:06 fortunately it's easy to implement by just having sequences as keys

3:06 Chousuke: or a map of IP -> integer

3:06 psykotic: err, values

3:08 defn: http://gist.github.com/342052

3:09 that's pretty much as far as I've gotten -- kind of sad really heh -- whenever i add maps into the mix thing sjust get dog slow

3:15 idk, maybe im out of my league here

3:27 Chousuke: any tips on implementing a multimap?

3:28 ohhhh!!! I think I see...

3:29 something like (defn add-to-multimap [multi key val] (assoc multi key (conj (get multimap key #{}) val))) ?

3:58 Mec: aside from the fact that print is a bad choice is there anything wrong with: (defmacro debug-> [& xs] `(-> ~@(interleave xs (repeat 'print))))

4:05 defn: sorry to be a bother, but anyone have any experience with multimaps and want to help me out for a moment?

4:09 Mec: My net crashed, did I actually send that last question?

4:10 defn: Mec you did

4:10 aside from the fact that print is a bad choice...

4:11 i wish i could help you, but you seem like you're probably better off without my help :)

4:11 Mec: lol ok

4:11 I dont have a clue what a multimap is so we're even ;p

4:13 defn: Mec -- im not 100% either ;)

4:13 Mec: FWIW I think it works like this...

4:13 ,{:a 1 :a 2 :b 2}

4:13 clojurebot: {:a 1, :a 2, :b 2}

4:14 defn: having two :a keys is a bad thing for our map, so what a "multimap" allows us to do, is to give :a the values #{1, 2}

4:14 Mec: looks like you might be able to just make each key a set

4:14 defn: Mec: yeah i think that would be heavy handed though

4:15 I'd like to keep a single unified sequence

4:15 preferably a map

4:19 LauJensen: Morning gang

4:20 defn: hi LauJensen

4:21 LauJensen: I'm struggling a bit with building something in clojure which will parse a 300MB logfile for IPs in a specific context in each line in the file, and then create a map which contains the unique IPs in a map, where the value of the unique IPs == the number of times the IP occurs in the file

4:21 the file is approx 2,000,000 lines -- someone has suggested multimap, but im a bit fuzzy on implementation

4:22 LauJensen: Which part of the implementation is tricky ?

4:23 I mean, are you designing or have you something running but needs improving?

4:23 defn: i guess im just sort of stuck looking at stuart sierra's multimap code, not fully understanding it

4:23 let me show you where im at currently...

4:23 LauJensen: Ok - I haven't checked it out myself. For 300 MB I would just go with a hash-map, would take 10 minutes to implement and 5 minutes to run

4:24 defn: LauJensen: http://gist.github.com/342095

4:24 Mec: ya a map of sets, thats what i was thinking

4:25 defn: if you could offer a "next step" given my current code, that'd be very much appreciated, even a minor tweak -- i think i need a break

4:25 LauJensen: ok, lemme look, M-x gist-fetch FTW!

4:26 defn: M-x gist-buffer :)

4:26 err region in this case :)

4:26 Mec: How come you need a multimap if youre just tracking IP and count

4:26 LauJensen: Mec, not a map of sets, a map where the key is an int representing the IP and the value being the number of occurances

4:26 That would be most lean I think

4:26 Mec: Ya that would just be a regular map

4:26 LauJensen: Yep

4:27 defn: LauJensen: my feeling was that it would break given:

4:27 ,{:a 1 :a 2 :b 2 :c 3}

4:27 clojurebot: {:a 1, :a 2, :b 2, :c 3}

4:27 defn: the multiple keys sort of scared me

4:27 so i was led to multimaps/sets

4:27 hiredman: defn: why would you need a multimap

4:28 defn: that is a, uh, bit of undefined behaviour in arraymap

4:28 you should never have the same key multiple times in a map literal

4:29 LauJensen: defn: http://gist.github.com/342097

4:29 hiredman: I'd suggest parsing using a line seq, then process the line-seq

4:29 LauJensen: I think you were over complicating. If you check out that simple formula, you can pass that a seq of the IPs and it will give you a map counting the number of occurances

4:30 hiredman: ,(merge-with + {"" 1} {"" 1})

4:30 clojurebot: {"" 2}

4:31 LauJensen: defn: and that make-seq-of-IPs could just be your re-find statement

4:31 Would that work for you ?

4:33 lpetit: hello all

4:34 LauJensen: Morning lpetit

4:35 lpetit: Morning Lau Jensen

4:38 defn: LauJensen: sorry, im back -- looking...

4:43 LauJensen: so in my code this would look something like (defn to-counted-map [] (reduce #(assoc %1 %2 (inc (get %1 %2 0))) {} (parse-outside-ips (find-lines-in-file "Deny tcp src outside" *logfile*))))

4:44 LauJensen: that code is a lot faster than i had imagined...

4:44 LauJensen: So you're up and running?

4:45 defn: I crashed my emacs, but it looks like it worked beautifully

4:45 I will probably try something to increase performance somehow

4:45 LauJensen: Great

4:45 defn: Thanks much -- I'm surprised it was so simple :\

4:46 LauJensen: 300Mb shouldn't be a problem, in my climate program (IIRC) nearly 50 GB were cooked down to a map which all came through a single reduce

4:46 (I'll admit, that could be optimized) :)

4:48 defn: I guess I've just seen things like ato's widefinder 2 implementation

4:48 and it makes me want to optimize the hell out of things

4:49 LauJensen: I'll put my vote on the Optimize-Only-When-u-need-to strategy - its a tedious task

4:49 And for something which need to go very fast, you need to mutate and I'd like to avoid that 99.99% of the time

4:57 defn: Evaluation aborted that time...

4:58 * defn hopes it runs this time

4:58 spariev: is it true that with protocols it will be possible to monkeypatch existing java classes ?

4:58 LauJensen: defn: I think you'd want something between -Xmx768m and -Xmx1024m at the very least

4:59 defn: LauJensen: Xmx?

4:59 psykotic: spariev: no monkeypatching is involved, but there is open extensibility, yes, and in a much more controlled form than what passes for open extensibility in the ruby and javascript world.

5:00 LauJensen: defn: java -Xms512m -Xmx1024m -cp clojure.jar clojure.main yourscript.clj

5:00 That'll give you 512 MB of Ram to start out with, and allow it to grow to 1 Gb

5:00 defn: ah ha, thanks LauJensen

5:01 spariev: psykotic: great! I should upgrade to 1.2 and add all c.c.strings fns to java.lang.String :)

5:03 defn: LauJensen: would it make sense to use something like atoms to speed this up?

5:04 Mec: i have 2 macros: `(a b) and `(c b) is there a way to abstract out that the only difference is the first symbol (which is a macro)

5:04 LauJensen: defn: You're reading from a single file and everything is going through the same reduce pass, so if you want to speed it up, either paralleize that reducer pass, or make 2 - 4 chunks of the file and then finish with (merge-with + chunks)

5:05 defn: yeah i was thinking about chunking

5:05 LauJensen: thanks again for all the help

5:05 i know it's sort of a boring topic :\

5:05 LauJensen: not at all - and it was np to help :)

5:24 defn: how do i change the key in a map

5:25 psykotic: defn: you can dissoc/assoc

5:26 LauJensen: defn: sure you need to ?

5:26 defn: LauJensen: well, im going to go through every value in the resulting map that we created above, and get the geolocation of the IP from a binary DB

5:27 LauJensen: Yea?

5:27 defn: id'd like to have the IP, country code, and number of occurrences -- obviously i cant have all three in the map, right?

5:27 maybe a second map makes more sense

5:28 LauJensen: defn: depending a little on the size of the map, I think it makes sense to associate those data with the IP itself

5:28 defn: could you show me what the structure would look like in your mind?

5:29 {{:code :ip} 5}

5:29 something like that?

5:29 LauJensen: {: {:country "DK" :x y :z 3}}

5:30 defn: ah right

5:30 LauJensen: (assoc-in m [: :country] "DK")

5:32 defn: LauJensen: wow you rule.

5:32 LauJensen: hehe :)

5:33 Licenser1: u

5:34 defn: uh oh Licenser_ is here

5:34 ;)

5:34 Licenser_: hi defn

5:34 defn: good morning

5:35 spariev: what's the most up to date tutorial on developing appengine apps with clojure/compojure ?

5:35 Licenser_: defn: I read your query and I know the 'problem'

5:37 defn: Licenser_: cool -- i figured you would since it looks related to the sandbox :)

5:41 Mec: How do you cast an object to a string?

5:41 spariev: ,(str 123)

5:41 clojurebot: "123"

5:42 Mec: well duh

5:42 * Mec hides in the corner

5:42 spariev: but it's not exactly a cast

5:42 more like Java's toString()

5:50 defn: I keep getting a no matching method found for getCountry for class com.maxmind.geoip.LookupService

5:52 LauJensen: How are you calling it?

5:53 psykotic: defn: make sure you're passing the right argument. the compiler isn't very specific about what 'no match' means. it could mean no method by that name, or that the name exists but no overload of the right signature exists.

5:53 Licenser_: defn: the problem is that if the method you look for themself fail the sandbox nothing is found

5:54 defn: I (:import [com.maxmind.geoip LookupService]) (def database (LookupService. *database-path*))

5:55 then (defn country-code [#^String ip] (-> database (getCountry ip) (.getCode)))

5:55 err .getCountry ip

5:57 LauJensen: Have you tried manually calling (.getCountry li "Googles ip") ?

5:57 defn: Oh yeah definitely, it runs fine in that context

5:57 (.getCountry "") => "XYZ"

5:57 errr (country-code "x.x.x.x") => "XYZ"

5:58 it seems like it might be a thread issue

5:58 _mst: is ip definitely a string? not a keyword or something?

5:58 defn: _mst: could that produce a no matching method?

5:58 _mst: the wrong argument type could, yep

5:59 defn: I mean, I created this sequence, and it doesn't seem likely

5:59 LauJensen: defn, that was psykotics point

5:59 _mst: yeah, just saw Lau's example above using a keyword. Wasn't sure if that's what you were doing too

5:59 LauJensen: ,(name :

5:59 clojurebot: ""

5:59 defn: it is a massive sequence though, it's possible one of the strings in the sequence is screwy

6:00 Mec: is it bad form to error check by exception rather than using if ;p

6:00 LauJensen: (try (get-country...) (catch Exception e "NO COUNTRY"))

6:01 defn: where are try/catch?

6:01 LauJensen: in cor

6:01 e

6:02 defn: 1.1.0? I don't have either of them :X

6:02 LauJensen: ,(try (/ 5 0) (catch Exception e "Div by Zer0"))

6:02 clojurebot: LauJensen: Pardon?

6:02 LauJensen: eh

6:03 They have been around as special forms for over a year

6:06 lpetit: ,(doc try)

6:06 clojurebot: Gabh mo leithscéal?

6:08 defn: my mistake LauJensen && Company -- for some reason swank doesn't complete on those

6:08 LauJensen: ok, I wonder what clojure bots problem is

6:09 spariev: try is a special form

6:09 psykotic: LauJensen: de er skoere, de gallere

6:09 lpetit: ,(doc def)

6:09 clojurebot: DENIED

6:09 lpetit: ,(doc fn)

6:09 clojurebot: "([& sigs]); (fn name? [params* ] exprs*) (fn name? ([params* ] exprs*)+) params => positional-params* , or positional-params* & next-param positional-param => binding-form next-param => binding-form name => symbol Defines a function"

6:10 lpetit: fn is a special form, non ?

6:10 Mec: fn is just a macro

6:10 defn: ,(doc pre)

6:10 clojurebot: I don't understand.

6:10 lpetit: a special form currently implemented as a macro, I guess

6:11 ,(doc loop)

6:11 clojurebot: "([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein. Acts as a recur target."

6:11 lpetit: ,(meta (var loop))

6:11 clojurebot: {:macro true, :ns #<Namespace clojure.core>, :name loop, :file "clojure/core.clj", :line 2985, :arglists ([bindings & body]), :doc "Evaluates the exprs in a lexical context in which the symbols in\n the binding-forms are bound to their respective init-exprs or parts\n therein. Acts as a recur target."}

6:11 lpetit: ,(meta (var fn))

6:11 clojurebot: {:macro true, :ns #<Namespace clojure.core>, :name fn, :file "clojure/core.clj", :line 2931, :arglists ([& sigs]), :doc "(fn name? [params* ] exprs*)\n (fn name? ([params* ] exprs*)+)\n\n params => positional-params* , or positional-params* & next-param\n positional-param => binding-form\n next-param => binding-form\n name => symbol\n\n Defines a function"}

6:12 lpetit: ,(source fn)

6:12 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

6:12 lpetit: ok ok

6:12 Mec: ,(clojure.contrib.repl-utils/source fn)

6:12 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/fn

6:13 Mec: weird

6:14 LauJensen: ~source fn

6:14 defn: ,(assoc-in {"1" 4 "2" 8} ["1" :country] "US")

6:14 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.Associative

6:15 defn: ,(assoc-in {:x 4 :y 8} [:x :country] "US")

6:15 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.Associative

6:15 defn: ,(assoc-in #{:x 4 :y 8} [:x :country] "US")

6:15 clojurebot: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.Associative

6:15 defn: bah

6:16 LauJensen: ,(assoc-in {: {:country nil :code 404}} [: :country] "DK")

6:16 clojurebot: {: {:country "DK", :code 404}}

6:16 LauJensen: If you're not doing a nested call, use assoc, if its a nested structure, use *-in

6:17 defn: well it wasn't a nested structure, before, but now i need it to be

6:18 Licenser_: clicki :D

6:20 licoresse: I am looking for a swank-clojure library that allows me to dump strings onto a console in emacs for debugging purposes

6:20 is there such a thing?

6:20 LauJensen: ,(let [m {: 5} ip :] (assoc m ip {:occurences (ip m) :country "DK"}))

6:20 clojurebot: {: {:occurences 5, :country "DK"}}

6:22 defn: LauJensen: my god man i need to sleep this is getting worse and worse

6:22 i think ive done this before 3-4 times

6:22 LauJensen: slept?

6:22 :)

6:22 defn: in the last 7 days yeah ;)

6:22 LauJensen: Ok, go to sleep, nothing worse than trying to code when the brain isn't playing along

6:23 defn: *nod*

6:23 see you all in a bit

6:23 noidi: licoresse, I don't have an answer for that question, but this might be relevant http://

6:23 measuringmeasures.blogspot.com/2010/01/agony-of-clojurehadoop-logging-

6:23 http://measuringmeasures.blogspot.com/2010/01/agony-of-clojurehadoop-logging-and-how.html

6:23 licoresse: nodidi: thanks, I think something like that could be useful!

6:27 noidi: licoresse, but basically if you println from the main thread, it is shown on the slime repl in emacs, and printlns from other threads go to the terminal in which you ran "lein swank"

6:28 licoresse: I don't use lein swank, might be worth a try

6:28 but, println does not emit anything on my repl

6:29 noidi: licoresse, then check the buffer called *inferior-lisp*

6:29 licoresse: noidi: oh, it does!

6:30 :)

6:30 great!

6:31 and all those exceptions! good stuff, now I am not blind

6:31 noidi: hehe

6:31 defn: clojure.lang.PersistentHashMap cannot be cast to java.util.Map$Entry

6:31 what could cause that?

6:36 hoeck: defn: ,(key {})

6:36 ,(key {})

6:36 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.util.Map$Entry

6:37 defn: crap

6:38 licoresse: This system is making me SO HAPPY!!

6:41 powr-toc: Is clojure.org hosted on wikispaces?

7:16 Mec: Whats the best way to wait a certain amount of time and then do something?

7:19 oh nvm think i got it

7:20 SynrG: curious. my jline history has some nulls in it for clojure and when i uparrow to those it messes up where jline thinks the cursor is (off by one for each null encountered)

7:20 how'd they get in there and how can i prevent this?

7:21 Licenser_: darn :(

7:24 hmm I've found a very sneaky problem

7:25 (read-string) only reads the first s-exp of a string, is there any way to read all of them?

7:27 esj: slightly off topic - but what do you guys use to format somebody else's html ? I'm trying to scrape a page and want to figure our the logical structure, but the text itself is. Emacs html mode doesn't seem to have an auto-format !

7:28 Licenser_: esj: I simply don't :P

7:28 spariev: Licenser_: maybe wrap whole string in parens ?

7:29 esj: Licenser_: i like your solution

7:30 spariev: ,(read-string "(+ 1 2) (- 3 2)")

7:30 clojurebot: (+ 1 2)

7:30 spariev: ,(read-string "((+ 1 2) (- 3 2))")

7:30 clojurebot: ((+ 1 2) (- 3 2))

7:33 Licenser_: esj: thank you :)

7:33 spariev: but that alters the code sadly

7:37 spariev: ,(doc read)

7:37 clojurebot: "([] [stream] [stream eof-error? eof-value] [stream eof-error? eof-value recursive?]); Reads the next object from stream, which must be an instance of java.io.PushbackReader or some derivee. stream defaults to the current value of *in* ."

7:38 spariev: maybe you could try to wrap string in PushbackReader and feed it to read, then

7:39 Licenser_: spariev: *nods* that is my current atempt just that I have to handle the EOF error :P but thanks to your nice doc it seems I can skil this

7:39 skip

7:39 noidi: what's wrong with wrapping the string in parens?

7:40 it doesn't really alter the code, as you always get a list and always iterate through the items

7:40 so each item still appears as it was

7:41 ,(str (read-string "foo bar"))

7:41 clojurebot: "foo"

7:41 noidi: ,(map str (read-string "(foo bar)"))

7:41 clojurebot: ("foo" "bar")

7:43 Licenser_: hmm I am not entirely sure what is the best aproach for a general sandbox

7:43 hmm hmm hmmm

7:43 but with () it weould try to evaluate the first expression as function

7:44 spariev: it just reads it, not evaluate

7:45 Licenser_: yes but next part is to evaluate it :P

7:46 hoeck: just (map eval ....) to evaluate all toplevel forms ?!

7:48 defn: http://inspiration.sweyla.com/code/

7:48 very nice

7:48 licoresse: When running lein jar I get this clojure.lang.PersistentVector cannot be cast to clojure.lang.Named error, but no indication where the error occured other than inside compiler.java, is there a way to get a more descriptive message from lein, or something else?

7:49 hoeck: Licenser_: load does sth. along the lines of: http://gist.github.com/342217 (no need to wrap the string in parens)

7:50 licoresse: ls

7:51 Licenser_: hoeck: I figured to solve it on application level instead of library level

7:51 the sandbox tax a s-exp period

7:51 if you have more then on in you source you've to deal with that

7:52 since only the application can actually know how to handle this

7:52 licoresse: my project.clj file could have some nonsense, need to read on that...

7:57 of course it was riddled with nonsense, never mind...

7:58 arnihermann: Can someone take a look at this macro weirdness: http://paste.pocoo.org/show/193221/

7:59 I can't figure out why it's trying to resolve a symbol

7:59 which is inside a map

7:59 Mec: I'm playing around with clipboard manipulation, anyone know what might be wrong with http://gist.github.com/342221

8:00 psykotic: why does clojure does quasiquoting in the reader?

8:00 it makes advanced macro-writing macros using nested quasiquotes a bit of a problem

8:00 Chousuke: psykotic: it's easier

8:01 psykotic: implementing syntax-quote as a macro is rather problematic

8:01 psykotic: at least, difficult enough that I gave up trying to do it :P

8:02 psykotic: I kept finding more and more corner cases.

8:02 psykotic: no-one said it was easy but there are papers out there like alan bawden's that everyone has read

8:02 okay, maybe not everyone, but the semantics are well documented by now

8:03 * psykotic tries to find a workaround

8:03 Chousuke: syntax-quote does autogensyms and namespace resolution though.

8:03 psykotic: autogensyms is a 15 line macro

8:04 in fact, i'm trying to implement it right now as a demonstration, and i'm running up against the apparent lack of support for properly nested quasiquotes

8:04 Chousuke: might be. though I ran into some nesting issues when I implemented it.

8:05 namespace resolution was horror though

8:05 psykotic: yeah, i can imagine that might be the tough part

8:05 Chousuke: I think I have that stuff on github somewhere

8:06 psykotic: right now i've been doing the ~'foo thing explicitly to punt on it

8:07 Chousuke: http://github.com/Chousuke/clojure/blob/clojure-reader/src/clj/clojure/lang/reader/internal.clj

8:08 that probably could be simplified considerably but hm

8:08 that's just the function version that the reader uses. as a macro, it just doesn't work.

8:09 arnihermann: can anyone figure out why clojure tries to resolve key in a map from inside a macro: http://paste.pocoo.org/show/193221/

8:10 Chousuke: you're doing (symbol ":" ...)

8:11 arnihermann: ah

8:11 crap

8:11 Chousuke: the :y in the expansion is not a keyword, it's a symbol

8:11 arnihermann: I always fall into that trap

8:11 right

8:11 thanks

8:11 this is the second time in 2 days or so

8:11 I manage to pull something like this off :)

8:11 Chousuke: also the double parens after the and look suspicious

8:12 it'll probably be your next error :)

8:12 you probably meant to type (and ~@constraints)?

8:13 arnihermann: yup

8:13 Chousuke: indeed

8:13 thanks :)

8:14 hoeck: Mec: mind to paste more context, e.g. your imports and the Exception you get or a description of what went wrong?

8:14 Mec: hoeck: sure 1 sec

8:17 licoresse: my project depends on some bitmaps, can these be included in the jar using lein?

8:18 Mec: hoeck: http://gist.github.com/342221

8:19 licoresse: perhaps this is what :resources-path is used for?

8:26 defn: At work on my laptop with 1/4th as much RAM and half as many cores I am able to run some code in my REPL, but when I get home and try to run the same thing I get Java Heap Space

8:27 Mec: Must be running different jvm settings

8:28 defn: Is there any way to specify what slime uses?

8:29 hoeck: m-x customize-group swank-clojure

8:30 Mec: no match

8:31 hoeck: or m-x customize-variable swank-clojure-extra-vm-args

8:31 and then set it to (list "-Xmx1G")

8:32 (for 1 gig)

8:32 but works only if you start clojure from within emacs, don't know how lein handles it

8:32 defn: Debugger entered--Lisp error: (void-variable -Xmx1G)

8:32 you sure?

8:33 oh nvm im sorry

8:33 you said (list "...")

8:34 Mec: Is there any way to see if that setting is being applied?

8:34 defn: we'll know on my next run ;)

8:35 hoeck: Mec: jvisualvm show the jvm args, and maybe there is a System/getProperties entry which shows them too

8:36 Mec: your setContent code somehow works, at least after a call to .getContent a different Transferable is returned

8:36 fogus: Mec: Thanks for the catch on my blog post. (that was you no?)

8:37 Mec: fogus: yes indeed, the same error was at the bottom but I didnt notice that one :D

8:38 hoeck: Mec: oh, it actually works, it clears my clipboard (running jdk6 + ubuntu)

8:38 Mec: hoeck: weird, it doesnt do anything on windows jdk6

8:38 defn: Mec: that setting is definitely being applied

8:39 I was barely cracking 200MB before and now it baloons up to 400 when the time is right

8:39 hoeck: but it appears not to work within emacs, as emacs has its own yank-buffer and mostly ignores the clipboard or caches it

8:40 Mec: oh maybe thats why

8:40 Wow, it does work outside of emacs

8:40 SynrG: nobody have ideas about why jline in my repl has nulls at the ends of some lines, messing up cursor positioning?

8:41 Mec: hoeck: thanks, i would have never thought to check it outside of emacs

8:41 SynrG: it's really annoying

8:42 hoeck: Mec: yw

8:43 Mec: in a ns def can you do (import ...) or does it have to be (:import ...)

8:43 hoeck: SynrG: mhh, different encodings between your shell and clojure?

8:44 SynrG: locale says en_CA.UTF-8 ...

8:44 Chousuke: java has its own encoding

8:45 SynrG: gnome-terminal says UTF-8 ...

8:45 where does it determine encoding?

8:45 Chousuke: it's some property which I can't remember

8:45 file.encoding perhaps?

8:45 ,(System/getProperty "file.encoding")

8:45 clojurebot: java.security.AccessControlException: access denied (java.util.PropertyPermission file.encoding read)

8:45 Chousuke: damn :P

8:46 Mec: Mine says "Cp1252"

8:46 Chousuke: you can change it on java startup via -Dfile.encoding=...

8:47 SynrG: mine says UTF-8

8:47 so i think all is well

8:47 any other ideas?

8:47 when i check the jline history file for clojure ...

8:48 some lines have a single null at the end of them

8:48 defn: oh god thank you for showing me the jvm settings

8:48 SynrG: if i up-arrow to that line, the cursor is now off by one

8:48 defn: this is so much less painful

8:48 * defn assigns 4GB to java

8:48 SynrG: the end of the line is the only place i have ever seen these nulls

8:48 licoresse: defn: when searching this channel, I saw that you had a question regarding where to put images/pictures when using leiningen, did you figure that out?

8:48 SynrG: and only on two out of several lines. i have no idea what might have caused them :(

8:49 defn: licoresse: IIRC the resources dir is not working per technomancy

8:49 licoresse: defn: I see, any workarounds?

8:50 defn: i havent looked into it to be honest, things may have changed recently

8:50 ,(first {:a 1 :b 2 :c 3})

8:50 clojurebot: [:a 1]

8:51 licoresse: defn: ok, I'll keep searching

8:51 defn: Can assoc/disassoc be mapped over a map?

8:52 or does the [:a 1] upset it somehow?

8:54 Mec: seems like filter would be more natural, what are you trying to do?

8:55 defn: Mec: take a very large map like: {"some-key" 5...} and turn it into {"some-key" {:count 5 :other-val 3}...}

8:57 Mec: (reduce (fn [m [k v]] (assoc m generate-sub-map)) {} your-large-map)

8:57 defn: I'm doing something like: (map #((let [mykey (first %) cnt (rest %)] (assoc % mykey {:count cnt :other-val (some-fn mykey)}))

8:59 Mec: ok (Reduce (fn [m [mykey cnt]] (assoc m mykey {:count cnt :other-val (some-fn mykey)})) {} your-map)

8:59 and that will give you a resulting map, rather then a seq of maps

9:01 defn: Mec: thanks so much that's exactly what I've been trying to put together

9:04 * defn studies your wisdom

9:06 Licenser_: there we go

9:06 defn: Mec: would it be too much to ask you to explain how that is put together? namely that destructuring...

9:06 Licenser_: clicky is waaay better now

9:06 defn: Licenser_: linki?

9:06 Licenser_:

9:06 my playground!

9:07 Chousuke: (into {} (map (fn [[k v]] [k {:count v :upcase (.toUpperCase k)}]) {"foo" 3, "zonk" 4}))

9:07 ,(into {} (map (fn [[k v]] [k {:count v :upcase (.toUpperCase k)}]) {"foo" 3, "zonk" 4}))

9:07 clojurebot: {"foo" {:count 3, :upcase "FOO"}, "zonk" {:count 4, :upcase "ZONK"}}

9:07 Chousuke: using into is preferable to reduce because you get transients for free :)

9:08 Mec: I thought into was only good for 2 maps

9:08 oh nvm, misread it

9:08 Chousuke: into just conjs every item in a sequence into whatever you give as a first arg

9:09 and [k v] is a map entry

9:09 ,(conj {} [:foo 'bar])

9:09 clojurebot: {:foo bar}

9:09 seths: anyone for/against a clojure-dev discussion on reducing the difficulty getting started with Clojure?

9:09 defn: ,(let [a [:b :c]])

9:09 clojurebot: nil

9:09 defn: ,(let [a [:b :c]] a)

9:09 clojurebot: [:b :c]

9:09 seths: that seemed to be the main point behind the "chosen not to employ..." flashpoint

9:10 it seems like everyone is reimplementing bin/clj [.sh|.bat]

9:10 it might be nice to include a basic one (with jline!) as part of a download

9:11 Mec: clojure needs a simple editor written in clojure for noobies

9:11 seths: Mec: even before you get into the editor tho

9:11 defn: ive heard good things about enclojure and clojurex

9:11 Chousuke: Mec: I think that's false.

9:11 Mec: good integration with existing editors is much more important.

9:11 Mec: I've never used netbeans or enclojure or emacs, so i was kind of sunk until i spent a week learning emacs

9:12 Chousuke: people are already likely to use them, and introducing another editor is just a waste of time

9:12 seths: I would dearly love to see a kitchen-sink download for Clojure 1.2

9:12 Licenser_: the 'choosen not to employ' stuff was half bogus, I remember back when PHP was fresh it was a minor hell to get it running with apache and mysql propperly

9:12 seths: including bin/clj with contrib & jline

9:12 Chousuke: if they are not using one of the well-integrated editors, then they have an incentive to learn one :)

9:12 seths: possibly also copy of the docs

9:13 Chousuke: Licenser_: I thought it had some good points, but they were all horribly presented

9:13 seths: java -cp clojure.jar is great, but it's a little too simple maybe?

9:13 Mec: by all means there should be good integration, but having to learn to use a massive system just to start hacking isnt very fun

9:13 Licenser_: Chousuke: it had some horrible points but this one wasn't good, at least the example was very flawed

9:13 clojure apps are incredible easy to deplay way easyer then any other application I know of

9:13 Chousuke: Licenser_: also the fact that he announced he would ignore all replies sounded rather arrogant to me.

9:14 * Licenser_ agrees

9:14 defn: I think part of the problem is that so many of the people who use currently use clojure are a) people who know how to teach themselves, hence emacs has not been a large barrier for a majority of the community. b) the tools that already existed in other editors, while somewhat quirky to setup for someone brand new to clojure, have a host of tools that is just hard to find in same mix in other editors

9:14 Licenser_: there is little easyer deployment as lein uberjar; java -jar app-standalone.jar

9:14 seths: Licenser_: not so

9:14 Chousuke: Licenser_: uberjar creates bloat though ;(

9:15 seths: or partly not so, Lein is still awkward on windows

9:15 Chousuke: Licenser_: might not be bad for a one-off deployment but it's not fit for distribution

9:15 Mec: I'm dreading when i finally finish my program here and try to get it actually deployable

9:15 Licenser_: you also can just copy the content of lib

9:15 defn: i didnt know to run standalone at first -- i think that's a bit confusing to newbies. i think it's also confusing to use java -jar xxx.jar, it seems sort of archaic even if it would be in many minds superfluous to include a bash script or something to launch java -jar app-standalone.jar

9:16 Licenser_: and yes lein is horrible to use on windows, but nearly everything is

9:16 Chousuke: Licenser_: unless, perhaps, you want to create some kind of a self-contained "platform" that is supposed to be updated as one.

9:16 seths: yes, but manual dependency management is awful

9:16 defn: "patches welcome"

9:16 Chousuke: It's sad that maven seems to be the best tool around to handle dependecies ;/

9:16 defn: ;)

9:16 Chousuke: it's so damned verbose.

9:16 Licenser_: Chousuke which is a good practice to guarantee compatibility and effects

9:16 seths: Chousuke: polyglot maven looked interesting

9:17 http://polyglot.sonatype.org/clojure.html

9:17 Chousuke: and it fills the repository with all kinds of crap and doesn't provide means of trimming it, as far as I can tell.

9:17 seths: the "pom.xml" looks like a lein project.clj

9:17 defn: what makes dependency management so difficult -- why doesn't the clojars/lein combo work the same way things like ruby/gems/rake work?

9:17 Chousuke: defn: it does, doesn't it?

9:17 defn: well, sort of

9:18 Licenser_: defn rubygems are great but also not perfect

9:18 Chousuke: defn: it downloads deps using maven.

9:18 Licenser_: one problem is that maven can be confusing

9:18 chouser: maven ant tasks, which is not maven itself I think

9:18 Licenser_: and that - as so foten - documentation is sparse for lots of stuff

9:19 defn: Sort of ironic all the incidental complexity is in the configuration of your build environment...

9:20 Chousuke: I think maven should be good enough for Clojure use in the java world but some work on polyglot definitely needs to be done.

9:20 seths: defn: rake & gem would be more awkward if they were OS-specific scripts like lein

9:20 Licenser_: what would be good is a one shot installer for clojure that gets you running like clojure box

9:20 lein goes a long way but that it requires internet is .. ann oying

9:21 seths: Licenser_: I'm all for a one shot installer, but that's a large task

9:21 Licenser_: yes I know but it'd be good

9:21 seths: a zip file with bin/clj and contrib/jline on the classpath would be a nice midpoint

9:21 Licenser_: something that is like 1 file that gives you bin/clj bin/lein perhaps even emacs or something

9:22 seths: ClojureBox is that sort of thing for Windows

9:22 Chousuke: a Clojure "SDK" installer could come with a dependency on maven (or bundle it) and some custom wrapper to provide access to common functionality with a more clojure-focused interface.

9:22 rrc7cz-hm: has anyone looked at Ivy for dep management?

9:22 seths: Chousuke: I like the "sdk" term

9:22 chouser: jline has caused some people problems. I think a little GUI editor+REPL with contrib loaded would be nice.

9:23 Licenser_: well rubygems is su successfull since it lets you really manage deps with close to no hassle

9:23 Chousuke: seths: need something to differentiate from just installing the clojure core libraries

9:23 chouser: But I need to look at labrepl -- that may be better

9:23 Licenser_: I still find leiningen way more complicated, error prone

9:23 Chousuke: seths: that would be the CRE :P

9:23 seths: Chousuke: CRE? sorry

9:23 Chousuke: a pun on JRE

9:23 seths: :-)

9:23 chouser: labrepl is a lein app

9:23 it's nice, the mini-browser demos very well

9:23 defn: leiningen is really nice. it's great. i think it still has a lot of potential. it just needs TLC. How long has it been around, anyhow?

9:24 chouser: defn: about 3 weeks

9:24 :-)

9:24 Chousuke: I think leiningen could be retrofitted to work completely on top of maven though

9:24 chouser: Chousuke: have you seen polyglot maven?

9:24 Chousuke: so even if you were to promote use of maven there's no need to just throw away lein

9:24 chouser: yes

9:25 cemerick: ah, I was about to beat that dead horse

9:25 Licenser_: the question is, is maven good?

9:25 chouser: Licenser_: perhaps. Or maybe the question is: what's better than maven?

9:25 cemerick: Licenser_: almost like asking, is the jvm good?

9:25 Chousuke: Licenser_: It's rather verbose but it's probably better than anything we can come up with by ourselves :P

9:25 seths: rrc7cz-hm: never looked at Ivy, what is it built on?

9:26 Chousuke: Licenser_: and with polyglot people with XML-allergy can also use it.

9:26 defn: Chousuke: you're a bigger man than i for admitting it

9:26 Licenser_: Chousuke: I'm not sure I'd like a gem like solution more\

9:26 Chousuke: I'm not really familiar with ruby gems

9:26 defn: i've always liked ruby gems

9:26 Chousuke: in my mind it basically does what maven does.

9:26 seths: I looked at clojuresque a bit last night, not sure I like mixing Groovy into this discussion tho

9:27 Licenser_: Chousuke: it can do a bit more, you canspecify versions directly in your code, keeps stuff in a global place isntead of adding a gazillion libs to a folder and stuff like that

9:27 SynrG: new information on my jline problem. it's not that nulls in the history cause the problem. it's that just exercising the arrow keys a lot eventually causes the problem. somehow a null is introduced, and then i'm left on a line that looks corrupted, and when i press enter on that line (which previously was valid) i get an exception

9:27 seths: defn: gems are pretty mature, even platform specific gems work out pretty well

9:27 defn: im far less familiar with maven than rubygems -- it was just such an easy to use thing when i started playing with gems.

9:27 Chousuke: Licenser_: versions how, exactly? :/

9:27 SynrG: so the nulls are an effect, not a cause

9:28 Chousuke: Licenser_: and you can have a systemwide repository with maven too

9:28 Licenser_: Chousuke: of a library

9:28 I can say something like (syntax m ight be off) require mylib, ">1.0.0"

9:28 seths: anyone tried http://freshmeat.net/projects/rlwrap instead of jline?

9:28 sattvik: For linux-based users, one very important thing is to integrate well into their chosen distribution. For Gentoo, a source-based distribution, maven has been a huge problem for integrating Java apps and libraries.

9:28 Chousuke: Licenser_: ah, well, that's ruby-specific I guess.

9:28 Licenser_: Chousuke: but as soon as I do lein deps it stuffs everything I need or it thinks I mighyt need when my grandmother dies next sunday in lib/

9:29 Chousuke: Licenser_: that's lein, not maven :/

9:29 Licenser_: Chousuke: why, I find it quite generic. if I've a library and know my application works with version 1.0.0-1.2.0 I should be able to say I tepend on this versions

9:29 sattvik: Ultimately, Linux users probably want to install Clojure application similarly to other packages in their system.

9:30 Licenser_: gems allow executables

9:30 I can do say: gem install coderay

9:30 then I have a coderay executable I can use

9:30 another cool thing

9:30 defn: gem install somegem, emacsclient "myfile.rb", require 'somegem', Blah.methods -- by contrast -- read disclojure.org, search on clojars.org, page through github, install leiningen, edit project clj, lein deps, lein repl, (use 'how.do.i.include.this.with.no.java.namespace.experience)

9:30 SynrG: aha! more specifically ...

9:31 rrc7cz-hm: seths: it's an apache project, much like Maven but without all the project management stuff. It's pure dep management. I haven't worked with it, but anyone looking for a maven alternative certainly should

9:31 defn: some of that is just a part of these tools not having been around long enough, but the pain points on the clojure side far outweigh the ease of getting started with a funky library in ruby

9:31 SynrG: 1. in repl with jline support, up-arrow twice. left-arrow to go back one character. now down-arrow, up-arrow, down-arrow again. each time i do that, the lines get progressively more corrupted.

9:32 seths: rrc7cz-hm: thx, I'll check Ivy out some more

9:32 rrc7cz-hm: seths: the key thing is that it can draw from Maven repos natively, so it shouldn't set you back

9:32 Licenser_: gem list --remote alib > lists versions of this lib I can get; another nice feature

9:32 SynrG: can anyone reproduce this? clojure 1.1, jline 0.9.94

9:32 Licenser_: I see why maven has an advantage, it lets you include java stuff too

9:33 cemerick: defn: insofar as clojure is a JVM environment, that will be the case.

9:33 Licenser_: but it isn't nice, people want nice, one of the biggest reasons for ruby's sucecss is that a lot of stuff is just dead simple. Clojure is like that in some points but dep management is certenly not the case

9:34 I was trying to get a compojure app running yesterday I was trying like an houre to find the right versionm of the compojure jar and all the deps for it

9:34 defn: cemerick: I disagree that some of that is necessary.

9:34 Licenser_: that is just a situation that is unbarable in a long run

9:34 seths: hmm: http://ant.apache.org/ivy/history/2.0.0/release-notes.html

9:34 drewr: ruby's dep management is not any easier than clojure's, IMO

9:34 Licenser_: I want to do lein dep compojure -> gets me compojure and all the required libs for that

9:34 seths: drewr: how so?

9:34 cemerick: defn: given typical tools, certainly not. Rubbing together twigs with a command line is another story.

9:34 seths: cemerick: lol

9:35 SynrG: whatever it is, it's not just the repl. in jirb i can eventually cause the problem too.

9:35 Licenser_: drewr: I can do gem install rails and I get all I nee.

9:35 Chousuke: Licenser_: that can still be built on top of maven.

9:35 sattvik: I'd rather use Ivy than Maven. Maven is simply too bloated. The whole "downloading the Internet" is a bit of a put-off just to get a few JARs. And that's if your lucky. What if you are behind a firewall or proxy? Also, from a corporate development point of view, a lot of IT staff won't be happy with software that installs and updates other software automatically.

9:35 * SynrG goes looking for upstream for jline to find their bug tracker

9:35 cemerick: seths: FYI, ivy is an evolutionary dead end, at least IMO.

9:35 drewr: Licenser_: I've had gem break plenty of things

9:35 defn: cemerick: id be happy with one or two sticks.

9:36 rubygems is just a big twig, too, after all...

9:36 Licenser_: drewr: sure it can happen but lein /mvn /whatever is doing it. Is just broken in that area

9:36 Chousuke: sattvik: I don't think that'll be a problem. After all, Java is fairly successful

9:36 sattvik: Java's dependency handling situation is no better, fundamentally, than Clojure's :P

9:37 Licenser_: I did not even know that java has a dependency handling ...

9:37 seths: cemerick: Ivy only offering dependency management is not valuable enough? Confused.

9:37 cemerick: Licenser_: it does -- maven. Seriously, it's the accepted standard.

9:38 Licenser_: cemerick: java is an accepted standard it stull sucks in my eyes :P

9:38 defn: leiningen with the ability to search and retrieve meta info on libraries, install versions from the command line, provide executables

9:38 Licenser_: at this note my spelling is a accepted standard and definetlyt sucks

9:38 cemerick: seths: No, it's not. How about handling deployment? Multiple build profiles? Massive plugin ecosystem?

9:39 defn: and a uniform easy-to-understand way of using libraries you download in your clojure code out of the box

9:39 cemerick: defn: You're quite honestly talking about maven, as it sits today.

9:39 seths: I was hoping to avoid unraveling this into a build tool discussion

9:39 Licenser_: All I say is, in the long or midrun, to be successful clojure needs something good to handle it's own libraries

9:39 Chousuke: defn: I still think all of that can be built on top of maven :P

9:39 sattvik: Chousuke: I agree. But Java tends to live outside the ecosystem set up by Linux distributions and the like. With the Jigsaw project stuff, I hope that the situation will get much better and we can take the dependency management aspects out of build tools. Or at least, simplify the situation.

9:39 defn: oh -- well like i said, i dont know anything about maven, cemerick & Chousuke -- that's really what I'm looking for TBH

9:39 seths: if no one hates the idea of discussing an official "clojure sdk" download with a bin/clj [bat/sh] I will post something to the dev list

9:39 cemerick: seths: I'm not sure how to avoid it. a la carte "systems" are painful, I don't want to deal with them anymore.

9:40 seths: cemerick: I wish we could all go bak to using GNU Make

9:40 cemerick: oh, fer sure! :-P

9:40 defn: i am often upset that i need to open a .jar and find out how to use the library in my code -- i wish there was some way to make them more uniform. it'd be nice if other people's releases of a jar to clojars were kept in the same folder instead of being strewn about

9:40 Chousuke: psh, shell scripts!

9:40 seths: or even "imake", an abstraction over makefiles

9:41 cemerick: seths: oh, you were being serious...

9:41 seths: cemerick: yes, I am a GNU Make fanboy. served me well on a multi-platform C++ project years ago

9:41 Chousuke: defn: I think that might just be lein silliness. Maven really does put the things it downloads just where you tell it to put them. that can be a private repository or a global one.

9:42 sattvik: The thing I like about lein is that it has the potential to define a simple interface, the 'project.clj' file. You could then write different back-ends to handle the dependency management.

9:42 cemerick: seths: yeah, not sure that's an endorsement. :-)

9:42 seths: ,#($%)

9:42 clojurebot: java.lang.Exception: Unable to resolve symbol: $ in this context

9:42 cemerick: sattvik: you're looking for polyglot maven. Regardless, don't confuse syntax and such with the platform underneath.

9:42 defn: Chousuke: Hmm, maybe we're talking about different things?

9:42 seths: er

9:42 ,#(&%)

9:42 clojurebot: java.lang.Exception: Unable to resolve symbol: & in this context

9:42 Chousuke: defn: I'm not sure. maybe :P

9:42 seths: sigh

9:42 ,#(%&)

9:42 clojurebot: #<sandbox$eval__7906$fn__7908 sandbox$eval__7906$fn__7908@15e8c9d>

9:42 Licenser_: Chousuke: the problem wiuht ein here is it puts the stuff it downloads in ~/.m2 and <project>/lib

9:43 defn: Chousuke: I don't like downloading enlive [enlive "1.0"] (in my project.clj), and then finding out when i get to my repl that it's net.cgrand.enlive-html

9:43 Chousuke: Licenser_: why it puts things under /lib I don't understand :/

9:43 defn: as a newb that was an "ugh" moment for me

9:43 Chousuke: defn: maybe there could be a "lein describe" command

9:43 defn: that'd be nice

9:43 Licenser_: Chousuke: even worst it does not delete old stuff

9:44 mattrepl: the local repo, ~/.m2, is useful for using custom builds of project dependencies

9:44 cemerick: defn: clojars is certainly not the tidiest maven repo, for sure.

9:44 Licenser_: if you update a lib and don't delete the old one by hand it seems to randomly decide which one to use

9:44 Chousuke: Licenser_: that's my primary complaint about it.

9:44 * Licenser_ nods

9:44 Chousuke: Licenser_: but I suppose it wouldn't be impossible to write a mvn cutleaves plugin

9:44 defn: yeah it's a big annoying cemerick -- like 10 versions of compojure up there, all in different directories, you need to do different things to use them in your project, etc.

9:45 Licenser_: I don't mean to say how it is bad how it is, or that we need to reinvent the wheen just that there is a lot of room for improvement and a good depmanagement/build platform is incredible important

9:46 cemerick: defn: See, if compojure had a regular maven pom, it would have specific and canonical coordinates, as well as a definition of where to deploy it when cgrand did a build. Just sayin.

9:46 Chousuke: Another thing maven has done wrong IMO is that it defaults to downloading things from the internet.

9:46 defn: On that note it's worth mentioning again that lein is really good for how young the project is.

9:46 cemerick: interesting. i like that.

9:47 cemerick: defn: this is my point. All this stuff is *built already*.

9:47 defn: I've heard people in here from a couple different linux distro communities asking how to build a clojure package without using the internet

9:47 cemerick: welcome them to the 21st century.

9:47 stacktracer: is there a way to say "(if x x :default)" that doesn't require repeating x?

9:47 Chousuke: (or x :def)

9:47 defn: cemerick: heh i think it is the result of build guidelines they are following -- i tend to agree with you

9:48 stacktracer: Chousuke: wow, that seems obvious now that you've said it

9:48 thanks

9:48 cemerick: defn: otherwise, maven has an offline build mode (-o)

9:49 defn: so what is polyglot maven, how does that remove the "suck" from maven? I've heard so many snarls about maven over the last 8 months...

9:50 Chousuke: defn: it's really just for the xml-allergic

9:50 * Licenser_ is XML allergiuc!

9:50 Chousuke: defn: allows you to write the pom files in any language.

9:50 defn: i don't like XML -- noisy lisp etc. etc.

9:50 Chousuke: ah

9:51 does everyone need to install some thingamajig to use that functionality?

9:51 Chousuke: well, the polyglot plugin, probably :P

9:51 defn: so removing a pain point, but adding another layer of complexity

9:52 Chousuke: but you probably can do it by writing your pom in clojure and automatically translating it to XML

9:52 cemerick: defn: try to not base your tool choices on heresay. Otherwise, you'd be avoiding the LISP relics.

9:53 Chousuke: I think XML is an okay format for transporting pom files but it's not a good format for editing them ;/

9:53 defn: cemerick: you seem to get the impression that I'm not willing to use maven. Everything you've said makes a lot of sense to me, and if the XML crud is removed I think it'd be great.

9:53 I was just echoing a sentiment I've heard many times lately

9:53 for sake of argument

9:53 Chousuke: XML is disparaged more than it deserves sometimes

9:54 defn: I don't have any problem with key/value pairs, but after you've seen how easy it is do build a similar datastructure with a syntax that makes it easier to edit, it does seem a bit archaic and weird

9:54 cemerick: defn: Sure. I'd only say, care about what really matters. What really matters with build tools is ecosystem/community and capability. Stuff like XML vs. sexprs is not a valid discriminator given the relative importance of other factors.

9:55 defn: cemerick: well said

9:55 Chousuke: its value is mostly in the vast number of tools surrounding it though. parsers, automatic syntactic and semantic validators based on schemas, XML transformers etc.

9:57 defn: Chousuke: I think the hardest thing here is trying to find a balance between people new to clojure, and people who want to really push the envelope

10:01 not even to push the envelope... This is going to come off as incredibly subjective and perhaps a bit naive, but, I just feel like there are a lot of opportunities for a new language to define their own culture

10:01 s/their/its

10:02 alexyk: I launch 8 agents on an 8-CPU box and give them chunks of a database to process. Each will hold a vector of results. How do I do a barrier sync to get all chunks when ready and concat them?

10:03 sattvik: In my opinion, I think what is most helpful for people new to Clojure is to be able to install Clojure the same way they do other software. For Linux users, this means using apt-get, emerge, or whatever their distro uses. For Windows users, it means having an installer that will install a JRE, the Clojure JARs, and a link on the desktop to the REPL.

10:03 cemerick: defn: given that clojure is at its roots a hosted language, it only makes sense to use the orthogonal tools provided by the given host or prevalent in the community. I presume ClojureCLR will use NAnt or whatever the build tool of choice is in .NET-land.

10:04 mattrepl: alexyk: await? http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/await

10:04 defn: cemerick: Is Maven a JVM build tool or a Java one?

10:05 alexyk: mattrepl: thx!

10:05 cemerick: defn: decidedly the former.

10:05 defn: Does jruby use ant?

10:05 alexyk: defn: there'sa polyglot maven now too

10:05 http://polyglot.sonatype.org/

10:05 has a clojure logo in it

10:05 headius: jruby uses ant, but partly through rake+ant integration

10:06 hopefully eventually entirely through rake

10:06 cemerick: defn: I've no idea what they use. But then, they have an existing community they want to be compatible with.

10:06 defn: see that seems like something we want headius, i dont know the answer...

10:07 seths: ok, message was posted to the dev list. Hope to provoke some useful discussion.

10:08 headius: I think our next step is to do maven integration as well, but I'm partial to just using ant and structuring my projects the way I want to

10:11 sattvik: headius: That's the thing. Doubtless, Maven is a powerful tool; but it's very complex. I prefer to keep things simple and transparent, and Ant provides that for me.

10:12 headius: in an effort to help java folks adopt jruby, we're integrating all that crap...but I haven't swallowed the maven pill yet

10:12 maybe a jruby-based maven tooling would change my mind

10:12 the rake+ant stuff is really nice

10:13 cemerick: Funny enough, I had my own irrational maven hatred until last fall, ~ 14 months into using clojure.

10:13 That, as a way of saying, maven is a generalized build solution, not a Java-specific tool.

10:14 defn: headius: that sounds like the ideal solution to me just because it lets you "ease" into ant, but it's still ant.

10:15 headius: defn: we also do two-way integration, which I don't think any other ant wrappers do

10:15 defn: This discussion started on "new users". I think if new users have no prior knowledge of java they should still be able to pick things up and have some idea of what's going on

10:15 headius: so you can call both ways

10:16 defn: headius: cool

10:16 headius: did you know a lot of java prior to picking up clojure?

10:16 headius: heh

10:16 chouser: headius: have you ever heard of ruby?

10:17 ;-)

10:17 headius: I don't really use clojure, I'm just a spy from ruby-land

10:17 and yes, I've done a bit of java

10:17 I'm one of those rare polyglots that doesn't think java's all that bad

10:17 defn: headius: I remember your from #ruby-lang sometime back -- c nutter?

10:17 headius: defn: yup

10:17 defn: ah, good to see you again :)

10:18 sattvik: cemerick: The #1 problem is that it's a build tool that takes a lot of custom development to integrate it into a larger building ecosystem. Maven has been a big problem with integrating more Java packages into Gentoo. It's too difficult to get Maven's dependency management to cooperate with Gentoo's. It's probably possible to create the appropriate plugin or something like that, but it's not a project anyone has taken up.

10:18 defn: headius: are you sympathetic to the "use maven, but give people an easy way to do maven without doing maven"?

10:19 headius: yes

10:19 cemerick: sattvik: Apologies ahead of time, but *everything* has trouble cooperating with Gentoo!

10:19 headius: I think the danger is in straying too far from maven proper, like buildr seems to do

10:19 you don't want to reimplement all of maven in another tool...it would be better to just wrap it with a better exterior

10:19 defn: headius has rvm caused any spike in the number of people using jruby, or has it been growing consistently regardless?

10:20 headius: like git wrappers do for git

10:20 defn: hard to tell

10:20 jruby can be fetched from lots of locations

10:20 defn: headius: ive been using jruby all the time. i dont see why id use ruby proper at this point...

10:21 cemerick: cemerick: More seriously, gentoo is such an edge case in so many ways. If jvm stuff can be made to work there, then so can clojure, but until that's the case, us changing any kind of approach to accommodate gentoo seems to me like a spectacular distraction.

10:22 defn: after i saw your performance graphs practically a year or maybe two years ago now, i was fairly skeptical, but it's just ruby -- and it's fast. i really love it. :)

10:22 Licenser_: jruby runs on more platforms

10:22 defn: cemerick: yeah i tend to agree. RHEL, Ubuntu -- those take precedent over gentoo IMO.

10:22 Licenser_: getting ruby run on sparc solaris is a seriouse PITA

10:23 rsynnott: cemerick: what, the JVM doesn't work on gentoo?

10:23 headius: jruby's arguably the best windows ruby right now also

10:23 cemerick: rsynnott: No idea.

10:23 headius: and we get the weirdest bugs

10:23 cemerick: From what I hear, a lot of stuff doesn't work on gentoo. *shrug*

10:23 headius: I thought nothing would top the EBCDIC bugs until OpenVMS bugs started to show up

10:23 rsynnott: oh, it's just a build system impedence mismatch

10:23 defn: by a long shot headius. i had to slap something together on windows the other day and I use jruby. it's the default in netbeans now isn't it?

10:23 headius: defn: I think it always was

10:24 defn: ah, either way, very cool :)

10:24 * rsynnott loathes java, but some of the jvm languages have turned out quite nice

10:24 sattvik: cemerick: Well, I am biased, but I'd argue that's FUD. And Gentoo isn't the only the system to use source-based packages. There is BSD's ports and Macports. Java works just fine on Gentoo, and I have clojure/clojure-contrib ebuilds that work just fine, too.

10:24 cemerick: defn: Windows, OS X, Ubuntu, RHEL are the key targets. Beyond that, one has to assume people know what they're doing, and are happy to fix stuff that goes awry.

10:24 underdev: rsynnott: i'm fond of this one lisp dialect on that runs on the jvm

10:25 rsynnott: sattvik: however, not all things on MacOS are expected to be built using ports

10:25 SynrG: headius: hi

10:25 headius: yo

10:25 SynrG: headius: speaking of OpenVMS bugs :)

10:25 rsynnott: sattvik: is the problem just that gentoo's build system doesn't get on with maven?

10:25 SynrG: Ben Armstrong, OpenVMS bug submitter

10:25 cemerick: sattvik: Fair enough. Of course, macports is a horrible, miserable thing to work with. Regardless, if we have a solution that addresses the four platforms I just mentioned, but gentoo ends up being out in the cold, I can't say I'd care much. Sorry again. :-|

10:26 SynrG: headius: incidentally, clojure runs on VMS too :)

10:26 * rsynnott once got a bug report for some project or other from a guy running OS/2

10:26 headius: SynrG: hah, hello there :)

10:26 rsynnott: (it was a java thingy)

10:26 headius: yes, I'd assume clojure runs on openvms too

10:27 SynrG: haven't done anything with it yet, tho. and jruby ... well, that's going to be a big project for us to make everything work. i'm just hoping Uso Thierry can do things with it before I have to dirty my hands with it

10:28 headius: if I had a way to help, you know I would :) some bugs are out of my reach

10:28 SynrG: sure. well, with Uso interested, at least we're no longer alone like we were with the MRI port

10:29 headius: I think the bugs you filed were largely in the lower-level process stuff we do, which I don't think any other JVM langs have attempted

10:29 it's fun and exciting to implement libc-like process control on top of java.lang.Process...no really

10:29 SynrG: i have since then learned a thing or two about the controls for filename handling

10:29 in a different context, umm ...

10:30 headius: I never knew vms, so everything in that bug was totally baffling to me

10:30 * SynrG thinks ...

10:30 headius: I think enebo understood some of it

10:30 sattvik: rsynnott: The problem is that Gentoo and Maven is that they both do dependency management. If you're just installing binary jars, it doesn't really matter what Maven does since you don't really need it to install programs that are built with Maven. However, since Gentoo compiles all programs, it needs to use Maven to compile. Unfortunately, Maven doesn't know about all of the jars already installed on the system and tries to download t

10:30 Licenser_: to distract you people:

10:30 rsynnott: sattvik: but a gentoo user could happily just install clojure outside the gentoo package management system, no?

10:31 SynrG: headius: ah, solr!

10:31 lucene, to be more precise

10:31 rsynnott: this sounds more like a problem for the gentoo people to fix than a reason not to use maven

10:31 SynrG: it was misfiring on filenames with no extension

10:31 cemerick: rsynnott: Indeed.

10:31 SynrG: "filename" would end up as "filename."

10:32 chouser: actually, that's a problem for every runtime-specific dep manager (gems, cpan, etc.) on every distro (redhat, debian, gentoo)

10:32 afaik, each combination is "solved" slightly differently, to slightly different values of "solved"

10:32 Mec: what is wrong with (reduce #(assoc %1 (inc (get %1 %2))) {} coll) that im getting NullPointerException?

10:33 headius: SynrG: ahh interesting

10:33 SynrG: headius: anyway, your appearance here mentioning OpenVMS reminds me to revisit the bugs to see if any of what i learned with lucene can be applied to those bugs

10:33 sattvik: rsynnott: Yes, as with any distro, a user can do whatever they want independent of the build system. However, it'd be ideal if it could be integrated into the system.

10:33 headius: SynrG: yes, it would be nice to get those resolved at some point :)

10:33 it was definitely path-parsing in at least one of the bugs

10:33 SynrG: yup

10:33 headius: the other was the use of sh to run subcommands I think

10:34 SynrG: mhm

10:34 rsynnott: sattvik: but that would be an issue important largely to people who use gentoo (which is not many), and so something that the gentoo people should sort out rather than expecting third parties to accomodate something with minimal market share

10:34 Mec: nvm there was a lot wrong with that, time for bed methinks

10:34 SynrG: headius: hmm, and i have clojure to cross-check these things with. surely there are equivalent constructs?

10:34 sattvik: chouser: Exactly, there are Gentoo wrappers for dealing with CPAN, CTAN, and Ruby, at least. Maven hasn't been tackled yet.

10:35 headius: http://jira.codehaus.org/secure/IssueNavigator.jspa?reset=true&jqlQuery=project+%3D+JRUBY+AND+%28summary+%7E+openvms+OR+description+%7E+openvms+OR+comment+%7E+openvms%29

10:35 looks like there was at least one other person who filed openvms-related bugs

10:35 SynrG: headius: speaking of jruby, you wouldn't happen to know why jline sometimes cocks up and starts dropping characters. this seems to affect both clojure and jirb on debian sid.

10:36 headius: I do not...somehow I became an admin on jline though, so it's probably my fault in some way

10:36 sattvik: rsynnott: Perhaps, but so long as I have a voice, I'll try to push for solutions that are easy to integrate into source-based distros.

10:37 SynrG: headius: my reproducible test case: start clojure repl. up-arrow a couple of times. left-arrow once. then a bunch of up/down/up-arrows until the lines start to get corrupted

10:37 same with jruby only it took a bit longer to eventually drop characters

10:38 headius: I think you or someone else brought this up and it seemed to only be a problem in xterm or rxvt

10:39 I was able to reproduce it using OS X xterm, but not Terminal

10:39 some terminal emulation oddity wrt jline

10:44 djpowell: With maven, if I want to do something like run a java command-line to generate a file that is required by the build, how would I go about doing it?

10:44 SynrG: headius: aha. yeah, i was beginning to investigate this, but so far had only tried: gnome-terminal, lxterminal, xterm

10:44 djpowell: I get the feeling that it is more than one line of code?

10:44 SynrG: headius: my next test was going to be in console

10:45 defn: ,(type {:x 1})

10:45 clojurebot: clojure.lang.PersistentArrayMap

10:47 SynrG: headius: nope. screws up in console too (TERM=linux)

10:48 headius: djpowell: it's probably eight lines of XML, knowing maven

10:48 defn: are big arraymaps coerced into hashmaps?

10:48 persistentarraymaps vs persistenthashmaps

10:49 headius: gotta run, bbl

10:50 Licenser_: hmm now to join a list?

10:50 defn: cons, concat?

10:50 Raynes: I think you want concat.

10:50 Licenser_: I mean like ["a" "b" "c"] -> "a,b,c"

10:51 Raynes: Or flatten.

10:51 sattvik: Licenser_: interpose?

10:51 defn: clojure.contrib.seq-utils

10:51 /flatten

10:51 Raynes: ,(apply str (interpose "," ["a", "b", "c"]))

10:51 clojurebot: "a,b,c"

10:52 Raynes: ,(clojure.contrib.seq-utils/flatten ["a" "b" "c"])

10:52 clojurebot: ("a" "b" "c")

10:52 Raynes: Doesn't do what he wants here.

10:52 :(

10:52 I mean, it wouldn't anyway without interposing ",", but still.

10:52 Licenser_: I like the interpose thing

10:56 Raynes: Licenser_: By the way, good morning (depending on what time it is wherever you live. ;))

10:56 defn: ,(let [[x y z] ["a" "b" "c"]] (str-join "," [x y z]))

10:56 clojurebot: java.lang.Exception: Unable to resolve symbol: str-join in this context

10:56 alexyk: how do you update a global (def *a* 1) from within a defn?

10:56 Licenser_: afternoon :(

10:56 :)

10:56 defn: ,(use 'clojure.contrib.str-utils)

10:56 clojurebot: nil

10:56 defn: ,(let [[x y z] ["a" "b" "c"]] (str-join "," [x y z]))

10:56 clojurebot: "a,b,c"

10:56 Chousuke: alexyk: you should not

10:56 alexyk: but alter-var-root

10:57 alexyk: Chousuke: ok

10:57 but I won't :)

10:57 Chousuke: unless you mean dynamic rebinding, which is sometimes useful

10:57 using the binding macro

10:58 alexyk: I just want to declare some (def *agents* []) on top, and do actual (<reassign> *agents* <actual creation>) in a defn

10:58 so I have *agents* in the repl for inspection

10:58 Chousuke: alexyk: that might be an okay use for alter-var-root

10:58 alexyk: Chousuke: I'm relieved :)

10:59 Chousuke: alexyk: just make sure not to make it a habit. :P

10:59 alexyk: I'll try :)

11:00 Chousuke: another way to do it might be to write a function that returns a vector of agents and then just do (def *agents* ...) though.

11:08 gko: Hello

11:10 lpetit: chouser: the community is wanting (also has not yet understood it's what it wants) your lightweight graphical REPL (with auto-indentation, bracket matching, and code completion, of course :-) ) to be delivered as an alternative to the current clojure.main & clojure.contrib.repl_ln textual REPLS !

11:12 Licenser_: lpetit: tgat wouold be cool

11:13 gko: How do you define functions that calls each other? I have this exception: "Unable to resolve symbol: decode-grouped-values in this context" because some function is calling decode-grouped-values, which itself calls this function...

11:14 lpetit: Licenser_: yes, because the other great current approach for noobs is : everything packaged in a zip, but those zips would be no less than a hundred megabytes, and that could stop noobs too :-)

11:14 Chousuke: gko: declare it first

11:14 just (declare foo)

11:14 conradbarski: ...

11:15 gko: Chousuke: OK

11:16 conradbarski: Hi- Anyone know a paredit trick for changing bracket types in a complex expression? i.e. to change "(((2 2) (1 1)) 3)" to "([(2 2) (1 1)] 3)" or similar changes...

11:16 gko: Chousuke: thanks!

11:17 fogus: lpetit: Have you seen the Beanshell graphical REPL? It's quite nice (caveat... I've only played with it briefly). I would love to see something like that for Clojure

11:17 lpetit: No, haven't seen it

11:18 fogus: quick link ?

11:18 ~google Beanshell graphical REPL

11:18 ~search Beanshell graphical REPL

11:18 hiredman: oh

11:18 I need to auth clojurebot

11:19 ~google Beanshell graphical REPL

11:19 ~google Beanshell graphical REPL

11:20 clojurebot: First, out of 248 results is:

11:20 A Taste of 2.8: The Interactive Interpreter (REPL) | The Scala ...

11:20 http://www.scala-lang.org/node/2097

11:22 _invis: Guys plz tell me how to set emacs working directory

11:23 lpetit: ~google Beanshell scripting environment

11:23 clojurebot: First, out of 4110 results is:

11:23 BshServlet and Servlet Mode Scripting

11:23 http://www.beanshell.org/manual/servletmode.html

11:23 lpetit: arg

11:23 cemerick: mmm, I'm going to make this clojure+maven post into a screencast.

11:23 _invis: thanks

11:23 fogus: lpetit: http://www.beanshell.org/manual/desktop.html

11:24 lpetit: fogus: thx

11:25 fogus: lpetit: np. So you're going to write something like this for Clojure right? ;-)

11:25 lpetit: fogus: grmlml

11:25 fogus: yes, after having finished ccw :-p

11:26 fogus: lpetit: So you're saying there's a chance? :p

11:26 lpetit: fogus: If, like cats, I have several lifes :-)

11:27 fogus: I guess I remember chouser talking about something like that, once

11:28 fogus: something using minimal dependencies but what the plain JDK API provides (aka swing)

11:28 fogus: Chouser's REPL-thingy could probably serve as the basis of a Beanshell-type environement

11:28 Right. Nothing external.

11:28 lpetit: fogus: so that a handful of clj files suffice to have something good enough for testing the language/working on small projects

11:30 fogus: My thoughts exactly. A no-thought way for new-comers to play with Clojure out of the box, but that is more than just the raw REPL.

11:31 zaphar_ps: any moderators for the clojure mailing list on here right now?

11:31 fogus: Ohhh, that happens to work one all OSes. But not an IDE

11:33 _invis: Guys plz tell me how to set emacs working directory

11:33 noidi: _invis, M-x cd

11:33 _invis: omg

11:33 noidi: but in emacs the working directory is per-buffer

11:33 _invis: thanks

11:34 noidi: and the default in each buffer is the directory of the file that you've opened in that buffer

11:34 _invis: ok

11:34 Raynes: Your working directory will be the directory of the file you're currently working on, afaik.

11:34 noidi: yes, unless changed with M-x cd

11:35 usually when I have to do something with a specific working directory, I just visit the directory in a new buffer with C-x C-f and then do the thing with the buffer active

11:45 arohner: what's the difference between (foo bar) and (#'foo bar)?

11:45 I'm trying to write a macro, and I think I need the first, but I'm getting the second

11:46 oh, that's a var...

11:48 Licenser_: okay anyone interested in trying to break a sandbox?

11:48 zmila: lpetit and fogus - this shell seems to be very similar to newLisp's GUI

11:49 lpetit: zmila, fogus: if only eclipse was not based on swt . Or if only the JVM shipped with both swt and swing :-)

11:51 fogus: Sounds like a JSR is in order... then we just wait a decade or so.

11:52 joshua-choi: If I have (defn f [s] (when (seq s) (lazy-seq (cons (inc (first s)) (f (nnext s)))))), does f hold onto s's head while computing?

11:53 Do I need to surround (f (nnext s)) with a lazy-seq form too?

11:53 Raynes: Licenser_: Can we add lein-swank as a dev-dependency?

11:53 Licenser_: Raynes: of cause

11:53 hiredman: clojurebot -> hornetq -> openvpn to laptop -> growl notifications of irc

11:53 ready for the enterprise

11:54 chouser: heh

11:54 Raynes: Licenser_: Thank you.

11:54 lpetit: chouser: heh

11:54 Licenser_: ah nothing to thank me

11:54 :)

11:55 _invis: Is anyone here know why I cant slime-connect to Labrepl ??

11:55 Have this message: open-network-stream: make client process failed: connection refused, :name, SLIME Lisp, :buffer, nil, :host,, :service, 4005

11:56 lpetit: joshua-choi: I guess your code should look like (defn f [s] (when-let [s (seq s)] .... ) , but this does not answer your question :-)

11:57 ,(doc nnext)

11:57 clojurebot: "([x]); Same as (next (next x))"

11:57 lpetit: joshua-choi: I'm pretty sure your code doesn't hold onto s head

11:58 Licenser_: so people who are named lloyd are actually (loyd (loyd))?

11:58 lpetit: Licenser_: yes, they were created with the Y operator :-p

11:58 Licenser_: :D

11:59 somnium: so that's what the Y is for...

12:01 joshua-choi: lpetit: Hopefully. But how can that be? s is referred to inside the lazy-seq code...When (f (nnext s)) is called, s is still in the lexical scope.

12:07 lpetit: joshua-choi: so you created a Seq instance with an object for first ready to be computed (holding a ref to s), and an object with code for computing the next seq, also holding s. You call next/rest on the seq, and you create the next Seq instance, which will hold the (nnext s) head

12:07 * lpetit guesses his explanation is full of holes ....

12:09 lpetit: joshua-choi: make the cal to (lazy-seq) be the first form of your method body, too

12:10 Licenser_: hey defn the way to fix the 'nothing found' problem is rather simple, if the sandbox test returns an empty list just show the other list ;)

12:10 lpetit: joshua-choi: (defn f [s] (lazy-seq (when-let [s (seq s)] ...

12:10 joshua-choi: Ah, right...the lazy-seq form returns immediately. But s is still in lazy-seq.

12:10 Would it be better if I (let [first-thing (first s), remainder (nnext-s)] (lazy-seq (cons (inc first-thing) (f remainder))))?

12:12 lpetit: joshua-choi: not needed, take a look at "take" implementation:

12:12 ~source take

12:12 Licenser_: woooh why is clojurebot pink?

12:20 SynrG: Licenser_: notice

12:20 Licenser_: SynrG: what should I notice?

12:20 ahhh sneaky pink people around!

12:20 SynrG: /notice #clojure feeling in the pink

12:21 joshua-choi: I get it now, I think. When the lazy seq evaluates itself later, whenever it's needed, it evaluates (f (nnext s)), creating another lazy sequence, but the head of s is free to drop off, since (f s) has already been called a while back.

12:25 lpetit: yes

12:26 SynrG: hmm. a debian colleague just indicated she has uploaded a cute game written in haskell for debian: http://raincat.bysusanlin.com/

12:26 clojure needs something like this :)

12:28 somnium: wow, it looks like a Miyazaki Haiyou short film

12:29 /s/Haiyou/Hayao

12:30 SynrG: next she's packaging something by the same authors, this time in "Stackless Python using SFML" (huh?) ... anyway: http://hobocat.bysusanlin.com/

12:30 somnium: ya :)

12:31 somnium: my little girls, ages 8 and 12, really love raincat. though i don't think i could effectively use that as a hook for learning haskell :)

12:31 Licenser_: but we have clicki! :P

12:31 somnium: SynrG: I can see how that would be challenging :)

12:32 * SynrG googles "stackless python" and sfml and is enlightened

12:33 somnium: that reminds me of a yegge blogpost comparing Scheme, ELisp, and CL. Scheme was a sports car with no radio or AC, ELisp was a Subaru compact, and CL was Howl's Magic Castle.

12:33 Chousuke: SynrG: if they manage to learn haskell, they should have little trouble in maths class ;P

12:33 SynrG: hehe

12:33 somnium: which raises the question, what vehicle is Clojure?

12:33 SynrG: Licenser_: clicki? whazzat?

12:34 dpritchett: Could someone help me udnerstand why (macroexpand-1 (->> 5 (- 3))) returns "-2" rather than "(- 5 3)"?

12:34 Licenser_: SynrG: my newest crazy inventiojn of cause!

12:34 zaphar_ps: somnium: the minivan

12:34 it gets stuff done

12:34 SynrG: somnium: how's moving castle, oo. nice :)

12:34 dpritchett: ... this is in re: fogus's blog from yesterday

12:34 zaphar_ps: and takes you places

12:34 Licenser_: A real wiki program (as it nearly entirely editable on the web)

12:34 SynrG: howl's

12:34 Chousuke: dpritchett: you're not quoting the expression

12:34 SynrG: clever. but cute?

12:34 Chousuke: dpritchett: you're passing 2 to macroexpand

12:35 dpritchett: and it returns the macroexpansion of 2, which is 2

12:35 Licenser_: SynrG: you can make it cute ;)

12:35 Chousuke: only, with minuses

12:35 dpritchett: Chousuke: indeed, thanks! I have read a few chapters/posts on Clojure macros but I haven't actually used enough to remember the proper syntax. Thank you!

12:35 SynrG: :)

12:35 Licenser_: just toss in a few cat pictures here and there :P

12:35 SynrG: hehe

12:36 Chousuke: dpritchett: it's not really a syntax thing. macroexpand just expects clojure code as an argument, and you were passing just a number :)

12:36 Licenser_: SynrG: make it cute :P - since you can edit about everything it i -

12:36 dpritchett: Just out of curiosity is there ever a case where someone would want to automate the use of macroexpand to compose larger functions and *not* quote out the argument? Would it be possible for the macroexpand macro to autoquote in case of noobs forgetting?

12:37 Chousuke: dpritchett: well, macroexpand shouldn't really be a macro because then it would have to expand itself with itself...

12:37 SynrG: Licenser_: a) no artistic talent here :p b) still can't see my little girls giving it rave reviews, even *with* cute cats

12:38 Chousuke: dpritchett: better just get used to the fact that you can pass code to functions. it's neat when you *really* finally get it.

12:38 dpritchett: Good point Chousuke, I don't know why I thought macroexpand was itself a macro.

12:38 Licenser_: Meh why not? They can edit the cute cats in clojure! Making more cute and cuter cute cats!

12:39 SynrG: <insert joke about cute cats and tail recursion here>

12:39 Chousuke: dpritchett: though in clojure the macroexpand function could be made a macro because it doesn't actually do the macro expansion for the compiler (there is a java method for that)... but that might someday change :)

12:39 Licenser_: I mean with 8 they are in the right age to learn something fundametnal like clojure!

12:39 chouser: can't run raincat -- maybe it's 32bit-only?

12:39 SynrG: humm ... debian now has packages for 32 and 64-bit ...

12:39 Licenser_: SynrG: we don't have automatic tail recursion :)

13:27 _invis: Guys I need a correct calculus with PI, but dont know how :(

13:27 ,(* 180.0M 3.7)

13:27 clojurebot: 666.0

13:27 _invis: ,(+ 180.0M 1)

13:27 clojurebot: 181.0M

13:28 chouser: ,Math/PI

13:28 clojurebot: 3.141592653589793

13:28 _invis: i know

13:28 but it will not be BigDecimal

13:28 ,(* 5 Math/PI)

13:28 clojurebot: 15.707963267948966

13:29 _invis: ,(* 5.0M Math/PI)

13:29 clojurebot: 15.707963267948966

13:29 _invis: so how I can take correct calculus ?

13:30 chouser: It sounds like you're asking for infinite precision.

13:30 _invis: ,(* 5.5M Math/PI)

13:30 clojurebot: 17.27875959474386

13:30 _invis: ,(* 5.5 Math/PI)

13:30 clojurebot: 17.27875959474386

13:30 _invis: the same result

13:31 not infinite, but more correct

13:31 chouser: how much more correct?

13:31 _invis: look

13:31 chouser: http://blog.objectmentor.com/articles/2009/08/05/generating-pi-in-clojure

13:31 defn: use one of the algorithms to approximate it

13:31 _invis: ,(* 5.5622322313254324131542313M 180)

13:31 clojurebot: 1001.2018016385778343677616340M

13:32 _invis: ,(Math/PI)

13:32 clojurebot: 3.141592653589793

13:32 _invis: ,(* 5.5M 3.141592653589793M)

13:32 clojurebot: 17.2787595947438615M

13:32 _invis: ,(* 5.5M Math/PI)

13:32 clojurebot: 17.27875959474386

13:33 _invis: I want first

13:33 chouser: so you want more digits of pi than is shipped with Java or Clojure.

13:34 _invis: why

13:34 chouser: I gave you a link above to code that generates pi to arbitrary precisions

13:34 _invis: same digits in the last 2 examples

13:34 chouser: why do you want more? I have no ida.

13:34 _invis: I think your link will help me

13:34 *hope

13:35 afk

13:42 Chousuke: _invis: you can't do correct calculus with doubles because it simply doesn't have the needed precision. You need BigDecimal

13:43 _invis: and multiplying a bigdecimal with a double produces a double because it can't be guaranteed that there is no loss of precision, so the answer is given in a form that doesn't pretend to be accurate.

14:19 ag90: Question about apply. Can it be used on static functions from Java stdlib? I'm trying to do (apply BorderFactory/createTitledBorder (list of arguments)) but it complains about not being able to find "static field: createTitledBorder in class javax.swing.BorderFactory". Any way around this?

14:20 chouser: apply only works directly on clojure functions, but there are a couple ways to get what you want.

14:21 One is to do something like (apply #(BorderFactory/createTitledBorder %1 %2 %3) mylist)

14:21 ag90: Yeah I considered that but the number of arguments is not known.

14:21 chouser: ...where you must supply exactly the number of %'s as the size of mylist.

14:21 ok

14:22 in that case you have to use reflection

14:22 ag90: Alright. Thanks.

14:23 chouser: something like (clojure.lang.Reflector/invokeStaticMethod BorderFactory "createTitledBorder" (to-array mylist))

14:23 ag90: Oh yeah that would do.

14:23 chouser: ag90: is createTitledBorder variadic itself?

14:24 ag90: createTitledBorder can take 0, 1, 2, 4, 5 and 6 arguments.

14:24 chouser: ok, what I pasted above should work.

14:24 ag90: No wait not 0.

14:24 Cool

14:24 Thanks

14:52 shales: What's the equivalent of a static main method in clojure?

14:54 vegai: shales: no such thing, is there?

14:54 Chousuke: you can write a static main method :P

14:54 vegai: really? Sick. :P

14:54 shales: I think I'm missing something

14:54 vegai: what?

14:54 clojurebot: what is wrong with you

14:55 vegai: clojurebot: heh. Touche.

14:55 Chousuke: using gen-class, you can generate a class from your namespace, and the namespace can have a function that corresponds to the main method

14:55 clojurebot: It's greek to me.

14:55 Chousuke: but if you don't use gen-class, then clojure has no such thing as a main method :)

14:55 things are simply evaluated in order

14:55 shales: I'm using leiningen to build a jar and it appears to be running the function call I have in a clj file when I run 'lein jar'

14:56 I was using this function call as my "main" equivalent when I ran that script

14:56 Chousuke: that would happen, yes

14:56 shales: but I don't understand why it runs when I use lein jar

14:56 Chousuke: because the code is executed

14:56 the entire file. including the function call.

14:57 shales: ya, clearly, but why is executing it necessary to build a jar file?

14:57 Chousuke: it's necessary because to build a jar file you need to evaluate the code that makes up the jar file

14:58 chouser: (def foo 10) (defmacro bar [] `(list foo)) (defn bash [] (bar))

14:58 Chousuke: Clojure differs from Java and other statically compiled languages in that in java the compiler reads code, compiles it, generates bytecode, and there is a static entry point.

14:58 chouser: in order to compile bash, bar must be evaluated. In order to evaluate bar, the value of foo must be evaluated.

14:58 Chousuke: but clojure starts by reading one expression, compiling it, executing it, then reading the next expression, compiling it, and executing it...

14:59 shales: oh, I'd thought the jar would contain the clj source and that would be compiled when it was eventually run.

14:59 Chousuke: well, that could happen too

14:59 chances are you're telling lein to precompile things

15:02 shales: so is it a better to not precompile or to use gen-class with a static main method

15:02 ?

15:02 chouser: in general I'd recommend avoiding external side-effects in top-level code. Then you can do either.

15:03 technomancy: shales: it's best not to precompile unless you have a specific need that's forcing you to do it

15:03 but making executable jars is a decent reason if you're distributing to end-users

15:04 slyphon: wow, this is bizarre, i'm getting a "wrong number of args passed to blah" exception, but i'm like, so not

15:05 does having a {} as the last argument do something funky?

15:05 drewr: it counts as one, so no

15:05 shales: Ok, but it sound like even if I'm making a exectuable jar I should still use gen-class. I'll give that a shot.

15:05 kotarak: slyphon: paste the code?

15:05 * slyphon is totally baffles

15:05 slyphon: kotarak: one sec

15:07 kotarak: https://gist.github.com/b2f6b5577b32099e1062

15:07 i gotta run out for lunch

15:07 bbiafm

15:07 kotarak: it's on line 43

15:07 i'm calling it like (canonicalize-params (Date.) "12345" {})

15:08 drewr: slyphon: is it possible the exception is referring to something else?

15:08 kotarak: most likely

15:23 slyphon: hrm

15:24 ynef: newbie question: this works: (filter #(zero? (rem 12 %)) (range 2 (inc (/ 12 2)))) but this does not: (defn divisors [n] (filter #(zero? (rem n %)) (range 2 (inc (/ n 2))))) and then calling (divisors 12)

15:24 slyphon: oh, ffs

15:24 ynef: why?

15:24 clojurebot: http://clojure.org/rationale

15:24 slyphon: kotarak: it's on line 56

15:25 no, shit

15:25 kotarak: slyphon: the map!

15:25 chouser: ynef: both return (2 3 4 6) for me

15:25 kotarak: #(lsajdflkj %1 %2) wants two arguments

15:26 ynef: chouser: that's really interesting, since I get something different :-/

15:26 kotarak: slyphon: you have to use (fn [[a b]] (... a b))

15:26 slyphon: oh, shit, yeah

15:26 kotarak: good catch

15:26 ynef: chouser: nevermind, it was a problem with my eclipse plugin not reloading since I did some changes

15:26 * ynef is stupid

15:26 chouser: or maybe #(str-join "=" %)

15:27 ynef: np

15:27 ynef: thanks anyway, you helped me regain some sanity :-)

15:27 slyphon: chouser: oh, yeah, i'll try that

15:27 chouser: yep, worked, thanks

15:27 kotarak: thanks

15:28 kotarak: yw

15:30 Raynes: technomancy: "Q: What's the difference between Ant and Maven? A: The creator of Ant has apologized."

15:30 Good show.

15:31 slyphon: HAH

15:37 Raynes: You know, Rich Hickey appreciation day is coming up soon.

15:38 Oh shit. We missed it.

15:38 It was the 20th.

15:38 It's hilarious how you can forget a mock holiday you yourself created

15:40 shales: Question about work flow. I'm using emacs, swank and leiningen. I'm creating a little toy app that has a couple clojure libs and a main class. I can build a jar with lein and execute that fine. Now what is the best way to rerun and test things without building a jar?

15:41 I haven't figured out how to run the main function using 'java -cp ... clojure.main'

15:42 kotarak: clojure.main -e "(main)"

15:46 shales: If the function is namespace is this the best way? clojure.main -e "(use 'bonjure.main) (-main)"

15:46 is *in* a namespace

15:47 Raynes: clojure.main -e "(bonjure.main/-main)"

16:01 ynef: I get a "ClassCastException" -- is there any way of getting more details about an exception? like what caused it?

16:01 This is what gives me problems: (defn abundant [limit] (filter #(> (reduce (+ (divisors %))) %) (range 3 (inc limit))))

16:01 I thought that would be reasonable :-)

16:02 chouser: reduce wants a fn -- (+ ...) probably doesn't return a function

16:03 maybe (apply + (divisors %)) ?

16:04 instead of (reduce ...)

16:07 underdev: how do i check the version of clojure that's running in a repl. I'm trying to use labrepl within emacs, but i think i'm using my original 1.1.0 clojure

16:07 chouser: ,(clojure-version)

16:07 clojurebot: "1.1.0-master-SNAPSHOT"

16:07 chouser: ^^^ that actually means something before the 1.1 release

16:07 underdev: nope, i'm good

16:08 thanks chouser

16:47 raek: how can I make sure a function is always runned in a transaction?

16:47 simply suround its body in a dosync?

16:48 I want to make sure that all the refs are read at the same time

16:49 but these functions will be building blocks that other code will use inside transactions

16:49 marten: hmm, is it possible to catch the exception thrown when an assertion fails?

16:50 (try (some-fn-with-assertion) (catch Exception _ "exception occurred")) doesn't seem to cut it

16:51 , (try ((fn [] {:pre [false]} "fn returned")) (catch Exception e "exceptioned"))

16:51 clojurebot: marten: Pardon?

16:52 slyphon: clojurebot: who are you, richard nixon?

16:52 clojurebot: Gabh mo leithscéal?

16:52 slyphon: well, i guess he told *me*

16:53 chouser: (doc io!)

16:53 clojurebot: "([& body]); If an io! block occurs in a transaction, throws an IllegalStateException, else runs body in an implicit do. If the first expression in body is a literal string, will use that as the exception message."

16:53 chouser: oh, that's backwards.

16:54 raek: yeah, use dosync. they nest fine.

17:01 shales: If I have two namespaces, A and B, where B has a (:use A), and I move function from A to B, how do I reload these namespaces in slime?

17:02 I get "Name conflict" errors when I try to C-c C-k the clj file for namespace B.

17:02 How do I get it to recognize the function was removed from A?

17:05 Drakeson: if I replace a .jar and re-evaluate the (ns ...) importing it, possibly with :reload-all, will the new .jar be used?

17:06 kotarak: Drakeson: no

17:06 * Drakeson curses java.

17:06 Drakeson: thanks

17:06 kotarak: Drakeson: put the contents in a directory. files may change and the changes are picked up

17:07 Drakeson: put the ".class"es in a directory? e.g., jar xf foo.jar?

17:08 kotarak: Drakeson: the class files can be loaded only once, but clojure source files can change.

17:09 Drakeson: the thing I want to reload is unfortunately java. I guess I have to suck it up and restart the vm

17:09 marten: shales: try (remove-ns 'A)

17:09 destroys the entire namespace though

17:09 kotarak: Drakeson: that the most straight-forward thing. You could fiddle with class loaders or use jrebel & friends.

17:09 shales: ns-unmap

17:12 slyphon: hfm, you can't do (is (not (thrown? ))) ?

17:12 (is (thrown? )) works

17:12 * slyphon is a little confused

17:12 * slyphon goes to look at teh sores

17:13 shales: marten: thanks, getting a different compiler error now but may not be related

17:14 kotarak: that's for individual symbols only? does remove-ns essentially do the same thing for all of the symbols?

17:14 marten: oh, doh. to answer my own question, java.lang.AssertionError is not a subclass of java.lang.Exception, so catching Exception doesn't help catching failing preconditions

17:15 kotarak: shales: I though you just want to remove the single function from the namespace A. But now that I think about it, you'll probably have to unalias things in B two. Does (require :reload-all 'B) help?

17:16 rys: hmm, brain fail: how would I take every nth pair of items from a seq, until the seq is completely evaluated?

17:18 kotarak: rys: quick guess (take-nth 2 (partition 2 ...))

17:18 ,(take-nth 2 (partition 2 [1 2 3 4 5 6 7 8 9 10 11 12]))

17:18 clojurebot: ((1 2) (5 6) (9 10))

17:19 rys: sweet, just what I needed

17:19 thanks

17:25 erikcw1: When I try to use SLIME commands (such as C-c C-x) from aquamacs, I get "Symbol's function definition is void: lisp-eval-last-sexp". I'm using M-x slime-connect in conjunction with "lein swank". Anyone have any ideas as to why my keybinding aren't working?

17:28 slyphon: aquamacs is Emacs 0.22.x, i think there's a note that says the swank-clojure thing is written for 0.23.x

17:30 erikcw1: slyphon: I'm on emacs 23 - -I'm using 2.0

17:30 aquamacs 2.0 that is

17:30 slyphon: hrm

17:30 weird

17:30 dunno then

17:37 shales: kotarak: the (require :reload-all 'B) didn't work. It's as you suspected though. After moving the function foo from A to B and doing C-c C-k in A's buffer, there is still this (get (ns-refers 'B) 'foo) => #'A/foo

17:38 kotarak: (doc ns-unmap=

17:38 clojurebot: EOF while reading

17:38 kotarak: (doc ns-unmap)

17:38 clojurebot: "([ns sym]); Removes the mappings for the symbol from the namespace."

17:39 kotarak: shales: you could simply try ns-unmap for foo in B.

17:39 shales: or ns-unalias

17:40 shales: yeah, I did. ns-unmap works, but it's a pain to remember what was moved and do that for each symbol

17:40 kotarak: I don't know whether this refers to namespace aliases, though

17:41 slyphon: so, with defmacro, if there's a &blah in the params, there *must* be more params?

17:43 kotarak: slyphon: no

17:43 slyphon: kotarak: https://gist.github.com/c969b7ac480d5d663e5e

17:44 arohner: Is there anything I can do to reduce the occurrence of PermGen errors?

17:44 slyphon: arohner: yes

17:44 one sec

17:45 http://blog.headius.com/2009/01/my-favorite-hotspot-jvm-flags.html

17:45 -XX:MaxPermSize=512M

17:46 arohner: slyphon: but I'm leaking if I run out of permgen, right?

17:46 slyphon: hm?

17:46 well

17:46 dnolen: it seems like Clojure is really picking up steam in Japan from all the tweets.

17:46 slyphon: there's another arg i use with jruby

17:46 one sec

17:46 arohner: what typically happens is I'll leave a repl open, and after several hours of developing, I hit the rmGen error

17:46 slyphon: oh

17:47 well, yeah, you're generating a lot of class garbage

17:48 i use -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled

17:48 that really helped with long-running jruby processes, might help with clojure

17:50 kotarak: slyphon: maybe something like this? http://paste.pocoo.org/show/193515

17:50 arohner: slyphon: thanks!

17:50 slyphon: arohner: sure

17:50 kotarak: ahh, that looks promising

17:51 kotarak: thanks

17:51 kotarak: np

17:51 noss: is there any killer app in clojure that is not related to being a dev tool on clojure projects?

17:53 arohner: noss: you mean a killer app of clojure, aside from developing in the language?

17:53 noss: arohner, yeah

17:54 im sitting here as an erlang programmer, feeling a bit skeptical about the concurrency primitives in clojure. I want to see it used in a complex app.

18:00 Raynes: No.

18:00 Not in the traditional "killer app" sense.

18:01 I'm sure there is a complex concurrent app around somewhere though.

18:02 noss: any real-life things then? a web app? a wiki... etc?

18:02 dnolen: noss: I think Penumbra is pretty interesting, it's for OpenGL. But you can safely and *easily* update the world state from multiple threads of execution, even though OpenGL itself is single threaded. but that applies to any app reall.

18:02 noss: web apps are not a good real world case since, http is stateless anyway. perhaps a complex web service, but not your average web app.

18:03 noss: web apps do more than communicate over http.

18:05 slyphon: kotarak: works like a charm, thanks!

18:06 kotarak: slyphon: :)

18:11 Drakeson: what is the current way for generating a [named] class dynamically?

18:15 Chousuke: Drakeson: is that even possible?

18:16 Drakeson: I don't know how dynamic it can be.

18:16 kotarak: Drakeson: you can do it once, but when the class is loaded it is put in concrete. (At least this is my understanding)

18:17 Drakeson: that is still [kinda] OK.

18:18 kotarak: Drakeson: but this is only a vague understanding on my side. Take with grain of salt.

18:34 joshua-choi: Is there any value in writing a Clojure parser in *pure* Clojure—that is, without any calls to Java methods—as opposed to having Java methods here and there?

18:34 Chousuke: joshua-choi: that would be quite the feat

18:34 joshua-choi: You mean, yes?

18:35 programble: where java isnt broke, clojure doesnt fix it

18:35 joshua-choi: Oh, "feat". I read is as fact. :)

18:35 Chousuke: it might be useful for non-java clojures too, so maybe. :P

18:35 programble: its on the JVM, feel free to use the Java API

18:35 joshua-choi: Chousuke: That's what I was thinking of.

18:35 I'm wondering if it would be useful for any bootstrapping

18:36 But if there's no point, I won't bother, since Java methods are really fast

18:36 Chousuke: I wrote a reader in clojure a while back but it didn't turn out that good :)

18:36 joshua-choi: I have a finished product

18:36 Chousuke: it was pretty ad-hoc

18:36 joshua-choi: But I'm wondering if it would be worth testing and debugging

18:36 Chousuke: does it use only core clojure? :/

18:37 ie. no external libraries

18:37 joshua-choi: And clojure.contrib.monads and clojure.template, which do not use any Java methods to my knowledge.

18:37 Chousuke: (java counts as core clojure :P)

18:37 joshua-choi: Yeah...

18:38 Chousuke: I would really like to see any of the java parts in clojure replaced with a clojure solution, so I'm supportive

18:38 joshua-choi: Would a Clojure parser that uses Java methods still be useful?

18:39 Chousuke: probably

18:39 it will *have* to use java methods at some point anyway

18:39 what matters is just how well it's hidden

18:39 joshua-choi: Well, I'm assuming that clojure.core's functions are the bottom line

18:39 But that might not be a useful distinction, maybe...

18:40 Chousuke: you can't do IO or string operations with just clojure.core though :)

18:40 joshua-choi: At least until Clojure isn't unique to the JVM anymore

18:40 Yeah, I'm starting with strings only

18:40 Chousuke: but once it's mostly clojure, wrapping the java parts should be trivial if the need arises to port it to another host

18:40 joshua-choi: String inputs, I mean

18:40 Yeah, that's right

18:41 mitkok: Anyone using swank-clojure without package.el ( elpa ) ?

18:41 Chousuke: I think I am. :P

18:41 joshua-choi: It's things like Integer/parseInt and Character.toUpperCase anyway

18:43 Well, I'll keep the pure Clojure version around as a proof-of-concept, I guess; for showing off my library, if nothing else :)

18:43 Chousuke: heh.

18:44 I don't think it would hurt to ask what Rich and others think about it.

18:45 and it might turn out to be useful for IDE plugins or something

18:46 but, sleep. later.

18:46 joshua-choi: Good night. If it's night.

18:47 Raynes: Nighttime is constant. Day is an illusion.

18:47 joshua-choi: Java question: does Character/isDigit accept non-ASCII digits such as Devanagari and fullwidth digits?

18:48 I can't test it on my REPL

18:48 Drakeson: Can I access a not-AOT-compiled clojure function or class from java? (i.e., does the class have to be on the disk?)

18:48 arohner: mitkok: yeah, I am

18:49 Drakeson: you can get at it through the var

18:49 Drakeson: I don't have a running repl at the moment, but it's something like v = Var.find("foo"); v.invoke();

18:50 invoke takes the same args that the clojure fn takes

18:50 Drakeson: how do I get at the namespace? Var.find("the.namespace.foo") ?

18:51 kotarak: Or v = RT.var("the-namespace", "the-var")

18:51 Drakeson: thanks

18:51 mitkok: arohner: Can you show how you load it, I used to load it like this: http://github.com/mitkok/emacs/blob/master/defunkt/clojure.el, but now it gives me error on (require 'swank-clojure-autoload)

18:51 kotarak: When would one use == instead of =?

18:51 mitkok: arohner: I'm using joshu swank-clojure and clojure-mode, not technomancy's

18:52 arohner: I do (add-to-list 'load-path "~/Programming/swank-clojure")

18:52 (require 'slime)

18:53 I have a separate script that starts up my clojure process, and then I connect through M-x slime-connect

18:53 kotarak: when you want fast integer compares

18:54 mitkok: which slime are you using?

18:55 CVS Head slime is known not to work for clojure

18:55 mitkok: arohner: I have a clone of git://git.boinkor.net/slime.git

18:55 arohner: mitkok: I'm using technomancy's github mirror of slime, and technomancy's swank-clojure and clojure-mode

18:56 mitkok: arohner: but doesn't these repos depend on package.el ?

18:56 arohner: maybe? I don't know

18:56 I think I have elpa installed, but I'm not using it for any clojure stuff

18:57 mitkok: because in the readme you have to geto the repos and install it with M-x package-install-from-buffer

19:14 alexyk: I have a sequence of vectors, each of pairs. I can convert each into a map with (into {} v), that'll do transients for me. But what about several such v's, [v u]?

19:17 _mst: maybe reduce?

19:17 ,(reduce into {} [[[:a :b]] [[:c :d]] [[:e :f]]])

19:17 clojurebot: {:a :b, :c :d, :e :f}

19:19 alexyk: I was thinking about that, should be ok

19:19 can you deref in #(..) as #(.. @% ..) ?

19:19 or have to use (deref %) ?

19:20 _mst: yep, @% should work

19:26 alexyk: how do you destructure struct's?

19:27 if you do

19:28 The-Kenny: Just like hashmaps I think

19:29 _invis: In the labrepl:

19:29 Our first reduce example showed using reduce to perform repeated addition. But in Clojure, the + function can itself perform repeated addition! What advantages does reduce offer over implicit reduction within a funtion?

19:29 Could you tell me what they mean ?

19:31 alexyk: The-Kenny: yep. thx

19:31 qbg: _invis: Why would you use (reduce + coll) instead of (apply + coll)

19:31 The-Kenny: alexyk: structs are just maps with some special, more efficient backend

19:31 qbg: ?

19:32 _invis: qbg: dont know

19:34 qbg: what authors mean when told What advantages does reduce offer over implicit reduction within a funtion? ??

19:36 qbg: I'm not sure that there is much of a difference....

19:36 I know why you wouldn't want to use (apply + coll) in CL, but that doesn't apply here

19:37 _invis: emm so why ?

19:37 qbg: _invis: Why in CL?

19:38 _invis: yes


19:38 _invis: I just dont know what the difference between apply and reduce. So I dont care what to use.

19:39 programble: apply is like

19:39 (apply + (1 2 3))

19:39 makes

19:39 (+ 1 2 3)

19:39 clojurebot: *suffusion of yellow*

19:40 programble: (reduce + (1 2 3))

19:40 would be

19:40 _invis: ,(apply + '(1 2 3))

19:40 clojurebot: 6

19:40 programble: well

19:40 same in this case

19:40 _invis: ,(reduce + '(1 2 3))

19:40 clojurebot: 6

19:40 programble: bad example

19:40 lol

19:41 qbg: (reduce + (1 2 3)) == (+ (+ 1 2) 3)

19:41 _invis: ,(apply + (1 2 3))

19:41 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

19:41 _invis: ,(reduce + (1 2 3))

19:41 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

19:41 _invis: you wrong

19:42 I think )

19:42 qbg: ,(reduce + '(1 2 3))

19:42 clojurebot: 6

19:42 programble: need the '

19:42 _invis: so what the different with apply ?

19:42 programble: (reduce + '(1 2 3)) == (+ (+ 1 2) 3)

19:42 _invis: yes I know

19:42 programble: (apply + '(1 2 3)) == (+ 1 2 3)

19:42 _invis: :)

19:43 reduce is recursion that's it ?

19:43 qbg: I think the only real question is which one is more idiomatic

19:43 _invis: I ask you not about apply :0

19:43 *:)

19:43 What advantages does reduce offer over implicit reduction within a funtion?

19:43 noss: ,(reduce #(list 'x %) '(1 2 3))

19:43 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--3729$fn

19:44 noss: hmm.

19:45 qbg: I'd think that explicit reduce would be more idiomatic

19:45 joshua-choi: noss: The function needs two arguments. If you didn't know. :)

19:46 noss: ,(reduce #(list 'x %1 %2) '(1 2 3))

19:46 clojurebot: (x (x 1 2) 3)

19:48 _invis: is this advantage about authors told ?

19:50 qbg: I don't know what the authors are looking for.

19:51 _invis: hmm ok

19:51 ty

20:04 (reverse "foobar")

20:04 Why is reverse's behavior the right thing to do, even for strings, and what options can/should be provided for String->String functions?

20:04 O_o

20:04 Raynes: ,(apply str (reverse "foobar"))

20:04 clojurebot: "raboof"

20:04 _invis: thanks

20:05 programble: raboof lol

20:05 _invis: the same as reduce

20:07 alexyk: I'm debugging agents. They have errors. How do I terminate whatever an agent was doing?

20:07 or reset it

20:09 or, how do I inspect which errors an agents has?

20:10 seths: ,(find-doc #"agent.+error")

20:10 clojurebot: ------------------------- clojure.core/agent-errors ([a]) Returns a sequence of the exceptions thrown during asynchronous actions of the agent. ------------------------- clojure.core/clear-agent-errors ([a]) Clears any exceptions thrown during asynchronous actions of the agent, allowing subsequent actions to occur.

20:34 alexyk: seths: you did it again

20:34 seths: wow, I must have superpowers that I don't know about

20:34 magic net-splitting powers

20:35 alexyk: magic incantation is "uh oh"

20:35 Bill Gates rebooted the internet again

20:36 seths: lol

20:40 defn: Licenser: around still?

20:40 Licenser: had a chance to fix that issue with walton? I'm going to work on performance for awhile tonight I think

20:53 whoa. i think im close to figuring out how to get circumspec working! :)

21:05 seths: defn: have you checked out labrepl?

21:05 it has a working config, even with file-system watchers to rerun tests after app code changes

21:06 http://github.com/relevance/labrepl

21:10 defn: oh sweet

21:10 thanks seths

21:12 hiredman: clojurebot: ping?

21:12 clojurebot: PONG!

21:12 hiredman: excellent

21:12 defn: ,(doc try)

21:12 clojurebot: Gabh mo leithscéal?

21:13 hiredman: special forms are special cased in the real doc function, but I haven't done it in clojurebot's doc

21:18 defn: oh nevermind seths -- looks like that's for netbeans only

21:18 nvm

21:18 seths: defn: labrepl is a leiningen app

21:18 defn: *nod* i see that now -- i just hadnt read beyond a couple headings :)

21:18 seths: when I used it in the Clojure training course I was running it from Emacs / swank-clojure

21:18 defn: oh man I wish I could have went to that

21:18 how much $ was it?

21:18 seths: we were Stu's guinea pig

21:19 company paid, but at least $1500 I think, depending on alumni discount

21:19 another course in May

21:19 Stu and Rich autographed my copy of Programming Clojure :-)

21:19 best training ever

21:19 ,101r3

21:19 clojurebot: Invalid number: 101r3

21:20 qbg: ,3r101

21:20 clojurebot: 10

21:20 seths: ah, ty

21:21 alexyk: how do you use doto to compress: (.print System/err s) (.flush System/err) ?

21:21 qbg: (doto System/err (.print s) .flush)

21:21 alexyk: thx

21:22 defn: holy labrepl dependencies batman

21:23 seths: lol

21:23 qbg: Not having tried it, it doesn't look that bad...

21:23 seths: maven is your friendly internet backup tool

21:23 it backs up the internet to your computer

22:23 qbg: Why can't I destructure in the arglist in the implementation of a protocol method in deftype?

22:25 brian__: hi, I am trying congomongo, I create the database , then when I do this: (insert! :robots {:name "robby"}) , i get com.mongodb.MongoException$Network: can't say something (NO_SOURCE_FILE:0)

22:26 seths: qbg: I asked that to Rich

22:27 shales: Should a recur work in one of the result-expr of a case? I'm getting a "Can only recur from tail position" error

22:27 seths: trying to remember what he said

22:27 shales: this doesn't compile (defn foo [] (case 1 1 (recur)))

22:29 seths: my take on what he said was that the [bar baz] in (deftype Foo [bar baz]) defined a list of fields

22:30 it's not a function call at that moment

22:30 a factory method (and constructor for Java) is defined for that list of fields

22:30 and the factory method seems like a good place for destructuring

22:31 but not sure how to add that between listing the type's fields and defining the factory function?

22:31 qbg: I'm talking about something like (deftype Rect [p1 p2] Shape (contains [[x y]] ...))

22:31 seths: I am probably misrepresenting Rich horribly

22:31 qbg: I'm not sure we are talking about the same thing

22:31 underdev: does anyone know a command to clear the repl of the functions used in the current session

22:31 qbg: (I'm talking about the contains part)

22:31 underdev: ?

22:32 qbg: underdev: Before I've just removed all of the interned vars from the namespace

22:32 seths: ah, I was talking about p1 p2

22:32 qbg: I don't like having to do (contains [point] (let [[x y] point] ...))

22:33 seths: qbg: so you want something like (deftype Rect [[x1 y1] [x2 y2]] (contains [x1 y1] ...)) ?

22:33 roughly?

22:34 qbg: No, just destructuring in the function/whatever definition

22:34 seths: ah ok

22:34 qbg: The arity is already known, so I don't see why it couldn't be provided.

22:34 seths: I didn't ask that question :-)

22:35 sorry for the confusion

22:35 qbg: no problem

22:36 underdev: Something like (map #(ns-unmap *ns* %) (keys (ns-interns *ns*)))

22:52 underdev: qbg: thanks, i was having a collision. I just changed the namespace.

22:53 qbg: clever idea though~

22:54 qbg: Actually (doseq [sym (keys (ns-interns *ns*))] (ns-unmap *ns* sym)) would be more correct

22:58 defn: anyone here familiar with incanter?

22:59 liebke: defn: what's up?

22:59 defn: oh nothing really at the moment -- i was thinking about cheating and asking someone to solve my problem for me but then thought better of it

23:00 liebke: ah :)

23:00 defn: BUT...since I have the man himself here... I have a structure that looks like {"" {:count 5 :country "US"}}

23:00 only it is much larger obviously

23:00 im interested in graphing some of that in incanter and was wondering where a good place to start might be

23:01 sort of an open ended question i know, but if you don't have a good answer I can experiment for a bit

23:01 <--first time incanter user

23:02 liebke: perhaps a more fitting question would be to ask which clojar i should be using :)

23:02 liebke: defn: if you converted that structure into an array of maps, like {:count 5 :country "US"}, you'd pretty much have an incanter dataset, which you could use in bar-chart (or line-chart)

23:03 what do you mean by which clojar?

23:03 defn: err, there are several incanters on clojars.org

23:03 was just wondering which is the "right" one

23:03 im using [incanter "1.0-master-SNAPSHOT"] IIRC

23:03 liebke: ah, don't use the version on clojars, they are old. go to http://repo.incanter.org

23:04 defn: awesome -- thanks

23:05 liebke: defn: I'm about to sign off, but if you have more questions, just send an email to the Incanter Google group

23:20 brandonw: is there a way to have an atom be a seq, and then change the atom such that it equals the second half of a call to split-at, while retaining the first half of split-at for something else?

23:20 or should i just use a ref for that type of thing?

23:21 defn: (:use [clojure.contrib.duck-streams :exclude (copy)]...

23:21 that should work right?

23:22 copy already refers to: #'clojure.contrib.duck-streams/copy in namespace: geoip.core

23:22 brandonw: i guess what i need to do isn't truly an atomic operation

23:23 arohner: brandonw: what do you mean "while retaining the first half"?

23:23 brandonw: i would have to do something more like a loop that continually takes the first x items out of the seq

23:23 for example

23:23 say i have an atom containing the value [1 2 3 4 5 6]

23:23 arohner: you can always do (swap! atom #(split-at x %))

23:23 brandonw: and i want to swap! the atom to be [5 6], but then operate on [1 2 3 4] separately

23:23 yes, but then i wouldn't know what the first part is

23:23 arohner: ah

23:23 brandonw: i think i do need to use a ref

23:23 arohner: what do you want to do with the first half?

23:24 brandonw: i basically have a queue that i add items to

23:24 and then every 'tick' i want to take the first x items and send them through a proxy

23:24 and set the new queue to be the rest of the items

23:24 arohner: ther e two reasons to use refs over atoms: 1) you want multiple refs to have coordinated changes 2) you're doing something where the performance is important

23:24 err #2 is a reason to use atoms over refs

23:24 brandonw: yeah, that is what i was thinking

23:25 i don't think i would classify what i want to do as coordinated

23:25 arohner: what is your proxy?

23:25 brandonw: since i only need to do a single change to the value

23:25 well it is basically a vector of structs

23:25 i want to take the first x maps, convert them into a string form to send over an actual network proxy

23:25 arohner: oh, that's important

23:26 refs and atoms are extremely likely to retry their operations

23:26 defn: (ns my.ns (:use [clojure.contrib.duck-streams :exclude (copy)] (incanter core charts))) -- even when excluding copy it is complaining that duck-streams already refers to copy

23:26 brandonw: and retain the rest of the elements for the next 'tick' (so that i never send more than a certain number at a time in order to not overload the receiver)

23:26 arohner: the things you do inside swap! or alter should be side-effect free

23:26 brandonw: right

23:26 i am not doing the side effect in the swap

23:26 only the splitting of the partition

23:26 arohner: you could send the other part to an agent

23:27 brandonw: but how would i get the other part from the swap! operation?

23:27 arohner: in that case, you would use a ref

23:27 the STM sends all outstanding agent sends when the transaction succeeds

23:28 (dosync (let [[first second] (split-at)] (alter foo (constantly second)) (send my-agent first)))

23:28 brandonw: if i can only do (swap! queue (second #(split-at x %)))

23:28 right

23:28 that's what i was thinking

23:28 so is this actually considered a coordinated change?

23:28 even though i technically am only performing a single operation on the atom?

23:29 arohner: if you want the agent send thing, I think you need to use a ref

23:29 brandonw: well, ignoring the agent piece of it

23:29 forget i said anything about a proxy or anything else

23:29 arohner: yes (swap! queue (second #(split-at x %))) is a single change

23:29 brandonw: if i had something like (swap! queue (second #(split-at x %))) to modify the queue in the atom, is there any way to retain the first piece of that split-at?

23:30 arohner: a second atom, but that's a little weird

23:30 brandonw: how is it weird exactly?

23:31 this is my first foray into the threading pieces of clojure, i'm just trying to make sure i have the foundations right

23:31 arohner: actually

23:32 brandonw: how would you even do it with a second atom? it seems like the process of swapping the atom means there is no way to retain the first piece of the split-at call

23:32 arohner: (let [[first second] (split-at...) (swap! a (constantly first)) (swap! b (constantly second)))

23:32 brandonw: since the function call to swap it has to be within the context of the swap! call, and if i split them before the call to atom, then i risk the atom being modified after i bind a local var to the result sof the split-at but before i call swap!

23:33 arohner: is this called from multiple threads?

23:33 I guess that's a bad question in clojure

23:33 brandonw: yes, there will be other threads

23:33 arohner: if it matters, You're Doing It Wrong

23:33 brandonw: i should have mentioned that at the start

23:33 yeah, that's true

23:34 i think i'll use a ref, it seems like what i am trying to do requires a little too much coordination to fit into an atom

23:34 arohner: yeah

23:34 brandonw: i am actually porting something to clojure

23:34 and realistically, i don't think the queue element limit will ever even be reached

23:35 so it probably won't even matter. i might as well just skip the split and just swap! to a new emtpy seq, and pass the current value of the atom through the proxy :D

23:35 but.. i shouldn't be lazy, haha

23:35 i'll do it right :)

23:40 whoaaaaa

23:40 i'm a dope

23:40 i just realized... it's a queue

23:40 anything added after i get a value of the atom won't matter

23:41 i can split it up beforehand, because as long as i only remove the number of elements in the seq i split, then it will still be consistent

23:42 so i could do like you said: (let [first-piece (split-at x @atom-var)] (swap! atom-var #(drop (count first-piece) %)))

23:42 and that would work perfectly

23:42 defn: How would I use destructuring to get {:foo {:bar 1 :baz 2}} => [{:bar 1 :baz 2}]?

23:45 ,(let [[_ [bar baar baz baaz]] {:foo {:bar 1 :baz 2}}] bar baar baz baaz)

23:45 clojurebot: java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap

23:45 defn: hmm

23:50 brandonw: i definitely need to learn destructuring; haven't used it much yet

23:50 defn: yeah im struggling with it

23:50 :\

23:53 it seems like this should be a lot easier than im making it

23:55 brandonw: i *think* (with almost no experience destructuring) that the correct way would be:

23:55 ,(let [{i :foo} {:foo {:bar 1 :baz 2}}] [i])

23:55 clojurebot: [{:bar 1, :baz 2}]

23:56 defn: huh... how does that work...

23:56 brandonw: the part where you add a vector to the value-- i don't think you can do that in destructuring, since a vector isn't part of the initial structure

23:56 defn: i think you can with :ivec maybe

23:56 brandonw: basically, you pull the value corresponding to the :foo key of the arg, and wrap a vector around it

23:57 what is :ivec?

23:57 haven't heard of it

23:57 defn: im about to find out :)

23:57 im just reading the special_forms doc on clojure.org

23:58 ,(let [{i :foo} :ivec {:foo {:bar 1 :baz 2}}] i)

23:58 clojurebot: java.lang.IllegalArgumentException: let requires an even number of forms in binding vector

23:58 defn: hmm that's not it

23:59 brandonw: only docs i find on :ivec is on the special forms page, and i can't figure out at all what it does

23:59 i think my solution would work though

23:59 defn: brandonw: i think it is short for internal vector

23:59 brandonw: if you have a map as an input, i'm not sure if you can destructure it into a vec, since a vec isn't part of its initial structure

Logging service provided by n01se.net