#clojure log - Oct 19 2011

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

0:03 amalloy: yeah, i don't think jark has really caught on

0:06 scottj: yeah, though I do use it for several scripts

0:07 cake (and jark) support #!

0:07 amalloy: scottj: what support is necessary?

0:09 scottj: amalloy: well b and c from your earlier comment

0:10 ibdknox: haha awesome: webnoir.org shows up on the first page of results for the word "noir"

0:10 scottj: now we just need pinot up there

0:11 ibdknox: :)

0:11 and Korma!

0:11 lol

0:11 tomoj: does jark come with caveats?

0:12 scottj: tomoj: I've seen occasional bugs but it was very actively developed for several months

0:13 tomoj: I'm not thinking of bugs but, like, fundamental limitations or things that are just too hard right now

0:13 I just feel like I will be amazed if my picture of what it does is correct and it works great

0:18 https://gist.github.com/3ca5df25e8829660eadc hmm

0:21 amalloy: tomoj: i love the classy "nil 2" in your jark -h

0:23 tomoj: seems like stuff works though, just usage string is wonky I guess

0:49 archaic: i just finished reading joy of clojure (first book on lisp i've read).. what book next, any advice? im deciding between on lisp, the reasoned schemer, sicp or another clojure book maybe?

0:49 amalloy: archaic: i haven't read reasoned-schemer, but the other two are excellent

0:50 though i thought RS was nth in a series and you'd want to start with little schemer or something

0:51 hiredman: write some code, read some code

0:52 alandipert: archaic: have you seen the clojure bookshelf? rich's amazon list

0:53 archaic: nope, looking for it now

0:53 alandipert: archaic: http://www.amazon.com/Clojure-Bookshelf/lm/R3LG3ZBZS4GCTH

1:30 sploop: has anybody in here dorked around with gcj and clojure?

1:30 hiredman: don't

1:31 gcj is bad

1:31 sploop: yeah, i'm getting the sense that it's not going to work out from the groups

1:31 amalloy: (inc hiredman)

1:31 lazybot: ⟹ 5

1:31 sploop: google groups

1:31 i means

1:32 trying to avoid the vm startup cost for a smallish utility that's probably going to be run from the command-line or part of a script. looked at nailgun, but it's less than desirable for what i'm doing.

1:39 danke

1:54 mikera: @sploop - JVMs are never going to be quick at starting up for short processes. But you might want to consider keeping a long running JVM or REPL instance and either a) running your script itself from the REPL or b) triggering the Clojure part of your code from the rest of script (e.g. a quick message piped to localhost:somerandomport)

1:57 Raynes: mikera: He is gone. Has been for neigh on 30 minutes now.

2:02 mikera: mmmm my IRC client clearly needs message timestamps :-)

3:28 todun: Trying to filter string of certain characters that are not in the range I want. To this end I do this: http://pastebin.com/TVXWcDUd , is this the right approach?

3:29 Blkt: good morning everyone

3:43 todun: so in my previous question, an example will be like input = "I am \tab an \tab example" will return "I am an example"

3:43 another question. is there a way to put a named function within the body of a string?

3:45 for example, (def in-string (char 20) ) ; (print "I am inside a string in-string", when the result will becomes I am inside a string DC4..?

3:46 I try a quote but that just returns the value unevaluated, I want to evaluate my result on printing the string for example. thanks.

3:48 (To clarify: the same way you can put \newline into a string and have it execute is the effect I'm looking for. thanks.)

3:49 thorwil: todun: defn is not lexically scoped, i.e each defn is at the top level, even when written inside another defn

3:49 so it's pretty much useless and considered bad style

3:49 Chousuke: todun: you're treating "text" as if it were mutable

3:50 the first two filters in your function are completely ineffective

3:50 todun: thorwil: Chousuke I have an imperative background that doesn't want to shake.

3:50 Chousuke: since text doesn't change and the result of the filter is ignored

3:50 todun: Chousuke: I suspected.

3:51 Chousuke: besudes, did you really intend (not enter?) :P that returns a boolean false

3:51 what you need is (filter not-linefeed? text)

3:52 todun: oh. so (not= ...) doesn't work?

3:52 Chousuke: but actually the best way to do this sort of filtering is (remove #{\a \b \c} text)

3:53 todun: the second argument to filter must be a function or something that is callable as a function (like a set)

3:53 wait, what, first argument aI mean

3:53 -a

3:53 todun: yes.

3:54 ,(doc filter)

3:54 clojurebot: "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."

3:54 Chousuke: remove is the opposite of filter

3:55 it basically does (filter (complement pred) coll) :P

3:55 todun: Chousuke: exactly what I want.

3:56 the reason I have the last nested function is that I wanted to delete a range of stuff NOT in the range I was interested in.

3:56 Chousuke: it's not a nested function though. As thorwil said defn's are always top-level and so global. :)

3:57 if you want local functions you can use a plain let or letfn for some syntactic sugar

3:57 or just a straight anonymous function

3:57 thorwil: http://clojuredocs.org/clojure_core/1.3.0/clojure.core/letfn

3:57 Chousuke: eg. (filter (fn [x] (not= x something)) coll)

3:58 todun: thorwil: I tried letfn but didn't quite understand it.

3:58 Chousuke: There's the shortcut form too :P lots of options

3:59 todun: thorwil: when you say top-level/global, what does that mean? I didn't imagine there were such in clojure(.ie. global stuff)?

3:59 Chousuke: top-level means not within any other form

3:59 todun: Chousuke: I'm not quite sure how to use remove to handle a range of things I want to remove.

4:00 , (remove #{\newline \tab} "this is

4:00 quite interested\tab don't you think so\tab?")

4:00 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading string>

4:01 Chousuke: ,(remove #(>= 1 % 5) [1 3 4 8 2 7 5])

4:01 clojurebot: (1 3 4 8 2 ...)

4:01 todun: , (remove #{\newline \tab} "this is \newlinequite interested\tab don't you think so\tab?")

4:01 clojurebot: (\t \h \i \s \space ...)

4:01 Chousuke: wait, hm

4:01 durr

4:01 todun: I gave it a string, I want the string back.

4:01 Chousuke: ,(remove #(<= 1 % 5) [1 3 4 8 2 7 5])

4:01 clojurebot: (8 7)

4:01 todun: so I try this:

4:02 ,(str apply (remove #{\newline \tab} "this is\newlinequite interested\tab don't you think so\tab?"))

4:02 clojurebot: "clojure.core$apply@c9153eclojure.lang.LazySeq@767a87e8"

4:02 Chousuke: I guess I should've upped the lower bound :P

4:02 you mean apply str :P

4:03 todun: Chousuke: but that bound will have to do something like the "nested" correct? function I had.

4:03 check a range of chars

4:03 ,(apply str (remove #{\newline \tab} "this is\newlinequite interested\tab don't you think so\tab?"))

4:03 clojurebot: "this isewlinequite interestedab don't you think soab?"

4:03 thorwil: todun: for def and defn and defmacro that use def internally, there is a single scope per namespace, no nesting

4:04 Chousuke: todun: oh, right, within strings the escapes are different

4:04 because of java

4:04 so a newline is just \n

4:04 todun: ha. I see.

4:04 ejackson: morning folks

4:04 Chousuke: and tab is \t

4:04 todun: Chousuke: ideally, I would just like to define it using the (char 80) etc

4:04 Chousuke: which explains the funky result

4:04 todun: oh ok.

4:05 Chousuke: you can use octal codes for characters I think but I don't remember the syntax

4:06 or maybe it was just unicode. It's been a long time since I needed anything beyond the basics :P

4:06 todun: uhm ok.

4:07 , ( apply str (filter (fn [x] (not= x (char 10))) "this is\nquite interested\tab don't you think so\t?") )

4:07 clojurebot: "this isquite interested\tab don't you think so\t?"

4:07 Chousuke: todun: anyway, for the range predicate you can use a higher-order function

4:07 todun: how so?

4:08 Chousuke: eg, (defn within-range [low high] (fn [char] (<= low (int char) high))) (filter (within-range 5 10) somechars)

4:09 amalloy: ,\012

4:09 ,\u000a

4:09 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unsupported character: \012>

4:09 amalloy: hm

4:09 clojurebot: \newline

4:10 Chousuke: todun: if you don't need a global function you can make within-range local with letfn

4:10 ,(letfn [(test [x] (+ 5 x))] (test 6))

4:10 clojurebot: 11

4:11 todun: is letfn like let in that the scope is limited?

4:11 Chousuke: letfn is just syntactic sugar for let, so yes

4:11 hiredman: *cough*

4:11 Chousuke: at least iirc :P

4:11 but whatever, close enough

4:12 hiredman: ,(letfn [(foo [] (bar 1)) (bar [x] (inc x))] (foo))

4:12 clojurebot: 2

4:12 amalloy: yes, it is conceptually sugar for let but realistically is a little more powerful

4:12 todun: uhm ok.

4:12 Chousuke: I guess the details aren't that important

4:13 hiredman: ,(let [foo (fn [] (bar 1)) bar (fn [x] (inc x))] (foo))

4:13 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: bar in this context, compiling:(NO_SOURCE_PATH:0)>

4:14 todun: ,\012

4:14 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unsupported character: \012>

4:14 todun: ,\u00a

4:14 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Invalid unicode character: \u00a>

4:14 Chousuke: 3 0s neede I guess

4:15 amalloy: Chousuke: 4 digits, anyway

4:15 todun: ,\u000a

4:15 clojurebot: \newline

4:15 amalloy: ah, it's \oNNN: ##'\o012

4:15 lazybot: ⇒ \newline

4:17 todun: I'm guessing this is unicode

4:18 amalloy: \u is

4:18 octal escapes only go as high as 255

4:18 &\o377

4:18 lazybot: ⇒ \ÿ

4:18 amalloy: &\o477

4:18 lazybot: java.lang.Exception: Octal escape sequence must be in range [0, 377].

4:19 todun: ,\o012

4:19 clojurebot: \newline

4:19 todun: amalloy: ok.

4:20 chouser: in my situation though I want those three functions to be the basis of the filter. can I do like a cond on three predicates like I hoped and still filter the same text?

4:20 ^Chousuke

4:21 chouser: I apologize for bothering you.

4:22 Chousuke: todun: you can combine the predicates. I think 1.3 has some new function for that but I forget what it's called

4:22 amalloy: ,(doc any-pred) ; i think?

4:22 clojurebot: Titim gan éirí ort.

4:22 Chousuke: todun: welcome to functional programming. here we use composition :)

4:22 amalloy: but you don't really need it. you can just filter three times

4:23 Chousuke: that too but it's handy.

4:23 amalloy: Chousuke: i'm definitely in favor of the predicate combinators

4:23 but (->> coll (filter pred1) (filter pred2)) is simple enough

4:23 Chousuke: I guess

4:23 though now you need to explain ->> :P

4:23 I guess macroexpand will do

4:23 amalloy: indeed

4:24 Chousuke: ,(macroexpand '(->> coll (filter pred1) (filter pred2))) ; see, it's magic

4:24 clojurebot: (filter pred2 (clojure.core/->> coll (filter pred1)))

4:24 todun: Chousuke: thanks for the welcome.

4:24 amalloy: but that's what I tried to do earlier.

4:24 http://pastebin.com/TVXWcDUd

4:24 amalloy: yeah, but it's not what you actually did

4:24 which Chousuke explained, iirc

4:25 Chousuke: todun: you did it without the ->> macro which transform the "chain" into (filter pred2 (filter pred1 coll))

4:25 +s

4:26 todun: woah. that's way over my pay grade.

4:26 Chousuke: todun: Clojure in particular offers lots of ways to do things and until you get used to things you will be confusd :P

4:26 ... I'm typoing a lot today.

4:26 todun: this is my 1 week clojure anniversary and I'm definitely confused.

4:26 np

4:26 Chousuke: yeah, 1 week isn't quite going to cut it. :)

4:27 todun: Chousuke: your alternative does not need -->, how can I go about doing this?

4:27 amalloy: i love that clojure lets you write things in whatever order you want

4:27 Chousuke: but you'll get it eventually. The most important thing is to try to drop the assumptions you have from imperative programming

4:28 if you do something to an object in clojure, most of the time the state of the object itself does not change

4:28 that's the first hurdle.

4:28 todun: ok

4:28 Chousuke: you need to capture the result of the operation and operate further on that

4:28 todun: ok.

4:29 Chousuke: there are of course exceptions (interop and, well, stateful code using the reference types) but that comes later

4:30 todun: can't wait :P

4:30 Chousuke: you can get far with just immutable things :P

4:30 todun: but the how eludes me.

4:31 Chousuke: you can use let to bind the result of a computation to a local identifier

4:31 or you can just chain things together

4:32 eg. (op-final (op2 somearg (op1 somedata))). read from right to left

4:32 todun: I'm actually trying that on your example now...let me run it by you to see if I'm approaching this correctly...

4:34 Chousuke: there are various macros and other things that help you to express such chaining more succinctly but it's still important to understand what ultimately happens

4:34 todun: yes. that's why I'm avoiding them for now. they don't help me lear squat..yet.

4:34 *learn

4:35 Chousuke: the repl and macroexpand are your friends

4:35 if you don't know what something does just try it a few times in the repl with some simple input and see what happens

4:36 since things are immutable the chances that you would screw up the state of your program are effectively nil

4:37 amalloy: yeah, good point. the character-filtering function you were trying to write was too complicated for you to comprehend all at once, todun - you might have more success if you broke it up into a number of independent pieces in a repl

4:38 todun: Chousuke: this is what I came up with when I tried composition http://pastebin.com/CAYXc1HZ

4:38 Chousuke: it helps to have a good IDE (or emacs, with SLIME) that lets you load code in the repl from a source file

4:38 todun: again, you're not giving filter functions as arguments

4:38 amalloy: todun: getting closer!

4:39 but yes, filter needs functions, not just snippets of code

4:39 todun: Chousuke: how so.

4:39 amalloy: &(= 1 2)

4:39 lazybot: ⇒ false

4:39 todun: I thought that (= ...) was a function?

4:39 amalloy: &(fn [c] (= c 2))

4:39 lazybot: ⇒ #<sandbox12207$eval14451$fn__14452 sandbox12207$eval14451$fn__14452@1d72a6c>

4:39 Chousuke: it's a function call

4:39 = is the function

4:39 todun: ha. I see.

4:39 Chousuke: that you're calling

4:40 you can wrap simple expressions with # to create a quick anonymous function. within that expression you can use % (%1), %2, %3 etc. to refer to arguments to the function

4:41 eg. #(not= % 5) is a quick anonymous function that compares its first argument to 5

4:41 it's just shorthand for (fn [x] (...)) which you can use when you need more than a single expression, or if you need to nest things

4:42 * ejackson just saw clojure.browser.repl in brenton ashworth's vid for the first time. YOWZER ! (thanks fogus).

4:43 Chousuke: ,(filter #(not= \a %) "testa") for example

4:43 clojurebot: (\t \e \s \t)

4:43 todun: my new try: http://pastebin.com/ySw7Rpm2

4:44 Chousuke: what's that pol a-char thing?

4:45 todun: oops. sorry. my ide doesn't let me have int

4:45 haha. that is int

4:45 Chousuke: you want just (filter not-enter? (filter ...))

4:46 the first expression you give as an argument to filter *must* evaluate to a function of one argument

4:46 which not-enter? is

4:47 todun: uhm..

4:47 Chousuke: and the second argument is a sequence you want to filter

4:48 in this case, the return value from the previous filter

4:48 or inner, to be precise

4:48 strings are treatable as sequences of characters in clojure

4:49 so the innermost filter works with that

4:49 todun: ok.

4:51 Chousuke: also move the defns outside the remove-characters definition. as it is, they're just distracting

4:52 todun: ok. but they'll work inside it though, right?

4:52 Chousuke: yes, because they're global definitions

4:52 when you get the filtering working you can add them to the letfn form

4:52 but let's take it one step at a time :p

4:52 todun: ok.

4:54 but if I want just (filter not-enter? (filter ...))

4:55 how does not-enter? know what its args are?

4:55 Chousuke: filter calls it with one arg

4:55 amalloy: filter calls it. but that's later; in the current scope you're passing not-enter? without calling it

4:56 Chousuke: you're in effect passing a function as an argument to another function

4:56 another thing that sounds outlandish if you've never used a language with first-class functions :P

4:57 amalloy: because functions are first-class objects, just like other data types. consider the array in java {1, 2, 3}. when you pass it around as an array, how does it know what index you need? it doesn't: it's all of them at once until someone else indexes into it

4:57 Chousuke: but in clojure, functions are values just like 1, "foo", or 'bar :P

4:57 todun: so something liek this http://pastebin.com/sDqNNJBV ?

4:57 *like

4:57 Chousuke: yes, exactly

4:58 amalloy: todun: looks like that should work

4:58 Chousuke: that gives you a character sequence as an answer

4:58 try it in the repl

4:58 todun: yeah. I have to do the (apply str...)

4:59 haha. I get nil

4:59 sigh.

5:00 amalloy: todun: you might want to drop the not, in in-range

5:01 todun: but I want things not in that range.

5:01 how can I manage this if I remove not ?

5:01 Chousuke: todun: try the function separately on input to see if it works

5:01 ie. do just (filter not-correct? text)

5:02 or even just (in-range? somechar 32 126)

5:03 todun: ok.

5:03 now I get only the tabs showing.

5:03 amalloy: todun: are you trying to *remove* characters between 32 and 128, or keep them?

5:03 todun: keep them.

5:04 also key 10 & 13

5:04 not sure how to convert the ascii to unicide

5:04 *unicode

5:05 amalloy: so you want to throw away all characters except \n, \t, and whatever's between 32-128? in that case you don't want three filters

5:06 todun: yes

5:06 oh. why so?

5:06 amalloy: well, consider how the not-enter? filter will work. it will throw away anything but \n, right?

5:06 so once you've done that, how will you "get back" the ones from 32-128?

5:07 Chousuke: shouldn't filter keep everything that's not-enter?

5:07 raek: todun: you can use 'int' and 'char' to convert from character to unicode code point number and vice versa

5:08 todun: unicode code point numbers 0 through 127 are the same as ASCII

5:08 todun: raek: but I want to see the actual unicode so I can put it in a string literal

5:08 amalloy: that makes sense.

5:09 Chousuke: actually shouldn't not-correct get rid of linefeeds newlines too?

5:09 todun: amalloy: what if I do not-correct? first

5:09 ?

5:09 Chousuke: not-correct is done first

5:09 todun: Chousuke: I want to actually keep newlines and returns.

5:09 amalloy: doesn't matter what order you do; three filters won't work

5:09 Chousuke: the innermost filter executes first

5:09 todun: yes yes. because it's the deepest in the filtering.

5:10 Chousuke: oh... then you need to include the conditions within not-correct

5:10 amalloy: i'm trying to explain why in terms of boolean logic but i can't get it to make sense

5:10 todun: raek: I want the unicode code so when I put it into the string like so "\unicode", it will be executed by print or soemthing

5:10 *something

5:10 amalloy: so instead, https://gist.github.com/1297800

5:10 todun: amalloy: ok.

5:11 Chousuke: amalloy: because not-correct returns false for newlines and linefeeds, they are already removed before the other filters are even executed

5:11 amalloy: Chousuke, todun: the amount of "not" going on in his code confuses all three of us

5:11 raek: U+03BB is the lowercase lambda. as a string: "\u03BB", as a char: \u03BB, as code point number: 955

5:11 Chousuke: amalloy: yeah

5:12 todun: try to avoid nots in code, it clearly confuses things :P

5:12 if you want to keep things, use filter with a positive predicate, and for removing things, use remove with a positive predicate :P

5:12 amalloy: well. don't write (not (and (not a) (not b) (not c))) when you could write (or a b c), anyway

5:12 raek: todun: what do you mean? do you want to escape it? with what convention?

5:12 todun: also, how do I use (str apply...) it seems to be giving me an object reference whenever I sue it.

5:13 amalloy: Chousuke sorry for the confusion :(

5:14 Chousuke: todun: you want to apply the str function, not stringify the apply function :)

5:14 todun: raek: so "I want ascii char 5 here so I will use unicode here like so \unicode5...so that when I call print on this string, it does whatever \unicode5 is"

5:14 raek: my interest is to write a test. henve my need for a string

5:14 *hence

5:14 Chousuke: so (apply str....) ?

5:15 Chousuke: yeah

5:15 todun: amalloy: the boolean logic makes more sense. thanks.

5:15 Chousuke: ok. let me try that.

5:15 raek: todun: if you want a string with unicode character #5 in it, just use the \uXXXX syntax:

5:15 Chousuke: str takes n arguments, you have a sequence of characters you want to give it as arguments; apply allows you to fit the function to the sequence

5:15 raek: ,"\u0005"

5:15 clojurebot: ""

5:15 Chousuke: so (apply str charsequence)

5:16 raek: ,(str (char 5))

5:16 clojurebot: ""

5:16 Chousuke: (apply str [(char 5)])

5:16 ,(apply str [(char 5)])

5:16 clojurebot: ""

5:16 todun: raek: so in general I use the ascii hex number at the end?

5:16 Chousuke: ok thanks.

5:17 claj_: I'm in the latest clojurescript from git and on windows. When I've installed the jars, closure etc acc. to instructions, I got a script/repl.bat

5:17 When I do (require '[cljs.repl :as repl]) it says nil (=good).

5:18 When I do (require '[cljs.repl.rhino :as rhino]) it says ClassNotFoundException org.mozilla.javascript.Context java.net.URLClassLoader$1.run (:-1) (=bad)

5:18 raek: todun: yes. in \uXXXX, XXXX is the unicode code point in hex. for ascii letter YY in hex, you'd write \u00YY

5:19 todun: raek: thanks so much. googling was confusing me more on this point.

5:28 claj_: Ans to self: download rhino from http://www.mozilla.org/rhino/download.html, put js.jar in /lib folder, restart repl, good to go.

5:31 raek: claj_: which jvm are you using?

5:32 rhino is included in sun's/oracle's jvm

5:54 todun: any advice on where to begin when I want to do concurrency with clojure? thanks.

6:05 zilti: todun: If you like screencasts this might be for you: http://vimeo.com/8672404

6:06 todun: zilti:thanks. screen-casts, allot(also elementary) sample-code, etc, whatever you know that is interesting to a concurrency and clojure newbie.

6:06 ^zilti thanks.

6:07 archaic: todun look at richs ant demo

6:07 chrido: todun: another good screencast http://blip.tv/clojure/david-liebke-from-concurrency-to-parallelism-4663526

6:08 todun: and of course http://blip.tv/clojure/clojure-concurrency-819147

6:08 todun: archaic: ok. thanks.

6:08 chrido: thanks.

6:40 kzar: Dumb question, but I'm still getting the hang of macros. Does this look right of a is-not macro? (defmacro is-not [& args] `(apply (comp not is) args))

6:41 claj_: raek: I'm using JRE from Oracle/sun 1.6.0_23something, Server VM build 19 something. Should the js.jar be included by default?

6:41 It works like a charm now, anyway.

6:50 kzar: I think this one is good for macro-learning: http://www.learningclojure.com/2010/09/clojure-macro-tutorial-part-i-getting.html

6:51 I could not get your macro going (test them with macroexpand and macroexpand-1 to see the resulting sexpression generated by the macro)

6:51 but maybe my bad success was because I had not the correct name-space enabled.

6:59 kzar: claj_: Think I got it http://paste.lisp.org/display/125389

7:00 claj_: Thanks for the link

7:00 claj_: (I cheated, did (clojure.repl/source is) to see how it worked and used that to make is-not.)

7:09 claj_: kzar: great! I always forget the reader-macros (`~) but the concept really ain't that hard. The results can be unexpected though.

7:37 zilti: I'm trying to use "clojure-jack-in", but then I get the message "Process swank exited abnormally with code 1. That's not a task. Use "lein help" to list all tasks." What am I doing wrong?

7:39 archaic: hmm only time i see that error is when i try clojure-jack-in and i already have a swank instance running

7:40 zilti: If I try "lein swank" on the command line it also says "That's not a task. Use "lein help" to list all tasks"

7:41 tdrgabi: zilti: maybe an old lein?

7:42 zilti: tdrgabi: Leiningen 1.6.1

7:44 tdrgabi: zilti: do you have swank-clojure installed?

7:46 zilti: tdrgabi: Yes

7:46 I have it both in the project.clj as :build-dependencies and using "lein plugin install swank-clojure 1.3.3"

7:47 tdrgabi: can you run this: ~/.lein/bin/swank-clojure ?

7:48 zilti: "Connection opened on null port 4005."

7:48 clgv: zilti: It has to be :dev-dependencies not "build"

7:49 zilti: Sorry, I meant :dev-dependencies, mistyped here

7:49 tdrgabi: does lein help show swank as one of the tasks?

7:50 zilti: no

7:53 archaic: you dont need swank-clojure anywhere in a project.clj file using clojure-jack-in from emacs.. can you eval (apropos "clojure-jack-in") in emacs *scratch*?

7:54 zilti: Command: (not documented)

7:55 You know, clojure-jack-in "works" in that it just displays that it's starting a swank server.

7:55 and then in the *swank* buffer there's that error message

7:56 archaic: hmmm rm -rf ~/.m2 ?

7:58 zilti: doesn't help...

8:00 archaic: eval (list-processes) in emacs is swank there?

8:01 zilti: is empty.

8:06 Ok have to go now. Bye

10:28 DappD: ?

10:38 pyr: ,(str (format "%c" \\))

10:38 clojurebot: "\\"

10:38 pyr: is this right ?

10:39 ,(str (format "%c" \a))

10:39 clojurebot: "a"

10:39 pyr: i would have expected the first form to yield "\"

10:39 TimMc: pyr: It is escaping the output for printing.

10:40 pyr: 'k

10:40 TimMc: ,(println (format "%c" \\))

10:40 clojurebot: \

10:40 pyr: to keep homoiconic then, makes sense

10:40 TimMc: ,(count (format "%c" \\))

10:40 clojurebot: 1

10:40 TimMc: ,(format "%c" \newline)

10:40 clojurebot: "\n"

10:40 TimMc: pyr: Also, no need for str here.

10:41 pyr: yep

10:41 bhenry1: is there anyone who can help me with jdbc for sybase's advantage database server?

10:41 i have sybase's adsjdbc.jar, but can't make sense of it

10:53 ljos: Hi - Is there a way to make macros capture variables in the input?

10:56 S11001001: ljos: yes, for several meanings of that. What are you doing?

10:57 ljos: S11001001, I've tried to do this but keep getting a fail: (defmacro test [& code] (let [i 1] ~code)) and afterwards running (test println i) .

10:58 S11001001: change i to ~'i

10:58 ljos: oh..

10:59 S11001001: hmm, I hear that do is special, let's see

10:59 ,(do (defmacro myenv [] (keys &env)) (let [i 1] (myenv)))

10:59 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

10:59 S11001001: hmm

11:00 ljos: That doesn\t work.

11:00 S11001001: okay I also suggest (assert (not (contains? &env 'i))) in the macro so you can avoid accidentally shadowing a local i

11:00 ljos: oh.. forgot the '

11:00 S11001001: you're also missing ` before (let

11:00 ljos: I want to shadow.

11:00 S11001001: you want to bind, not necessarily shadow

11:01 ljos: Ah.

11:01 S11001001: it's harder for a user to spot bugs caused by anaphora, but you can do so easily in the macro, and they can work around it by not using i for their own variable

11:01 raek: ljos: you also need ~@code instead of ~code

11:02 S11001001: doesn't work if you need (test ...) forms to live inside (test ...) forms, though

11:02 ljos: I'm also wondering, is there a way to bind into an eval?

11:02 raek: (test a b c) would otherwise become (let [i 1] (a b c)) and not (let [i 1] a b c)

11:02 ljos: you pretty much have to generate an enclosing let form

11:03 the way the clojure compiler is implemented the expression eval evaluates cannot access locals accessible from the eval call

11:04 ljos: raek: But (let [i 0] (eval '(print i))) doesn't work..

11:04 Ah.. so that was not the answer to the first question.

11:04 second*

11:05 raek: ljos: I was thinking about (let [expr '(print i)] (eval `(let [~'i 0] ~expr)))

11:06 ljos: Oh.. yeah. Thanks to both of you!

11:07 raek: if you parameterize the value i should have, you might also want to do this: (let [expr '(print i), i-value (reverse [1 2 3])] (eval `(let [~'i (quote ~i-value)] ~expr)))

11:08 this will become (let [i (quote (3 2 1))] (print i)), and not (let [i (3 2 1)] (print i))

11:09 you have to be cautious with what's code and what's not

11:28 ljos: That works out great, raek. Now I don't have to start over with the way I was thinking with my code :D

11:33 TimMc: bhenry: You'll probably have to be more specific.

11:33 bhenry: i can't find any examples

11:33 TimMc: the examples i've found don't match up with the classes in the jars i was provided

12:02 F3d: Newbie here... Is it possible to use pattern matching (matchure?) for processing/transforming XMLs ?

12:09 Any opinion on matchure vs. core.match ?

12:11 TimMc: I don't know how to pronounce the former, so I'd probably use the latter.

12:13 georgek: hi, as someone who uses Windows and Emacs, is the emacs-starter-kit the current recommended way to get started? And is there a tutorial to look at to get started with that and lein?

12:13 dnolen: F3d: I develop both. Try both and see which works better for you. core.match is much more traditional on it's approach to matching syntax and it does provide as much sugar as matchure.

12:15 todun: hi all.

12:15 dnolen: F3d: I meant I'd try both. I develop core.match

12:16 todun: if I want to get into clojure macros as a beginner, any nice resources out there? screen-casts, good/simple tutorials etc are welcome. thanks.

12:16 dnolen: and I meant core.match provides less sugar.

12:17 TimMc: I was gonna say...

12:17 dnolen: Who *does* develop matchure?

12:19 chewbranca: georgek: I found this to be useful when I was setting up emacs: http://dev.clojure.org/display/doc/Getting+Started+with+Emacs

12:21 georgek: thanks chewbranca, yes I'm looking at that now; I also just found this, http://underaboddhitree.blogspot.com/2011/10/using-emacs-and-leiningen-on-windows.html, published yesterday

12:22 dnolen: F3d: one advantage over matchure, core.match can deal w/ the presence of recur.

12:31 chewbranca: http://aichallenge.org/starter_packages.php

12:32 clojure is mentioned this time, no starter package though (yet?)

12:32 looks fun, ant colony domination

13:03 srid-work: http://stackoverflow.com/questions/7812635/

13:12 llasram`: chewbranca: Do you know, is there any sort of published timeline for the current (upcoming?) AI challenge? I don't see any dates or such on the site

13:15 jodaro: wow

13:15 i'm really happy with how easy some of my refactoring has been

13:15 just an observation

13:15 and now

13:16 fire drill time!

13:16 rad

13:16 chewbranca: llasram`: yeah I was looking around for a timeline as well but couldn't find one, I did see that they mentioned its all in beta right now, so I imagine a decent bit of time

13:16 jodaro: so much for productivity

13:16 bbommarito: Quick question: Is there any known issues with Clojure on OpenJDK?

13:17 technomancy: bbommarito: no, works fine

13:17 bbommarito: technomancy: Great, thanks. Been wanting to play with Clojure, but really don't want to install Oracle's java.

13:17 technomancy: clojurescript didn't work for a while, but ISTR that's been fixed

13:18 dnolen: technomancy: it has.

13:20 technomancy: cool

13:23 srid-work: is anyone using need to replace use/require in their clojure projects? https://github.com/stuartsierra/need

13:25 dnolen: srid-work: I would not use any Clojure library that hasn't had updates since April 2010

13:26 srid-work: its more of a tiny macro (that can be included in project tree) than a library :)

13:27 i asked this in SO: seperate use and require forms seem to be unnecessary.

13:27 .. and why they were created in first place (as opposed to designing a syntax like that of `need`)?

13:27 technomancy: srid-work: I'm a big fan of nstools for tidying up ns clauses

13:27 dnolen: srid-work: bringing a dependency for ns declarations seems gratuitous. better to lead the conversation on how ns form can be improved.

13:27 srid-work: I think it can chalked up to "hey, we all make mistakes"

13:28 technomancy: srid-work: use and require are definitely not ideal or the last word in loading syntax

13:28 they are just a whole ton better than load-file =)

13:28 DerGuteMoritz: hey guys, is there a specific reason to use a foo.core namespace in libraries? i.e. why not put the code directly into the foo namespace?

13:29 dnolen: DerGuteMoritz: there isn't any reason to foo.core ns. I've been reprimanded in the past for doing so in my libraries by users :)

13:29 hiredman: ~single segment

13:29 clojurebot: amespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

13:29 srid-work: dnolen: a human mistake? that explains it. :-) I remember seeing posts in clojure mailing list (mostly from stuart) proposing to improve the ns form.

13:29 DerGuteMoritz: dnolen: reprimated for using foo.core?

13:29 dnolen: DerGuteMoritz: oh yeah, single segment is bad, sorry thought you were referring to foo.bar.core instead of foo.bar

13:30 srid-work: not sure what the decision was. I assumed that it was rejected .. hence my question (above) about the adoption of `need``

13:30 DerGuteMoritz: single segment?

13:31 technomancy: DerGuteMoritz: (ns foo) rather than (ns foo.core)

13:31 dnolen: srid-work: no, I think the ideas proposed weren't much of an improvement. For what it's worth, ClojureScript ns story is way better since it only support two forms. :use :only, :require, :require :as

13:31 DerGuteMoritz: so putting definitions into `foo' is not good and `foo.core' should be used instead while `foo.bar' is ok?

13:31 technomancy: DerGuteMoritz: that puts it in the default java package and makes interop nasty

13:31 DerGuteMoritz: ah, so that's the reason

13:31 technomancy: DerGuteMoritz: if you have a descriptive two-segment name, there's no reason to use core

13:31 .core just means "I can't think of a better two-segment name to use to avoid a single-segment name" =)

13:32 DerGuteMoritz: hm, well I only have a very small library that doesn't make sense to split up further

13:32 ok then hehe

13:32 maye it should be put in http://dev.clojure.org/display/design/Library+Coding+Standards?

13:32 srid-work: dnolen replacing use/require with a single form (need) is not an improvement? is the clojurescript ns story better because it lacks a :import (third form)?

13:32 DerGuteMoritz: if anyone here is registered for editing the wiki

13:33 dnolen: srid-work: combining into a single form doesn't seem like an improvement to me. I have to examine the need expr to know what's happening.

13:33 DerGuteMoritz: thanks for the information!

13:33 technomancy: srid-work: I think it depends on the scope of the project. it's probably not worth it in small libs, but if you have huge a huge application it may be worth it.

13:33 srid-work: seriously check out nstools though

13:34 it lets you define a standard template to base other ns forms on

13:34 srid-work: technomancy just checked nstools; doesn't seem to unify use/require, does it?

13:35 technomancy: srid-work: no, but it lets you specify all your common requires in one place and refer to it succinctly all around your codebase

13:35 say you know you're going to need clojure.string, and http client, and a json parser in a bunch of namespaces

13:35 you can just add them to foo.base, and then in other nses you can do (ns foo.baz (:like foo.base))

13:37 srid-work: technomancy ok, and if you want to load a special-case library (eg: clojure.java.jdbc), you do that only in the required module but not the common namespace?

13:37 or add clojure.java.jdbc to foo.base as well, not worrying about requiring it in other modules?

13:37 (even though jdbc will be used only in one file)

13:38 technomancy: srid-work: I would keep the base as just all the common stuff

13:38 seancorfield: technomancy: that's nice... i hadn't read about that before... link to nstools?

13:38 technomancy: clojurebot: nstools?

13:38 clojurebot: Pardon?

13:38 srid-work: $g clojure nstools

13:38 seancorfield: (apologies if you posted it and i missed it)

13:38 technomancy: seancorfield: it's totally underappreciated

13:39 clojurebot: nstools is a library to reduce repetition in your ns clauses: http://code.google.com/p/clj-nstools/

13:39 clojurebot: Ok.

13:39 technomancy: seancorfield: there ya go

13:41 seancorfield: thanx... looks like it might not work with clojure 1.3.0? (haven't tried - just saw contrib dependency)

13:41 technomancy: yeah, probably not; it's kind of old

13:42 srid-work: nstools example - http://code.google.com/p/clj-units/source/browse/src/units/si.clj

13:42 technomancy: (you can tell since it's hosted on google code)

13:42 zzzzzing

13:42 seancorfield: maybe konrad and stuart could get together and see if some form of it could be added to clojure.tools.namespace? :)

13:45 technomancy: man. why do people treat the confluence comments section like the edit section? >=(

13:46 I guess that's what you can expect when you prevent people from editing the wiki

13:47 also: why do people think it's a great idea to add a tutorial for the starter kit to the clojure wiki? wtf

13:47 is there anyone around with privileges to delete wiki comments?

13:50 amalloy: technomancy: presumably to punish you for being a terrible tutorial-writer

13:50 technomancy: amalloy: a better explanation than any I've been able to come up with

13:50 pjstadig: i don't buy it

13:51 technomancy: seancorfield: I think c.t.namespace is more about inspecting and investigating namespaces than declaring them.

13:51 amalloy: technomancy: it's because i'm not distracted by having read any of your tutorials - my mind is open to the possibility they might be awful

13:51 technomancy: haha

13:57 never let facts cloud your judgement

14:00 zackmaril: technomancy: just got swank-clojure to work for the first time. It's magical. Just wanted to say thank you

14:00 technomancy: zackmaril: sweeeeeeet

14:01 zackmaril: Mos def. Now it's time to make a robot that sexts.

14:02 Thanks again!

14:08 devn: "Now it's time to make a robot that sexts."

14:08 Why do I feel like someone has said this in this channel before?

14:09 technomancy: devn: because there used to be a sexpbot?

14:10 amalloy: no, there was someone who suggested that as a project on the ML

14:13 devn: hahaha, oh yeah! who was that?

14:13 amalloy: *shrug* probably zackmaril

14:27 F3d: dnolen: Thanks! about core.match (better late than never)

14:38 mefesto: A while ago Meikel Brandmeyer wrote, "memoize done right" in which he created a pluggable caching strategy. Is any of this part of a clojure contrib project? http://kotka.de/blog/2010/03/memoize_done_right.html

14:45 drewr: mefesto: latest incarnation is http://blog.fogus.me/2011/06/20/unk/

14:45 which is really https://github.com/fogus/unk

14:46 srid: does `lein run` support passing arguments to the interpreter. specifically, I want to pass `-Duser.home=$HOME`. "lein help run" doesn't tell if this can be done.

14:46 mefesto: drewr: thanks :)

14:48 technomancy: srid: "lein help run" does list "lein run [--] [ARGS...]"; is that unclear?

14:49 oh, you mean args to the JVM itself?

14:49 srid: yup, and I found the solution from SO .. :jvm-opts in project.clj

14:49 technomancy: right, that's not mentioned in the help there because it's not specific to the run task

14:49 srid: looks like it doesn't support env variables.

14:49 technomancy: right; it's just forg arguments

14:50 *for

14:50 srid: oh, so no shell expansion happens.

14:50 technomancy: if you want environment variables you can use JVM_OPTS

14:50 same effect; it just doesn't live in the project

14:51 tolstoy: Also: VAR="whatever" HOME="/path/to/home" lein run

15:11 bbommarito: Now the true challenge, getting Slime and Clojure working in EMacs.

15:12 tolstoy: That really is a challenge, somehow. On the mac, with the recent "brew" version of emacs, most of the clojure stuff compiled with errors or warnings or something.

15:12 paulfryzel: bbommarito: i am new to the clojure community and also to "the emacs way of doing things". i was able to get Emacs 24 setup on OS X Lion + Slime/Swank the other night without much trouble at all

15:12 let me know if you run into any roadblocks, maybe i could offer some help

15:12 tolstoy: Well, there you go. ;)

15:13 paulfryzel: i used http://emacsformacosx.com/builds → Emacs-pretest-24.0.90-universal-10.6.7.dmg

15:17 tolstoy: Somehow my stock elpa was messed up, then I tried adding a repo for "marigold" (or whatever it is) and that was down. Gave up on Emacs until I've got more time.

15:17 A year or two ago it was a snap.

15:27 bbommarito: tolstoy: Marmelade.

15:27 tolstoy: Yeah, that's it.

15:27 bbommarito: I'm on a Linux box, and use Emacs 24, with el-get, and I would really love to use el-get for this, but my attempt to do that failed.

15:27 tolstoy: What's the best page for defmacro escape characters (given they're not the same as CLs)?

15:29 Hm. Maybe cheatsheet.

15:29 llasram`: http://clojure.org/reader, the sub-section on "syntax-quote"?

15:32 tolstoy: llasram`: thanks!

15:32 When you use, say a# in a let clause at the beginning of a macro, do you just refer to it as a# throughout the macro? a# isn't generated anew each time?

15:32 babilen: Hi all ... I seem to remember that I read a discussion of when to use () and when [] in (ns ...) somewhere. But I can't seem to find it. Are there coding guidelines, etc somewhere to be found?

15:33 tolstoy: Guess I can try macro-expand....

15:33 babilen: tolstoy: yes, you would always use a# throughout the macro.

15:34 llasram`: "If a symbol is non-namespace-qualified and ends with '#' [...] [a]ll references to that symbol within a syntax-quoted expression resolve to the same generated symbol." - http://clojure.org/reader

15:35 The official documentation knows all and sees all, despite being in bad need of some CSS lovin' :-)

15:35 drewr: "within a syntax-quoted expression" being the operative phrase

15:36 if you referred to it multiple times in a let outside of the syntax-quote it would be different each time

15:37 hiredman: I don't believe # does anything outside of syntax quote

15:37 llasram`: Well, I don't think it has any meaning outside of syntax-quote, but yeah -- different in different syntax-quoted expressions

15:37 ,(foo# foo#)

15:37 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo# in this context, compiling:(NO_SOURCE_PATH:0)>

15:37 llasram`: ,(`foo# `foo#)

15:37 clojurebot: nil

15:37 hiredman: ,(macroexpand '(let [x# 1 x# 2] x#))

15:37 clojurebot: (let* [x# 1 x# 2] x#)

15:37 llasram`: (list `foo# `foo#)

15:38 ,(list `foo# `foo#)

15:38 clojurebot: (foo__106__auto__ foo__107__auto__)

15:38 llasram`: There we go

15:38 I apparently need to take clojure bot off to a quite channel somewhere and practice my act a bit

15:40 drewr: hiredman: ah yes, you're right

15:41 don't know why I was thinking that

15:41 hiredman: well, it would kind of make sense, except syntax quote is insane

15:42 llasram`: hiredman: How so?

15:42 (insane, that is)

15:42 babilen: So are there coding guidelines for (), [] usage in (ns ...) ? I stumbled over a short discussion once but can't find it again.

15:43 hiredman: llasram`: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L762

15:43 TimMc: ~8thlight

15:43 clojurebot: I don't understand.

15:43 TimMc: bah

15:43 babilen: http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html

15:43 drewr: babilen: use [] except for () in :import

15:44 llasram`: hiredman: Ohhh, the reader impl for syntax-quote is insane? I can totally believe that

15:44 drewr: don't know if that's official but my team uses it to great success

15:44 hiredman: http://www.thelastcitadel.com/images/syntax.png is a rough diagram I made while trying to work out the flow control for syntax quote

15:45 babilen: TimMc: That looks like a good article, but isn't what I am looking for. But thank you very much.

15:45 drewr: Are there specific reasons?

15:45 llasram`: hiredman: wah! ok, insane :-)

15:46 hiredman: () lines up classes and packages well for imports

15:46 drewr: babilen: what hiredman said

15:46 hiredman: [] lines up :only clauses well for uses

15:46 babilen: "lines up" ?

15:47 hiredman: the way it indents

15:47 drewr: in clojure-mode

15:47 babilen: aah!

15:47 drewr: I don't use clojure-mode but vimclojure -- Guess it might be the same though.

15:48 drewr: unsure

15:48 babilen: But thank you -- I guess any standard is better than no standard. Are there other best-of-breed coding guidelines available?

15:48 drewr: I'll test it.

15:48 llasram`: My understanding of the Clojure convention was to use lists when there is intended to be an implication of code-execution, and vectors when there isn't

15:48 So (ns (:require [..]) (:use [..] (:import [..])))

15:49 (well, with the parens in the right places)

15:49 Is there some reason not to use vectors with imports?

15:50 hiredman: they don't indent correctly

15:50 the indentation you want for :import is like indentation for function calls

15:50 e.g. arguments aligned vertically to the right of the operator

15:51 or classes aligned vertically to the right of the package

15:51 llasram`: Ohh, I see. I think for me the code ex vs not trumps me vs normalized auto-indentation

15:52 clojure-mode has some backtracking indent stuff... I haven't looked into it closely, but maybe it could be taught that :import vectors indent like function application?

15:53 hiredman: code ex?

15:53 anyway forget I asked, I don't care

16:03 tolstoy: So… is it not good to remove items from a list you're iterating over in a doseq? I wouldn't even ask, but it seems to work!

16:05 amalloy: tolstoy: whatever it is you think you're doing, you're probably not doing

16:05 TimMc: haha

16:05 tolstoy: Well, I've got an atom which maintains a list, and a thread that runs through it and removes "bad" items once in a while.

16:06 And by remove, I mean (swap! …).

16:06 dnolen: tolstoy: why do that while iterating tho? instead of filter first then swapping the atom?

16:07 tolstoy: dnolen: Cause I didn't think of it? ;)

16:07 hiredman: why are you using an atom?

16:07 tolstoy: Several threads of execution are manipulating it.

16:07 ibdknox: you probably should be doing that in a transaction

16:08 tolstoy: Does deref give you an immutable copy of a list?

16:08 TimMc: tolstoy: The main Clojure data structures are immutable.

16:08 amalloy: tolstoy: every list is immutable

16:08 tolstoy: Basically, I have a bunch of socket-style resources I want to monitor. So it's just not cool immutable data structures.

16:08 TimMc: Lists included.

16:09 tolstoy: Ah, right. (remove fn @whatever) returns a new list. Got it. Knew I shouldn't've asked. :)

16:09 amalloy: atoms and refs simply hold mutable pointers to these immutable lists

16:09 TimMc: tolstoy: But now you know!

16:10 dnolen: tolstoy: I'm not a concurrency expert, but putting mutable things in immutable things is probably never a good idea.

16:10 amalloy: tolstoy: fwiw, that remove is unlikely to be correct

16:10 tolstoy: Heh. Right. Understanding when reading is different than understanding when writing, at least for me. Practice!

16:10 amalloy: you're likely to want (swap! whatever #(remove f %))

16:11 tolstoy: Yep. That makes sense.

16:11 TimMc: dnolen: I've used refs of lists of GUI components.

16:12 Whether you want to call GUI components "mutable" is another question, I suppose. They have setters, but their basic "value" doesn't change.

16:13 dnolen: TimMc: but what advantage is there to putting such things in refs? I'm honestly curious.

16:14 TimMc: I don't remember, come to think of it. :-/

16:16 tolstoy: amalloy: Well, your suggestions just killed my LOC count for the day. :)

16:17 TimMc: dnolen: I think it had something to do with two events possibly occurring concurrently, each of which had a handler that might modify the same part of the GUI. Then again, Swing only has a single thread for events...

16:17 dnolen: amalloy: mutable pointers is a bit of a simplification :) atoms and refs both have policies.

16:18 amalloy: mutable pointers, with magic

16:26 daniel___: hi everyone

16:27 i have a hash-map like this: {"a" 100, "b" 200, "c" 50} the numbers are probabilities and im trying to think of a way to select a value from the map based on this probability

16:29 TimMc: reductions with + across the keys might give you something to walk

16:29 tolstoy: filter?

16:29 clojurebot: filter is not map

16:31 S11001001: vals

16:31 hiredman: (let [m {"a" 100, "b" 200, "c" 50} total (apply + (vals m))] (first (shuffle (for [[k v] m itm (repeat (/ (* v 100) total) k)] itm))))

16:31 ,(let [m {"a" 100, "b" 200, "c" 50} total (apply + (vals m))] (first (shuffle (for [[k v] m itm (repeat (/ (* v 100) total) k)] itm))))

16:31 clojurebot: "b"

16:31 TimMc: daniel___: ##(let [p '{a 100, b 200, c 50}, ks (keys p), cvs (reductions + 0 (vals p))] cvs)

16:31 lazybot: ⇒ (0 100 300 350)

16:31 hiredman: ,(let [m {"a" 100, "b" 200, "c" 50} total (apply + (vals m))] (first (shuffle (for [[k v] m itm (repeat (/ (* v 100) total) k)] itm))))

16:31 clojurebot: "a"

16:31 hiredman: possibly the slowest way to do it

16:32 amalloy: hah. not the most efficient way to do that

16:32 TimMc: daniel___: Never mind, my method also requires sorting...

16:32 joly: for slowest, I was going to recommend picking a random key, incrementing a counter for it, and continuing the process until one counter exceeded the map value

16:33 amalloy: joly: i think hiredman found something slower

16:33 joly: I think you're right

16:34 dnolen: ,(require '[clojure.set :as set)

16:34 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: )>

16:34 daniel___: i dont understand how you can compute these things so quickly :p

16:34 dnolen: ,(require '[clojure.set :as set])

16:34 clojurebot: nil

16:34 dnolen: (set/map-invert {"a" 100 "b" 200 "c" 50})

16:34 ,(set/map-invert {"a" 100 "b" 200 "c" 50})

16:34 clojurebot: {50 "c", 200 "b", 100 "a"}

16:35 hiredman: I have a bit of non-deterministic functionality, I've been trying to write a test for, doing similar things

16:35 TimMc: dnolen: Two probs might be =

16:35 hiredman: also comes up when writing markov chains

16:36 amalloy: yeah, incanter has an actually-efficient way to do this, which i used when writing a markov chainer

16:36 $google clojure incanter roulette wheel

16:36 lazybot: [Overview - Incanter next API documentation] http://liebke.github.com/incanter/

16:36 dnolen: TimMc: ah yeah.

16:36 hiredman: each run is non-deterministic but it trends towards x

16:37 real pain

16:37 amalloy: https://github.com/liebke/incanter/blob/0ab56c4c49d6b2cf4bf601dd4c6f5e481b06f788/modules/incanter-core/src/incanter/distributions.clj#L194

16:37 gfredericks: finger trees could do it in log time, right?

16:39 TimMc: I think the incanter thing is basically what I was working towards.

16:39 Accumulate a probability sum until it passes a random threshold.

16:41 daniel___: working my way through this incanter functions, trying to understand it

16:41 thanks guys

16:48 can someone explain loop [acc i] ?

16:48 Apage43: loop is a let you can recur to.

16:48 if there's no recur inside, it behaves the same as let

16:48 Raynes: That's the most genius explanation I've ever heard.

16:50 raek: (inc Apage43)

16:50 lazybot: ⟹ 1

16:50 jamiltron: This is probably my lack of understanding regarding java coming through, but is there some trick you have to do to qualify records across files?

16:50 daniel___: so (loop [acc 0, i 0] with recur 1 1) will recur with acc=1 and i=1...

16:50 Apage43: yup

16:51 daniel___: ok, thanks Apage43

16:51 Apage43: and of course you can only use (recur) in places where it's what the loop form would return

16:51 jamiltron: So let's say I've defrecord'd a Person in person.clj. Now in core.clj I require person.clj as person - when I try calling (def me (person/Person. "stuff")) I get a "Unable to resolve classname" error.

16:52 Raynes: That's because defrecord creates a class, which you'd need to import.

16:52 If you don't want to do that, defrecord creates a factory function for creating an instance. (->Person slots go here).

16:52 Not sure if those factory functions were in 1.2 though.

16:53 amalloy: Raynes: no

16:53 jamiltron: I'm using 1.3 so that should work.

16:53 Raynes: amalloy: Wow. It took you exactly 4 seconds.

16:54 * amalloy has fast fingers

16:54 Raynes: amalloy: You must have "Raynes: no" bound to a shortcut or something.

16:54 amalloy: Raynes: no

16:54 jamiltron: Haha

16:54 amalloy: sorry misclick

16:54 :P

16:54 Raynes: ;)

16:54 jodaro: no-bot

16:56 daniel___: ,(macroexpand -->)

16:56 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: --> in this context, compiling:(NO_SOURCE_PATH:0)>

16:56 jamiltron: Raynes: Thanks, that factory function is just what I am looking for.

16:56 daniel___: ,(macroexpand ->)

16:56 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/->, compiling:(NO_SOURCE_PATH:0)>

16:56 daniel___: ,(macroexpand --> int double int)

16:57 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: --> in this context, compiling:(NO_SOURCE_PATH:0)>

16:57 daniel___: ,(macroexpand -> int double int)

16:57 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/->, compiling:(NO_SOURCE_PATH:0)>

16:57 Raynes: jamiltron: There is another one, map->Person. It takes a map.

16:57 daniel___: what's the difference between -> and -->

16:57 amalloy: daniel___: someone is going to kill you in a moment. try /msging clojurebot, or asking a real question of humans

16:57 Apage43: isn't it ->> ?

16:57 bhenry: ,(macroexpand (->> :a identity))

16:57 TimMc: daniel___: macroexpand needs a single form

16:57 clojurebot: :a

16:57 jamiltron: Raynes: Huh, interesting.

16:57 daniel___: sorry

16:58 raek: daniel___: "-->" is not something that is defined by Clojure

16:58 daniel___: ,(macroexpand (-> int double int))

16:58 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.core$int cannot be cast to java.lang.Number>

16:58 Apage43: ,(macroexpand (-> 1 inc inc))

16:58 clojurebot: 3

16:58 Apage43: er

16:58 TimMc: daniel___: /query clojurebot

16:58 raek: you need to quote the expression you give to macroexpand

16:58 it's a function

16:58 amalloy: Apage43: you need to quote it, and you probably want macroexpand-all anyway

16:58 bhenry: ,(macroexpand '(->> :a identity))

16:58 clojurebot: (identity :a)

16:58 TimMc: ~macroexpand-all

16:58 clojurebot: excusez-moi

16:59 TimMc: Hmph, thought there was a factoid there.

16:59 amalloy: &(use '[clojure.walk :only [macroexpand-all]])

16:59 lazybot: ⇒ nil

16:59 amalloy: &(macroexpand-all '(->> (range) (filter even?) (take 10)))

16:59 lazybot: ⇒ (take 10 (filter even? (range)))

16:59 raek: -> lets you write (h (g (f x a b) c d) e f) as (-> x (f a b) (g c d) (h e f))

16:59 amalloy: &(macroexpand-all '(-> (range) (filter even?) (take 10)))

16:59 lazybot: ⇒ (take (filter (range) even?) 10)

17:00 TimMc: raek: I think I prefer amalloy's example. :-)

17:00 raek: so the 'h' and its arguments 'e' and 'f' come close together in the code

17:05 daniel___: amalloy, why are they different?

17:05 by what logic does -> put 10 at the end

17:07 gfredericks: everything goes between the take and the 10

17:07 at each step the previous form gets inserted as the second element in the list

17:07 &(macroexpand-all '(-> (a) (b c d e) (f g) (h) (take 10)))

17:07 lazybot: ⇒ (take (h (f (b (a) c d e) g)) 10)

17:07 sritchie: think of each form replacing the commas of the following form: (-> (range) (filter ,,, even?) (take ,,, 10)))

17:08 gfredericks: "second element of the list" <~> "first argument of the function"

17:08 TimMc: daniel___: -> means "thread each result in as the first argument of the next form"

17:08 sritchie: after one expansion, you have: (-> (filter (range) even?) (take ,,, 10)))

17:08 TimMc: daniel___: ->> is the same, but as "last argument"

17:08 sritchie: and after the second expansion: (take (filter (range) even?) 10)

17:09 TimMc: sritchie: You're using ->, which is incorrect for the functions involved...

17:10 amalloy: TimMc: the question was how 10 ends up last

17:10 daniel___: i see TimMc, thanks

17:11 sritchie: TimMc: good point, I just wanted to show the commas

17:11 daniel___: amalloy: i understand now... take is the function and -> passes it as the first argument (before 10)

17:11 TimMc: amalloy: Ah! I see.

17:12 jodaro: Raynes: woop! there's the recently on clojars notification.

17:12 TimMc: daniel___: Bear in mind that -> and ->> don't actually "pass results around" -- they actually rearrange the code to produce the same result.

17:12 Raynes: jodaro: o/

17:12 TimMc: s/result./effect./

17:13 daniel___: TimMc: i understand that, it ends up the same once compiled

17:14 amalloy: me.panzoo/spaghetti sounds awesome if you say it aloud. i have to go look up what it does

17:14 jodaro: Finite State Machine


17:14 Raynes: $google panzoo spaghetti

17:14 lazybot: [jedahu/spaghetti - GitHub] https://github.com/jedahu/spaghetti

17:16 daniel___: ({"'jB" 4530} {"m%g" 5622} {"SOE" 2090} {"X57" 5313} {"3L]" 3459}) im getting this, and it want the whole thing enclosed in one pair of {}

17:17 amalloy: that looks so mutable that it's almost...spaghetti code...*rimshot*

17:17 daniel___: (map #(hash-map % (fitness %)) population) is roughly what my code is to create the hash-map

17:17 amalloy: &(apply merge '({x 1} {y 2}))

17:17 lazybot: ⇒ {y 2, x 1}

17:18 jkkramer: (into {} (map (just identity fitness) population))

17:18 just=juxt

17:19 daniel___: jkkramer, whats just and identity?

17:19 jkkramer: ,((juxt identity inc) 1)

17:19 clojurebot: [1 2]

17:20 jkkramer: ,(identity 1)

17:20 clojurebot: 1

17:20 jkkramer: daniel___: makes sense?

17:21 daniel___: ok, why not just write 1? :/

17:21 mdeboard: lol

17:22 jkkramer: just demonstrating what the function does

17:22 daniel___: wait ,(identity 2)

17:22 jkkramer: the above is equivalent to (into {} (map #(vector % (fitness %)) population)

17:22 daniel___: ,(identity 2)

17:22 clojurebot: 2

17:23 daniel___: ok cheers

17:23 jkkramer: juxt is a little hard to grok, but it's handy

17:23 daniel___: everything clojure is hard to grok

17:23 amalloy: clojurebot: juxt?

17:23 clojurebot: juxt is usually the right answer

17:23 daniel___: at least for now

17:24 amalloy: clojurebot: juxt is a little hard to grok but it's the best thing ever

17:24 clojurebot: 'Sea, mhuise.

17:24 gfredericks: clojurebot: grok is a little hard to juxt but it's the best thing ever

17:24 clojurebot: Alles klar

17:25 daniel___: lol

17:25 What's 'Sea, mhuise?

17:26 gfredericks: if you pointed a gun to my head I'd guess portuguese

17:26 amalloy: gfredericks: no way

17:26 gfredericks: with very low confidence

17:26 amalloy: yes I would

17:26 until I'm better informed

17:26 amalloy: not anymore, now that someone's told you it's wrong

17:27 gfredericks: I guess that's true

17:27 jkkramer: sounds like elfin or some other form of nerdspeak

17:27 gfredericks: dangit now I need to figure out what my second guess would have been

17:27 jodaro: gaelic?

17:27 jkkramer: jodaro: google agrees

17:27 amalloy: $timer 4 0 0 clojurebot: forget grok |is| a little hard to juxt but it's the best thing ever

17:27 lazybot: Timer added.

17:27 daniel___: ok, i think i've got that function working

17:27 jodaro: rad

17:27 daniel___: good time to call it a night

17:28 amalloy: gfredericks: i'm hoping you'll have forgotten in four hours

17:28 gfredericks: amalloy: :-D

17:28 babilen: irish?

17:28 daniel___: ,(repeat (print "nn all ") 5)

17:28 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.NullPointerException>

17:28 daniel___: ,(repeatedly (print "nn all ") 5)

17:28 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.NullPointerException>

17:28 daniel___: damn u

17:28 ,(repeat 5 (print "nn all "))

17:28 clojurebot: nn all

17:29 (nil nil nil nil nil)

17:29 daniel___: ,(repeatedly 5 (print "nn all "))

17:29 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.NullPointerException>

17:29 daniel___: nvm

17:29 babilen: heh

17:29 gfredericks: daniel___: gotta give it a function

17:30 TimMc: daniel___: That worjks out to (let [x (print "nn all ")] (repeat 5 x)) ... and print returns nil

17:30 daniel___: ,(repeat 5 #(print "nn all "))

17:30 clojurebot: (#<sandbox$eval27$fn__28 sandbox$eval27$fn__28@8de117> #<sandbox$eval27$fn__28 sandbox$eval27$fn__28@8de117> #<sandbox$eval27$fn__28 sandbox$eval27$fn__28@8de117> #<sandbox$eval27$fn__28 sandbox$eval27$fn__28@8de117> #<sandbox$eval27$fn__28 sandbox$eval27$fn__28@8de117>)

17:30 daniel___: yeah!

17:30 just what i wanted

17:30 gfredericks: daniel___: I meant for repeatedly

17:30 daniel___: ,(repeatedly #(print "nn all ") 5)

17:30 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: sandbox$eval55$fn__56 cannot be cast to java.lang.Number>

17:30 daniel___: ,(repeatedly 5 #(print "nn all "))

17:30 clojurebot: (nn all nn all nil nn all nil nn all nil nn all nil nil)

17:30 daniel___: got there in the end

17:30 TimMc: daniel___: Please use lazybot or clojurebot in privmsg!

17:31 gfredericks: or get your own repl

17:32 tolstoy: Can't quite make it out from the cheat sheet, but is there a seq function like "filter" that returns two lists, everything that matches, and everything that doesn't match?

17:32 TimMc: separate or some such

17:32 amalloy: tolstoy: hint: as always, the answer is juxt

17:32 TimMc: amalloy: juxt it!

17:32 damn, beat me to it

17:33 gfredericks: ,((juxt filter remove) even? (range 6))

17:33 clojurebot: [(0 2 4) (1 3 5)]

17:33 TimMc: (def separate (juxt filter remove))

17:33 (clojure.contrib.seq/separate)

17:33 tolstoy: Hah. That's a mouthful doc string on that.

17:34 amalloy: TimMc: you know what we do with people who recommend contrib...

17:34 TimMc: heh

17:34 * amalloy is torn between ~guards and $kill

17:35 TimMc: I'm partial to the first.

17:36 pjstadig: amalloy: thank them for pointing out functions that should have been migrated to new contrib instead of dropped?

17:36 TimMc: Anyway, that method does twice the necessary work.

17:37 clojurebot: Where did contrib go?

17:37 clojurebot: well... it's a long story: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

17:37 amalloy: TimMc: that's only sorta correct

17:38 pjstadig: ((juxt filter remove) f coll) is a lot simpler than (:use '[clojure.algo.seq :only [separate]]) (separate f coll) ;; pretending it got migrated to algo.seq

17:38 jkkramer: the punishment for recommending a contrib function should be to port it to 1.3

17:38 amalloy: (inc jkkramer)

17:38 lazybot: ⟹ 1

17:38 technomancy: jkkramer: yessss

17:39 amalloy: TimMc: you have little choice but to call filter and remove once each. you could arrange to call the predicate only once per item, but that would involve building a largeish number of lists, which is a waste of effort if the predicate is cheap

17:40 an implementation that does call pred once per item is at https://github.com/flatland/useful/blob/develop/src/useful/seq.clj#L21 if it interests you, though

17:40 Apage43: separate just called filter and remove anyhow

17:42 Raynes: (juxt filter remove)

17:42 Oh.

17:42 amalloy already did that. :<

17:43 amalloy: Raynes: it must really suck having a ten-minute latency to the irc server

17:43 Raynes: Or 10 minutes of scroll back that I didn't bother to read.

17:43 amalloy: (i don't have "Raynes: yes" on a hotkey, so i have to use snark)

17:47 TimMc: Raynes: Actually it calls filter and filter (complement f)

17:48 amalloy: What about a loop/recur building two vectors?

17:48 amalloy: TimMc: not lazy

17:48 TimMc: aha

17:49 amalloy: you can have laziness *or* "minimal work", but not both

17:49 TimMc: clojurebot: I am suddenly enlightened.

17:49 clojurebot: I don't understand.

17:50 TimMc: Good little zenbot.

17:50 amalloy: clojurebot: i don't understand is <reply> Suddenly, you are enlightened!

17:50 clojurebot: You don't have to tell me twice.

17:50 amalloy: clojurebot is the best toy ever

17:51 hiredman: it is true

17:52 TimMc: amalloy: So if you won't necessarily be consuming all the data, a lazy approach may be superior. But if you know you will consume everything, the loop/recur might be superior. (Assumes a predicate that actually does any real work.)

17:52 amalloy: TimMc: mostly true, but i don't think i totally agree

17:53 perhaps the input collection is ten million elements, and i know i want to deal with them all

17:53 but i don't need them all at once

17:53 TimMc: Point.

17:53 There's more than one reason for laziness.

17:55 amalloy: TimMc: and if you're willing to do a lot of mutability, it should be possible to get minimal-work and something that's (mostly) lazy

17:57 ie, make the two resultant lazy seqs aware of each other, mutating each other and the input seq. if you try to read from the filter-seq, and the predicate fails, it mutably appends to the remove-seq

18:02 i'm not sure i understand how ref-set interacts with transactions. is there anything actually broken about (dosync (ref-set r (f @r)))? of course an alter is better, but pretend the code is structured so that an alter is inconvenient - is this equivalent?

18:05 archaic: anyone use emacs evil-mode here? i need to integrate it with clojure-repl

18:06 Raynes: We should not talk of the great mode-that-shall-not-be-named.

18:09 srid: has anyone implemented capistrano-like tool on top of cake/lein?

18:09 brehaut: Raynes: theres a hastur-mode ?

18:12 technomancy: srid: pallet is probably the best clojure deployment tool

18:12 * technomancy is not sure if capistrano-like is necessarily a good thing =)

18:13 technomancy: would that mean reinventing the concept of a task because you don't know how your build tool works? =)

18:16 srid: hmm. i'll use shell script for now .. just < 10 lines of scp, ssh, uberjar and nohup :)

18:17 Apage43: amalloy: they are requivalent from the way i read the source

18:17 *equivalent

18:17 mqsoh: Capistrano was just pissing me off!

18:19 This channel is very relevant to my life.

18:29 TimMc: amalloy: I wonder if there would be a nice way to design such a mutually-mutable lazyseq thingum.

18:30 As in, nice enough to casually use the API the way one uses lazy-seq.

18:30 amalloy: TimMc: probably not

18:30 for one, as i said it's only "mostly" lazy

18:31 if your collection has a million items that fail the predicate, followed by one that doesn't, and you try to access the remove-seq, you'll have to keep the other million in memory in case you later try to access the filter-seq

18:31 TimMc: Right. :-/

18:45 tolstoy: Java-interop question: is there a clean way to match on the kind of exception I'm handed? (= (.getName (class ex)) "java.whatever.Exception"))?

18:46 Hm. (= (class "adsadad") java.lang.String) works. Good enough I think.

18:47 raek: tolstoy: also check out 'instance?'

18:47 tolstoy: Ah, okay. Not having a good day finding these things. Thanks!

18:51 gfredericks: tolstoy: lazybot has a nice findfn feature

18:51 $findfn String "foo" true

18:51 lazybot: [clojure.core/instance? clojure.core/not= clojure.core/distinct?]

18:53 amalloy: gfredericks: the unexpected answers are always the best

18:56 TimMc: It would be nice for not= and distinct? to be blacklisted.

18:57 $findfn 1 0

18:58 lazybot: [clojure.core/unchecked-dec clojure.core/rand-int clojure.core/dec]

18:58 amalloy: TimMc: i don't think they really come up that often

18:58 $ findfn 0

18:58 lazybot: [clojure.core/+ clojure.core/release-pending-sends]

18:59 amalloy: &(doc release-pending-sends)

18:59 lazybot: ⇒ "([]); Normally, actions sent directly or indirectly during another action are held until the action completes (changes the agent's state). This function can be used to dispatch any pending sent actions immediately. This has no impact on actions sent during a trans... https://gist.github.com/1299936

18:59 amalloy: well, you learn something new every day

18:59 $findfn 1

18:59 lazybot: [clojure.core/*]

19:01 gfredericks: $findfn false

19:01 lazybot: []

19:01 gfredericks: what would be a good name for (constantly false)?

19:01 my first thought was "nope"

19:02 $findfn nil

19:02 lazybot: [clojure.core/cond clojure.core/dosync clojure.core/import clojure.core/prn clojure.core/refer-clojure clojure.core/print clojure.core/with-loading-context clojure.core/newline clojure.core/comment clojure.core/or clojure.core/load clojure.core/shutdown-agents cloj... https://gist.github.com/1299943

19:02 gfredericks: jackpot

19:21 tolstoy: Do agents get garbage collected?

19:22 Nevermind: http://stackoverflow.com/questions/4609151/how-can-i-stop-a-specific-agent-in-clojure-when-are-their-states-garbage-collec

19:22 chouser: if they don't have any scheduled tasks, ys

19:22 tolstoy: Okay.

19:24 amalloy: gfredericks: i sadly none of those are actually the same as (constantly nil), i suspect

19:25 they're more like #(do nil), in that they require no args rather than ignoring their args

19:28 gfredericks: yep

19:28 $findfn ""

19:28 lazybot: [clojure.core/with-out-str clojure.core/print-str clojure.core/pr-str clojure.core/str clojure.contrib.string/as-str]

19:52 technomancy`: oh geez

19:52 joda-time 1.6 got deleted from maven central?

19:53 hm; search.maven.org claims it's still there

19:53 but it's not resolving

19:57 duck1123: is there a newer version, or is something funny going on?

19:57 how long do they hold on to artifacts?

19:57 technomancy`: non-snapshots are supposed to stick around forever

20:22 tolstoy: Is there a place where you can stuff "classpath resources" in leiningen other than "lib"? (Such as property files, etc).

20:22 technomancy`: tolstoy: sure; property files should go in resources/

20:23 tolstoy: Ah, okay. I did that. Seems that tools.logging + slf4j + logback isn't finding my logback.xml (like works automatically with Scala + SBT).

20:23 technomancy`: did you create the resources/ directory after launching the clojure process?

20:23 tolstoy: Who knows, could be some other issue. All this layering: sheesh.

20:24 Nope.

20:24 Could be that it's on the class path just fine, though.

20:24 technomancy`: if (clojure.java.io/resource "logback.xml") returns something then it's on the classpath

20:25 hiredman: well, it's visible to some classloader somewhere

20:25 technomancy`: true

20:25 hiredman: wow

20:25 you can actually even pass in the classloader

20:26 tolstoy: Would using "trampoline" affect it?

20:26 technomancy`: tolstoy: lein trampoline or clojure.core/trampoline?

20:26 tolstoy: lein trampoline.

20:26 It does seem to affect it.

20:27 technomancy`: ah... interesting.

20:27 tolstoy: I use trampoline because I'm messing with a lot of long-running persistent thread stuff and want to see the shutdown hooks work.

20:28 Wait! Hold on! I think "lein trampoline" is just fine.

20:30 technomancy`: whew

20:32 tolstoy: Yeah! No kidding!

20:34 technomancy`: ,(when (re-find #"Microsoft FrontPage" (slurp "http://shenlanguage.org")) (println "ಠ_ಠ"))

20:34 clojurebot: #<AccessControlException java.security.AccessControlException: access denied (java.net.SocketPermission shenlanguage.org:80 connect,resolve)>

20:34 technomancy`: dang it

20:35 well anyway, ಠ_ಠ

20:49 amalloy: technomancy`: clojurebot is just looking out for you. don't look at frontpage sites

20:49 it's for your own good. you'll understand when you're older

20:49 technomancy`: amalloy: it gets worse: <meta name="Originator" content="Microsoft Word 12">

20:50 amalloy: technomancy`: placing a <font> tag inside a <style> tag is a nice touch

20:50 er, an <a style="..."> tag

20:51 gfredericks: how have I gone this long with clojure without consciously realizing that slurp works with urls?

20:51 technomancy`: gfredericks: it snuck in during 1.2

20:51 gfredericks: I feel like I've even read it in the docs a number of times

20:51 I'm appalled

20:51 no more learning programming languages for me

20:53 oh good ##(doc slurp) doesn't mention it at all

20:53 lazybot: ⇒ "([f & opts]); Reads the file named by f using the encoding enc into a string and returns it."

20:53 technomancy`: I thought I opened a ticket for that

20:53 &(clojure-version)

20:53 lazybot: ⇒ "1.2.0"

20:53 technomancy`: oh, right

20:54 gfredericks: ,(clojure-version)

20:54 clojurebot: "1.3.0"

20:54 gfredericks: ,(doc slurp)

20:54 clojurebot: "([f & opts]); Opens a reader on f and reads all its contents, returning a string. See clojure.java.io/reader for a complete list of supported arguments."

20:54 gfredericks: aah

20:55 it's nice to have diversely-versioned bots. Is lazybot lagging on purpose?

20:57 maven compiles for java 1.3 by default? :/

20:58 either that or my pom is haunted

21:01 amalloy: gfredericks: no, Raynes is pretty close to getting lazybot on 1.3

21:03 Raynes: amalloy: It should be perfectly ready to go live.

21:03 amalloy: We just need to be vigilant.

21:03 amalloy: yeah, i know. but it isn't actually live yet, so you're only pretty close

21:03 Raynes: I'll consider throwing it up later.

21:04 amalloy: i wish i could think of something funny to teach clojurebot related to that. foo is <Raynes> I'll consider throwing it up later

21:06 gfredericks: somebody ought to put up an eval-only version of lazybot on 1.2. What would be a good name? fuddyduddybot?

21:06 amalloy: clojurebot: Raynes?

21:06 clojurebot: if it's not one thing it's another

21:06 technomancy`: amalloy: "Clojure 1.3: if swallowed, do not induce vomiting"?

21:06 jodaro: Raynes: http://www.joshrotenberg.com/wotd

21:06 it works

21:08 amalloy: this is unacceptable. how are there #clojure regulars that clojurebot doesn't have a soundbyte for?

21:08 gfredericks: clojurebot: amalloy?

21:08 clojurebot: amalloy is <amalloy> just use juxt, it'll be great

21:11 amalloy: (inc clojurebot)

21:12 gfredericks: (dec lazybot)

21:13 amalloy: gfredericks: weird, because his karma plugin claims to be loaded

21:13 gfredericks: justification: [lazybot didn't respond] or [law of conservation of bot karma]

21:13 archaic: why would (iterate inc 0) be used over (range) ?

21:14 gfredericks: archaic: to demonstrate iterate?

21:14 or because one forgot about range

21:14 amalloy: gfredericks: more reasons than that, keep going

21:15 gfredericks: chunked seqs!

21:15 amalloy: yeah, that's the most likely

21:15 archaic: ahh k

21:15 gfredericks: ,(map type (range) (iterate inc 0))

21:15 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: clojure.lang.ArityException: Wrong number of args (2) passed to: core$type>

21:15 gfredericks: boo

21:15 ,(map type [(range) (iterate inc 0)])

21:15 clojurebot: (clojure.lang.LazySeq clojure.lang.Cons)

21:15 gfredericks: yep, exactly not what I expected

21:15 amalloy: &(take 1 (map print (range)))

21:15 lazybot: ⇒ (012345678910111213141516171819202122232425262728293031nil)

21:16 amalloy: &(take 1 (map print (iterate inc 0)))

21:16 lazybot: ⇒ (0nil)

21:16 brehaut: gfredericks: iterate already has the first value computed, so it doesnt define it lazily, the lazy-seq is not the outermost element

21:16 s/element/form/

21:17 gfredericks: ,(type (rest (iterate inc 0)))

21:17 clojurebot: clojure.lang.LazySeq

21:17 brehaut: gfredericks: the body of iterate is (cons x (lazy-seq (iterate f (f x)))))

21:17 duck1123: &(take 2 (map print (iterate inc 0)))

21:17 lazybot: ⇒ (01nil nil)

21:18 amalloy: brehaut: there was a mailing list thread about that a week or two ago; i kinda wish iterate were all lazy anyway

21:19 brehaut: amalloy: interesting

21:19 * brehaut dives into the google groups mire

21:19 amalloy: because 1.3 allows you to call (realized?) on a lazy seq

21:19 brehaut: dev or normal list?

21:19 amalloy: ah of course

21:19 amalloy: normal i think

21:19 but if you try it on a Cons, you just get a classcastexception

21:20 brehaut: realized? is for lazy things, futures and promises right?

21:20 amalloy: perhaps making Cons implement IPending by always returning true is a better solution, though

21:20 brehaut: and delays, iirc

21:21 brehaut: just to double check, delays are lazy right?

21:21 amalloy: unclear on what this question means

21:21 gfredericks: it's either nonsensical or tautological

21:21 amalloy: a delay is a cached thunk

21:21 brehaut: yeah, so a delay falls into the category of lazy things?

21:21 gfredericks: ,(realized? (delay "FOO"))

21:21 clojurebot: false

21:21 amalloy: brehaut: sure, if you say so. i don't think it much matters whether you say that's true or not

21:22 gfredericks: ,(let [d (delay "FOO"), s (str @d)] (realized? d))

21:22 clojurebot: true

21:23 amalloy: to me it seems different from laziness: sequences automatically force themselves whenever needed, whereas delays are objects you can pass around and have to explicitly force

21:24 gfredericks: amalloy: i.e., laziness can usually be forgotten about but delays are explicit?

21:24 duck1123: they're super-lazy

21:24 brehaut: thats an interesting distinction

21:26 duck1123: Is there a way I can make my app finish up all of it's asynchronous tasks and logging before moving on to the next test?

21:26 I'm using clojure.test and midje, if that helps

21:27 amalloy: duck1123: await on your agent, or deref your future?

21:27 lazybot: clojurebot forget grok |is| a little hard to juxt but it's the best thing ever

21:27 duck1123: amalloy: I think I might need to re-engineer things so that I can always track my triggers

21:28 amalloy: argh dangit lazybot. it's totally my fault that he drops the : in those messages

21:29 duck1123: or just (Thread/sleep Integer/MAX_VALUE) to be extra-safe

21:29 duck1123: That might be a good quick and dirty solution, but it takes long enough to run my tests as it is

21:30 My problem is the actions in my system launch triggers which in turn call other actions, so when I get an error, it's all mixed up with the output of other tests

21:32 thankfully, I had the foresight to assign my executor service to a ref, so I might be able to make this work

22:35 gfredericks: (binding [future (something else)] ...)

22:56 archaic: jesus: In 1997, the Gartner Group reported that 80% of the world's business ran on COBOL with over 200 billion lines of code in existence and with an estimated 5 billion lines of new code annually

22:58 brehaut: apocryphal: apparently when .net was very young and there was a lot of buzz about 'every language needs to run on this common runtime' the cobol people had a bit of a panic about how they were going to make cobol OO (because of course everything on .net needs to be OO), during the fuss someone discovered that there had been an object cobol spec for years

23:21 Raynes: amalloy: Guess what I did.

23:21 amalloy: &*clojure-version*

23:21 lazybot: ⇒ {:major 1, :minor 2, :incremental 0, :qualifier ""}

23:21 Raynes: amalloy: I committed my API key in the README: https://github.com/Raynes/ororo

23:21 * amalloy guessed wrong

23:21 Raynes: I just got a notice that I went over my limit. Luckily, all I had to do was regenerate my key.

23:22 But hey, it's a real-world example, isn't it? ;)

23:22 amalloy: haha that's so weird. who spams wunderground api requests?

23:22 brehaut: Raynes: is that an xmen joke?

23:23 amalloy: (inc brehaut)

23:23 Raynes: There were like 80 today, so people were probably just using it and playing with it. I doubt anybody purposely made it happen. They probably didn't know it was a limited private key.

23:24 brehaut: Yes.

23:24 Not so much a joke as a homage?

23:27 jodaro: i did that with the first commit of wordnik

23:27 deleted and recreated the rep

23:27 o

23:28 Raynes: jodaro: At least it was the first commit.

23:28 But hey, all I had to do was generate a new one. No harm done.

23:29 amalloy: Actually, it's 500 per day. Wow. Somebody must have seriously spammed the server.

23:29 There is an evil Clojure programmer in our midst. Beware.

23:30 ibdknox_: wasn't me... this time.

23:30 jodaro: thats a lot of weather

23:30 Raynes: And I've found it.

23:30 amalloy: https://github.com/Raynes/ororo/commit/cc4f7fcfec001f4099a191e3129c2cf0cbad820f#commitcomment-663108

23:31 I knew he was evil. I could smell it in his emails.

23:33 jodaro: i think theres a rage comic in there somewhere

23:33 new idea for library - get it working - commit api key to github - ffffuuuuuu

23:43 aperiodic: does anyone know whether it's possible to use a builder pattern API that employs static class methods in clojure?

23:44 brehaut: aperiodic: are you asking if you can call static methods on java classes?

23:44 aperiodic: from the docs for the dot special form it seems that it might not be, but i'm not quite sure what's going on under the covers

23:44 brehaut: no

23:45 brehaut: the question is whether one can "thread" static method calls

23:45 brehaut: the API in question is apache.commons.cli.OptionBuilder

23:46 http://commons.apache.org/cli/api-release/org/apache/commons/cli/OptionBuilder.html

23:47 brehaut: by 'thread' do you mean ->

23:47 ,(-> "123" Integer/parseInt) ; frinstance?

23:47 clojurebot: 123

23:47 aperiodic: ideally, yes

23:48 the methods of the API all appear to be static class methods

23:48 so, e.g. (-> OptionBuilder (. withLongOpt "foo")) works as expected

23:50 but (-> OptionBuilder (. withLongOpt "foo") (. withDescription "bar")) gives a "No matching method found" exception

23:50 brehaut: you may need to type hint some things

23:51 aperiodic: do you understand how threading works?

23:51 because i think you might actually want doto in this instance

23:52 aperiodic: heh, i think i was replicating doto with ->

23:53 threading just iteratively inserts each form as the second member of the next form, right?

23:53 brehaut: yeah

23:53 or the last with ->>

23:53 based on that javadoc im a little surprised that what you tried above didnt work

23:55 aperiodic: i think the issue is the identity of the result of the first static method call

23:58 amalloy: aperiodic: you have to write something like (-> (OptionBuilder/withLongOpt "foo") (OptionBuilder/withDescription "bar"))

Logging service provided by n01se.net