#clojure log - Nov 08 2010

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

0:41 zakwilson: Are there Conj videos yet?

0:46 cemerick: zakwilson: http://twitter.com/#!/stuartsierra/status/544111341871105

0:47 zakwilson: cemerick: Ahh. It sounds like there was a lot of cool stuff there. I'm (over) eager to see the footage.

0:48 cemerick: it's coming :-)

0:48 May be a while yet, but I'm glad it's in-process.

0:48 I'm still sore about the video from ILC 2008 not getting out there. :-(

0:50 ppppaul: how would i convert \+ to +

0:51 amalloy: &(symbol \+)

0:51 sexpbot: java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.String

0:51 ppppaul: :D

0:51 amalloy: &(symbol (str \+))

0:51 sexpbot: ⟹ +

0:56 Raynes: That retarded bug should be fixed now.

1:12 ppppaul: ,(symbol +)

1:12 clojurebot: java.lang.ClassCastException: clojure.core$_PLUS_ cannot be cast to java.lang.String

1:12 ppppaul: ,(symbol '+)

1:12 clojurebot: +

1:13 ppppaul: ,(symbol "+")

1:13 clojurebot: +

1:13 rata_: how does I execute a class generated with :gen-class and compiled with leiningen?

1:13 ppppaul: magic

1:13 rata_: cd classes; java -cp . app doesn't work

1:14 amalloy: rata_: lein uberjar

1:14 java -jar myproj.jar

1:14 rata_: even when it's in :aot and not in :main?

1:14 Raynes: You can't 'execute' a class without a main method.

1:15 rata_: it has a main method

1:15 but it's not in project.clj as :main

1:15 it's in aot

1:15 Raynes: Then :main needs to be set to the namespace that -main is defined in.

1:16 rata_: Raynes: yes, but I don't want to put it in :main... it's not at all the main program

1:16 it's just to test something

1:17 Raynes: You *have* to if you want to execute it. You can't run something without a main method.

1:17 I suppose you could run the class directly.

1:18 java -cp classes your.main.Class?

1:18 rata_: it doesn't work so

1:19 amalloy: rata_: even with a fully-qualified classname?

1:19 rata_: it works now :) I had to put clojure.jar and clojure-contrib.jar in the classpath (even when they are compiled into classes/)

1:19 amalloy: its namespace is just app

1:22 Raynes: You know you don't have to AOT compile stuff all of the time, right?

1:23 I don't know what you're doing, of course. Just a note. If you're AOT compiling just to be compiling, you're doin' it wrong. :p

1:23 AOT is mostly for special interop stuff.

1:23 rata_: yes, I just wanted to AOT this tiny app

1:24 Raynes: Alrighty. Just checking. :>

1:24 rata_: it's to test how long it takes to run from the terminal as an app and to profile it with profiler4j

1:25 what's the idiomatic way to convert an string to a number (integer in this case)? (Integer. "1")?

1:59 Raynes: raek: &| (Integer/parseInt "1") |&

1:59 sexpbot: ⟹ 1

2:00 rata_: that's better than (Integer. "1")?

2:00 ppppaul: hmm

2:00 Raynes: Yes.

2:00 ppppaul: clojure doesn't have it's own?

2:01 ,(find-doc "integer")

2:01 clojurebot: -------------------------

2:01 clojure.pprint/*print-base*

2:01 nil

2:01 The base to use for printing integers and rationals.

2:01 -------------------------

2:01 clojure.pprint/*print-radix*

2:01 nil

2:01 Print a radix specifier in...

2:01 Raynes: rata_: There is also read-string, but it reads any object rather than just integers, and if you get your integer from user input, it can be dangerous.

2:01 ppppaul: Where Java isn't broke, Clojure doesn't fix it.

2:02 ppppaul: (int 1)

2:02 ,(int 1)

2:02 clojurebot: 1

2:02 ppppaul: ,(int "1")

2:02 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Character

2:02 ppppaul: ,(int \1)

2:02 clojurebot: 49

2:02 ppppaul: well...

2:02 (doc int)

2:02 clojurebot: "([x]); Coerce to int"

2:03 ppppaul: (symbol "1")

2:03 ,(symbol "1")

2:03 clojurebot: 1

2:03 ppppaul: ,(+ (symbol "1") 1)

2:03 clojurebot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number

2:03 ppppaul: ,(+ (int (symbol "1")) 1)

2:03 clojurebot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Character

2:03 ppppaul: blah

2:05 (doc ints)

2:05 clojurebot: "([xs]); Casts to int[]"

2:05 ppppaul: (ints "1")

2:05 ,(ints "1")

2:05 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to [I

2:05 ppppaul: ,(ints 1)

2:06 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to [I

2:06 ppppaul: confusing

2:06 replaca: ,(ints [1 2 3 4])

2:06 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to [I

2:07 ppppaul: (int '1)

2:07 ,(int '1)

2:07 clojurebot: 1

2:08 ppppaul: ,(+ (int '1) 1)

2:08 clojurebot: 2

2:08 ppppaul: coooool

2:08 ,(+ (int (symbol 1)) 1)

2:08 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

2:08 ppppaul: awww

2:08 ,(+ (int (quote (symbol 1))) 1)

2:08 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.lang.Character

2:09 rata_: thanks Raynes :)

2:09 good night guys

2:09 see you

2:09 ppppaul: what am i doing wrong?

2:09 replaca: ,'1

2:09 clojurebot: 1

2:09 ppppaul: ,(quote 1)

2:09 clojurebot: 1

2:09 replaca: ppppaul: no symbol there

2:10 ppppaul: ,(quote (symbol 1))

2:10 clojurebot: (symbol 1)

2:10 ppppaul: ,(+ (int (quote 1)) 1)

2:10 clojurebot: 2

2:10 ppppaul: the '1' is a symbol or a number?

2:10 replaca: numbers are quoted all by themselves, so '1 doesn't do anything

2:11 ,'"hello"

2:11 clojurebot: "hello"

2:11 replaca: ppppaul: strings too

2:11 ppppaul: i'm just wondering cus i am converting a string to symbols, and want to use some of them as numbers

2:11 ,(map symbol (rest (split "1+2+3+4" #""))))

2:11 clojurebot: java.lang.Exception: Unable to resolve symbol: split in this context

2:12 ppppaul: ,(map symbol (rest (clojure/split "1+2+3+4" #""))))

2:12 clojurebot: java.lang.Exception: No such namespace: clojure

2:12 ppppaul: ,(map symbol (rest (clojure.string/split "1+2+3+4" #""))))

2:12 clojurebot: (1 + 2 + 3 + 4)

2:12 ppppaul: what i'm doing isn't crazy, is it?

2:13 chouser: ,(class (first (map symbol (rest (clojure.string/split "1+2+3+4" #""))))))

2:13 clojurebot: clojure.lang.Symbol

2:13 replaca: ,(Integer/valueOf (name (symbol "1")))

2:13 clojurebot: 1

2:13 replaca: try that

2:14 ppppaul: ok

2:14 chouser: ,(map read-string (next (clojure.string/split "1+2+3+4" #"")))

2:14 clojurebot: (1 + 2 + 3 + 4)

2:14 chouser: ,(class (first (map read-string (next (clojure.string/split "1+2+3+4" #"")))))

2:14 replaca: ppppaul: normally you would ceck the string for integer-ness before going to a symbol or number

2:14 clojurebot: java.lang.Integer

2:15 ppppaul: i validate the string with regest

2:15 regex

2:15 then i parse it

2:15 i'm writing up a 24 game

2:15 chouser: ppppaul: you saw read-string there?

2:15 replaca: ppppaul: yeah, nothing wrong with that (though sometime the regex can get you in trouble), it's just less common

2:16 ppppaul: i love regex

2:16 replaca: :)

2:16 ppppaul: ,(re-find #"(?:\d[\\+-\\*\\])+\d" "6*7+8-4")

2:16 clojurebot: "6*7+8-4"

2:16 ppppaul: i can't test it with "\" though

2:16 it breaks

2:17 least in emacs

2:17 ,(re-find #"(?:\d[\\+-\\*\\])+\d" "6*7+8\4")

2:17 clojurebot: "6*7+8"

2:17 chouser: ,(re-find #"(?:\d[\\+-\\*\\])+\d" "6*7+8-4\\2")

2:17 ppppaul: :(

2:17 clojurebot: "6*7+8-4\\2"

2:17 * chouser goes to bed

2:17 ppppaul: my user isn't going to type in "\\"

2:17 replaca: ppppaul: regexs are great when the problem is really a regex problem

2:18 goodnight chouser!

2:18 ppppaul: i've been doing a lot of JS automation scripting.... got regex coming out of my ass

2:18 replaca: ,(map class (map read-string (next (clojure.string/split "1+2+3+4" #""))))

2:18 clojurebot: (java.lang.Integer clojure.lang.Symbol java.lang.Integer clojure.lang.Symbol java.lang.Integer clojure.lang.Symbol java.lang.Integer)

2:18 ppppaul: lol

2:18 coooooool

2:19 replaca: just expounding on chouser's work :)

2:19 ppppaul: (doc read-string)

2:19 clojurebot: "([s]); Reads one object from the string s"

2:19 replaca: ,(map class (map read-string (next (clojure.string/split "11+222+3333+4444" #""))))

2:19 clojurebot: (java.lang.Integer java.lang.Integer clojure.lang.Symbol java.lang.Integer java.lang.Integer java.lang.Integer clojure.lang.Symbol java.lang.Integer java.lang.Integer java.lang.Integer ...)

2:19 ppppaul: nice, i'll use that

2:20 replaca: but that's not really what you want, though you may be able to tokenize with a regex, depending on the complexity of your language

2:20 ppppaul: i think that's what i want. get numbers and symbols out of the string

2:21 regex is just for validation

2:21 i could do re-seq though

2:22 ,(read-string \1)

2:22 clojurebot: java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.String

2:22 replaca: ppppaul: well, each digit was pulled separately

2:22 ppppaul: that's cus of your regex

2:22 #"" splits on char

2:22 replaca: right

2:22 ppppaul: #"\d+" would get the full numbers

2:23 replaca: ,(map class (map read-string (next (clojure.string/split "11+222+3333+4444" #"\d+"))))

2:23 clojurebot: (clojure.lang.Symbol clojure.lang.Symbol clojure.lang.Symbol)

2:23 ppppaul: 24 game just uses single digits, so that's what i want

2:23 replaca: ahh, ok

2:23 ppppaul: you aren't matching the +s

2:23 replaca: I know :)

2:23 ppppaul: gotta have a regex more like mine

2:24 #"(\d[\\+)+

2:24 #"(\d[\\]+)+

2:24 #"(\d[\\]+)+"

2:24 something like that

2:24 #"(\d[\\]+)+\d"

2:24 #"(\d[\\]+)+\d+"

2:24 replaca: yeah, it's too late for me to do even simple regexs :)

2:24 ppppaul: lol

2:25 ,(map class (map read-string (next (clojure.string/split "11+222+3333+4444" #"(\d[\\+])+\d"))))

2:25 clojurebot: (java.lang.Integer java.lang.Integer java.lang.Integer)

2:26 ppppaul: ,(map class (map read-string (next (clojure.string/split "11+222+3333+4444" #"(\\+"))))

2:26 clojurebot: Unclosed group near index 4

2:26 (\\+

2:26 ^

2:26 ppppaul: ,(map class (map read-string (next (clojure.string/split "11+222+3333+4444" #"\\+"))))

2:26 clojurebot: ()

2:26 ppppaul: ,(map class (map read-string (next (clojure.string/split "11+222+3333+4444" #"\+"))))

2:26 clojurebot: (java.lang.Integer java.lang.Integer java.lang.Integer)

2:27 replaca: the prob with split is the it doesn't get the separators

2:27 ppppaul: ,(map class (map read-string (clojure.string/split "11+222+3333+4444" #"\+")))

2:27 clojurebot: (java.lang.Integer java.lang.Integer java.lang.Integer java.lang.Integer)

2:27 ppppaul: true

2:27 would have to make 2 passes

2:27 i just need 1 pass for my problem

2:27 replaca: yup

2:28 ppppaul: :D

2:28 replaca: of course,

2:28 ,(into [] "1+2+3")

2:28 clojurebot: [\1 \+ \2 \+ \3]

2:28 replaca: does about the same

2:29 ,(map class (map (comp read-string str) "11+222+3333+4444"))

2:29 clojurebot: (java.lang.Integer java.lang.Integer clojure.lang.Symbol java.lang.Integer java.lang.Integer java.lang.Integer clojure.lang.Symbol java.lang.Integer java.lang.Integer java.lang.Integer ...)

2:30 replaca: for instance

2:30 ,(map (comp read-string str) "1+2+3+4")

2:30 clojurebot: (1 + 2 + 3 + 4)

2:30 ppppaul: into is giving characters...

2:30 hhmmmmmmm

2:31 replaca: yeah, you don't even need the into there

2:31 cause a string *is* a sew of chars

2:31 ppppaul: (doc comp)

2:31 clojurebot: "([f] [f g] [f g h] [f1 f2 f3 & fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc."

2:31 replaca: == #(read-string (str %))

2:31 ppppaul: yeah, i see

2:32 ,(map (comp read-string str class) "1+2+3+4")

2:32 clojurebot: (class class class class class class class)

2:32 ppppaul: lol

2:32 they are all strings, i don't know if that's better than symbols

2:32 i think symbols would be better for me

2:32 replaca: you need the class on the lft

2:33 ppppaul: ,(map (comp class read-string str) "1+2+3+4")

2:33 clojurebot: (java.lang.Integer clojure.lang.Symbol java.lang.Integer clojure.lang.Symbol java.lang.Integer clojure.lang.Symbol java.lang.Integer)

2:33 replaca: no they're not

2:33 ppppaul: ooooooooooh

2:33 replaca: ,(map (comp class read-string str) "1+2+3+4")

2:33 clojurebot: (java.lang.Integer clojure.lang.Symbol java.lang.Integer clojure.lang.Symbol java.lang.Integer clojure.lang.Symbol java.lang.Integer)

2:33 ppppaul: comp is cool

2:34 i'll use this method

2:34 replaca: it's cooler in haskell, which has syntax for it :)

2:34 ppppaul: :D

2:35 now i need to convert from infix to postfix notation

2:35 oh

2:35 maybe i don't

2:35 replaca: it depends if you have operator precedence or not

2:36 Raynes: ppppaul: sexpbot is working again, fyi. :)

2:36 s/working/running/

2:36 sexpbot: <Raynes> ppppaul: sexpbot is running again, fyi. :)

2:36 ppppaul: sexbot lot

2:36 love

2:36 i think there is operator precedence

2:37 clojure has infix notation

2:37 i saw it

2:37 can't find it on clojuredocs, though

2:39 maybe i'm wrong... there is some dude with an infix git project, though

2:39 Raynes: ppppaul: https://github.com/fogus/unfix

2:41 ppppaul: i don't think i can use this stuff since it's outside of core

2:42 Raynes: replaca: Syntax for what? Function composition?

2:42 ppppaul: i looked at the infix code, holy crap it's complicated

2:42 i need to take "1+1+1+1" and get an answer out of it "4"

2:43 replaca: yeah, sure and partials too

2:43 ppppaul: but with *+\-

2:43 Raynes: replaca: Haskell doesn't have syntax for function composition. I'm pretty sure '.' is an ormal function.

2:43 normal*

2:43 replaca: well, yeah, but the overall syntax of the language makes that so

2:43 Raynes: Um, okay.

2:44 replaca: same with partials -> you can just not supply all the args and you've got a partial

2:44 ppppaul: i've done partials

2:45 replaca: the the design of the language means you use composition and partials a lot more in Haskell

2:45 fwiw

2:45 ppppaul: i've heard

2:46 maybe i should just ignore precedence?

2:47 (%6 (%4 (%2 %1 %3) %5) %7)

2:48 how hard do you think it would be to include precedence?

2:49 ,(seventh [1 2 3 4 5 6 7)

2:49 clojurebot: Unmatched delimiter: )

2:49 ppppaul: ,(seventh [1 2 3 4 5 6 7])

2:49 clojurebot: java.lang.Exception: Unable to resolve symbol: seventh in this context

2:50 ppppaul: ,(firrst [1 2 3 4 5 6 7])

2:50 clojurebot: java.lang.Exception: Unable to resolve symbol: firrst in this context

2:50 ppppaul: ,(nth 7 [1 2 3 4 5 6 7])

2:50 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number

2:50 ppppaul: ,(7 [1 2 3 4 5 6 7])

2:50 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

2:51 ppppaul: (doc nth)

2:51 clojurebot: "([coll index] [coll index not-found]); Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences."

2:51 amalloy: (nth [1 2 3 4 5 6 7] 7)

2:51 except 7 will be out of range

2:52 ,(nth [1 2 3 4 5 6 7] 5)

2:52 clojurebot: 6

2:52 ppppaul: clojure needs a tenth

2:52 just like common-lisp

2:52 needs a forty-secondth too

2:52 maybe a towel function as well

2:52 amalloy: ppppaul: we could use caadar too

2:53 ppppaul: caadar is just weird now

2:53 i thought clojure was supposed to have something like ressst

2:53 amalloy: yeah, because it's absurd

2:53 ppppaul: (doc first)

2:53 clojurebot: "([coll]); Returns the first item in the collection. Calls seq on its argument. If coll is nil, returns nil."

2:53 Raynes: &(nnext [1 2 3 4])

2:53 sexpbot: ⟹ (3 4)

2:54 ppppaul: ,(fiiirst [1 2 3 4 5 6]_

2:54 clojurebot: EOF while reading

2:54 ppppaul: ,(fiiirst [1 2 3 4 5 6])

2:54 clojurebot: java.lang.Exception: Unable to resolve symbol: fiiirst in this context

2:54 ppppaul: ,(fffirst [1 2 3 4 5 6])

2:54 clojurebot: java.lang.Exception: Unable to resolve symbol: fffirst in this context

2:54 ppppaul: (doc nnext)

2:54 Raynes: &(ffirst [1 2 3])

2:54 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

2:54 clojurebot: "([x]); Same as (next (next x))"

2:54 ppppaul: there aren't enough

2:55 how can we call clojure a real lisp without ffffffffnnnnnext

2:55 going to have to make my own

2:57 anyone been doing euler problems?

2:58 some are really easy, like... they ask for a single number

2:59 that's a one symbol problem

4:00 jrp: has anyone gotten lein-vimclojure working?

4:01 http://pastie.org/1281103 this confuses me. I have classpath issues, but java seems to work fine?

4:15 esj: bah. which cat dragged Monday in ?

4:16 bartj: esj, quote from a movie?

4:16 esj, or garfield ? :)

4:17 esj: probably :) I thought I'd made it up, but usually it turns out somebody else has thought of all the good lines before

4:17 Raynes: $isgd http://programmers.stackexchange.com/questions/4433/who-is-the-most-interesting-programmer-in-the-world/4454#4454

4:17 sexpbot: Raynes: http://is.gd/gPuza

4:17 Raynes: $learn interesting http://is.gd/gPuza

4:17 sexpbot: My memory is more powerful than M-x butterfly. I wont forget it.

4:17 esj: Raynes: lol.

5:49 Raynes: ,(Thread/sleep 10)

5:49 clojurebot: nil

7:04 klang: In sbcl, (time (foo)) returns the number of processor cycles and the amount of memory used (among other things). Is there any thing similar in clojure?

7:12 nimred: is new clojure-contrib's ./modules/complete/target/complete-$VERSION-bin.jar what old clojure-contrib's ./target/clojure-contrib*.jar was ?

7:35 _bob: open #illumos

7:35 join #opensolaris

7:42 sid3k: hi all. I'm going to install java for just clojure development. is it ok to use openjdk?

7:45 any ideas, suggestions?

7:46 bleeppurple: I have run clojure on fedora using openjdk

7:47 and then use lein as build tool

7:50 klang: I am using openjdk with clojure on ubuntu, without any problems.

8:03 sid3k: klang: bleeppurple thanks

8:03 bleeppurple: no probs

8:05 rdeshpande: hello

8:17 sid3k: I've cloned clojure contrib repo and typed "mvn package" on the directory

8:17 it has put lots of log lines with no errors

8:18 but there is no file like "clojure-contrib*.jar"

8:18 I'm following this article: http://riddell.us/ClojureSwankLeiningenWithEmacsOnLinux.html

8:19 any ideas? I'm not familiar with java world but mvn make me sick

8:20 bleeppurple: wait a minute....

8:20 sid3k: I have no mvn experience with no trouble ....

8:21 chouser: sid3k: you looked in the dir "target" ?

8:21 sid3k: there is no target dir

8:24 bleeppurple: where are you on the tutorial?

8:24 sid3k: on the mvn package command

8:26 it builds lots of packages with no errors but doesn't create target directory

8:26 bleeppurple: try lein self-install

8:27 have you installed lein script right?

8:27 sid3k: readme offers mvn install command

8:28 bleeppurple: i have a few problems building contrib with mvn...used lein instead

8:28 sid3k: bleeppurple: I want to install manually

8:29 bleeppurple: Ok

8:29 sid3k: btw readme tells that an uberjar containing all compiled modules at modules/complete/target directory

8:29 I guess target dir was changed

8:31 bleeppurple: im trying to build...see what i get

8:32 sid3k: arright

8:38 bleeppurple: mine built successfully....

8:40 sid3k: into which directory?

8:41 to ./target or ./modules/complete/target/ ?

8:41 bleeppurple:

8:42 bleeppurple: 2nd 1...

8:44 chouser: oh, I bet my ./target dir is old, sorry

8:44 bleeppurple: as complete-$VERSION-bin.jar

8:45 sid3k: all right, I completed the installation and reached my fresh clojure environment. thanks guys

8:45 lenw: hi all - i have a (defmulti process class) what do i say on the defmethod for an array of strings - if such a thing is possible ?

8:46 or for any array of incoming type ?

8:46 chouser: ,(class (into-array String []))

8:46 clojurebot: [Ljava.lang.String;

8:47 lenw: so the same defmethod for String will match the array of String ?

8:47 chouser: nope

8:47 (defmethod process (class (into-array String [])) [x] (str "is a string " x))

8:48 er

8:48 sid3k: btw I saw a performance comparision of clojure and nodejs that claims clojure 2x faster than nodejs and also asynchronous callbacks are dirty

8:48 chouser: (defmethod process (class (into-array String [])) [x] (str "is a string-array " x))

8:48 lenw: hehe yes thanks a mill chouser

8:49 sid3k: my question is, does clojure offers multiple threads for concurrent web apps?

8:49 chouser: could use (Class/forName "[Ljava.lang.String;") if you think that's clearer.

8:49 sid3k: or is there any clojure feature for coding asynchronous, concurrent web apps like comet servers?

8:51 because millions of users would make stream at the same time, we need a single threaded solution for comet or web socket

8:51 any ideas?

8:51 clojurebot: Titim gan éirí ort.

8:51 sid3k: *for a beginner

8:52 lenw: chouser: the first looks clearer imho :)

8:59 chouser: sid3k: the default behavior of ring on most (all?) servers is to give each client request its own thread for the duration of a request+response

8:59 sid3k: is that what you're asking?

9:00 sid3k: chouser: yeah, and this behavior is not a huge disadvantage

9:01 chouser: not at all, in fact it works well with Clojure's approch to concurrency.

9:02 sid3k: chouser: here is the article I was mentioning

9:02 <chouser> not at all, in fact it works well with Clojure's approch to

9:02 ah wrong paste sorry

9:02 http://dosync.posterous.com/22397098

9:02 tufflax: I don't understand what get-in does. Can anyone explain?

9:02 &(doc get-in)

9:02 sexpbot: ⟹ "([m ks] [m ks not-found]); Returns the value in a nested associative structure, where ks is a sequence of ke(ys. Returns nil if the key is not present, or the not-found value if supplied."

9:02 sid3k: chouser: are you familiar with comet or websockets?

9:03 chouser: sid3k: a bit, sure

9:03 sid3k: if response lasts 30 seconds, we can't use threads

9:03 chouser: why's that?

9:03 sid3k: on most modern OSs, threads are pretty cheap.

9:03 sid3k: that means a thousand thread for a thousand user because

9:04 think about facebook's instant messenger

9:04 chouser: yes, if you're sure that's a problem for your usage profile, do consider aleph.

9:05 sid3k: the thing I'm trying to ask is, does clojure provide one-threaded concurrency like javascript's callbacks?

9:06 klang: Repeating a question from earlier: In sbcl, (time (foo)) returns the number of processor cycles and the amount of memory used (among other things). Is there any thing similar in clojure?

9:06 chouser: sid3k: you certainly can do that, yes.

9:06 sid3k: chouser: how?

9:07 using what?

9:07 chouser: tufflax: get-in (and update-in, and assoc-in) are for nested collection, like multi-dimentional arrays.

9:07 sid3k: functions.

9:07 sid3k: ah great

9:07 with what?

9:07 chouser: using functions, just like javascript does

9:07 sid3k: asynchronously?

9:07 without threads?

9:07 chouser: well, you're always going to need at least one thread, right?

9:07 sid3k: yep

9:08 i'm correcting: asynchronously, with just one thread?

9:08 chouser: and if you've got multiple clients actively sending at once, you wouldn't mind one thread for each, right?

9:08 it's just idle connections that you're rather not assign a thread to?

9:08 & (get-in [[1 2 3] [4 5 6] [7 8 9]] [2 1])

9:08 sexpbot: ⟹ 8

9:08 Chousuke: klang: I'm not aware of anything simple like that but probably you could use a java profiler.

9:08 sid3k: I would mind

9:09 chouser: tufflax: like that ... [2 1] are essentially coordinates into the 2D "grid" of numbers.

9:09 tufflax: I read the source, now i get it. The doc string was not very clear imo.

9:09 Thanks though.

9:10 Chousuke: hmm

9:11 chouser: sid3k: why?

9:11 Chousuke: &(->> [[1 2 3] [4 5 6] [7 8 9]] 2 1)

9:11 sexpbot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

9:11 Chousuke: &(macroexpand '(->> [[1 2 3] [4 5 6] [7 8 9]] 2 1))

9:11 sexpbot: ⟹ (1 (2 [[1 2 3] [4 5 6] [7 8 9]]))

9:11 chouser: Chousuke: you'd need ->< :-)

9:11 Chousuke: heh

9:11 seems so

9:12 solussd: chouser- just finished 'the joy of clojure' meap this-morning. good book, thanks!

9:12 sid3k: chouser: because comet needs totally asynchronous architecture

9:13 check out python's tornado framework friendfeed uses

9:13 chouser: solussd: thanks, glad you liked it.

9:13 sid3k: they run it with just 4 instances using nginx for millions of users streaming consistently

9:13 chouser: sid3k: what I mean is, what harm would you suffer if multiple active clients used multiple real threads?

9:13 sid3k: you can't do it by opening threads for users

9:15 klang: Chousuke: hmm, ok .. not simple but workable

9:15 sid3k: chouser: consider you're coding facebook's instant messenger. a billion user will going to send a request which is streaming for 30 seconds your server

9:16 chouser: sid3k: are you aware of how Clojure's agent's behave? That might interest you.

9:16 sid3k: how can you open a thread for a user? can't you see the insanity?

9:16 Chousuke: klang: also check out the clojure debugging toolkit (http://georgejahad.com/clojure/cdt.html). I haven't used it myself but it looks nice :)

9:17 sid3k: chouser: I'm not aware of, of course. this is why I'm asking because the comparision with nodejs was claiming that clojure uses threads for concurrency

9:17 if there is no another solution for concurrency, it's not good

9:18 chouser: sid3k: agents are built into clojure. take a look http://clojure.org/agents

9:19 sid3k: chouser: what is the goal of agents for this discussion?

9:20 have you read my facebook example?

9:23 belun: (doc let-fn)

9:23 clojurebot: I don't understand.

9:23 belun: (doc letfn)

9:23 clojurebot: "([fnspecs & body]); Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body. fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+)"

9:27 chouser: sid3k: agents provide a combination of work queues and thread pools so that incoming work (client requests) can be assigned to threads without having too many running threads for how many cores you've got.

9:27 klang: Chousuke: I have a fear for debuggers .. but thanks, simple metrics for the resources used, like in the sbcl case, would be sufficient.

9:28 sid3k: chouser: sounds cool

9:28 chouser: using 'send', if you've reached you max number of threads, the work queues up until more threads are available.

9:36 tufflax: When I type (macroexpand ...) in my repl, the result gets evaluated too, so I can't really see the structure of it. How do I stop that from happening?

9:38 chouser: (macroexpand '(foo)) ; don't forget to quote the form like that

9:39 tufflax: oh ok

9:40 sdeobald: Anyone familiar with the internals of clojars around? http://clojars.org/repo/all-poms.txt seems to be lying to me, but perhaps I'm just reading it wrong.

9:40 tufflax: That expands it once, but what if I want it completely expanded, but not evaluated?

9:40 sdeobald: Of course I was. Wups.

9:42 chouser: tufflax: that's not actually how the clojure compiler works, but there's a thing in contrib that sorta simulates what happens.

9:42 tufflax: hm ok, thank you!

9:42 jarpiain: ,(clojure.walk/macroexpand-all '(or nil false true))

9:42 clojurebot: (let* [or__3470__auto__ nil] (if or__3470__auto__ or__3470__auto__ (let* [or__3470__auto__ false] (if or__3470__auto__ or__3470__auto__ true))))

9:42 jarpiain: ,(macroexpand '(or nil false true))

9:42 clojurebot: (let* [or__3470__auto__ nil] (if or__3470__auto__ or__3470__auto__ (clojure.core/or false true)))

9:42 chouser: jarpiain: thanks, I can never remember it.

9:46 _bob: chouser: can I ask a question on agents?

9:47 I am looking into Clojure because I saw a presentation on them by mr Hickey

9:47 however I recently read a bogpost

9:47 http://webcache.googleusercontent.com/search?q=cache:Htvhj0QHWaMJ:measuringmeasures.com/blog/2010/8/16/clojure-workers-and-large-scale-http-fetching.html+&cd=1&hl=en&ct=clnk

9:47 it has been removed from the blog I just saw

9:48 chouser: _bob: you can ask

9:48 _bob: so I don't know if the critisism of agents was valid

9:49 his key argument agains agents: Clojure agents block on failure

9:49 chouser: _bob: interesting. as of 1.2, there are a couple different error-handling modes

9:51 (doc set-error-mode!)

9:51 clojurebot: "([a mode-keyword]); Sets the error-mode of agent a to mode-keyword, which must be either :fail or :continue. If an action being run by the agent throws an exception or doesn't pass the validator fn, an error-handler may be called (see set-error-handler!), after which, if the mode is :continue, the agent will continue as if neither the action that caused the error nor the error itself ever happened. If the mode is :fail, t

9:51 _bob: Do agents block on failure?

9:52 chouser: _bob: so in :continue mode, the agent doesn't block on error

9:56 _bob: that blog entry does seem to still be there: http://measuringmeasures.com/blog/2010/8/16/clojure-workers-and-large-scale-http-fetching.html

10:07 _bob: he's also complaining about partition which has been solved with partition-all

10:08 _bob: chouser: yes that is also commented on in the comments on the blog

10:08 chouser: and about an agent thread pool that is not user-configurable. There has been some discussion about how to change that, and imagine it'll happen at some point, perhaps a user-provided pool.

10:08 _bob: I am sorry I missed your previous replies, lost my connection for a few minutes

10:09 chouser: _bob: so in :continue mode, the agent doesn't block on error

10:09 _bob: that blog entry does seem to still be there: http://measuringmeasures.com/blog/2010/8/16/clojure-workers-and-large-scale-http-fetching.html

10:10 _bob: chouser: ok, good I found it strange I got an error on the link

10:10 chouser: good to hear the agents don't block

10:21 lrenn: does slime-interrupt not work? Is there a way to kill along running function started in the slime repl?

10:35 vibrant_: hell-o

10:36 there is no equivalent of Java WeakHashMap in Clojure?

10:40 cemerick: vibrant: why not use WHM itself, if you want it?

10:41 vibrant: cemerick; yeah i guess that is an option. i'm writing a game so i'd like to have a map holding all players by ID, and then a map holding all units by ID, and then each player has a map containing his units. so when i remove a unit i'd have to remove it from the player's set of units.

10:41 but i guess it's not that much work after all manually heh.

10:42 cemerick: I'm just saying, if it does what you want, use it.

10:42 vibrant: yea youer' right.

10:43 cemerick: It is definitionally not possible to make a persistent flavor of it, so an "equivalent" can't really exist (if that implies a functional data structure).

10:44 vibrant: yea and that's evil.

10:48 cemerick: vibrant: I wouldn't say that, especially when there's no viable alternative for certain use cases.

10:49 danlucraft: Congrats on the redcar buzz – it seems to have come into its own :-)

10:52 nimred: when running M-x slime this is what i get : http://clojure.pastebin.com/CxSmy9zD

10:52 is it OK ?

10:56 cemerick: chouser: http://groups.google.com/group/clojure-maven-plugin/browse_frm/thread/ec87a43c3bfac1b6

10:58 apgwoz: did stuart ever make his "simplicity ain't easy" slides available?

10:59 pdlogan: apgwoz: I think I saw them yesterday in a tweet?

10:59 cemerick: apgwoz: yes, see his twitter feed

11:02 apgwoz: oh. i must have missed that.

11:02 thanks!

11:05 fogus_: pdlogan: Fighting the dynamic vs static fight! Good luck with that. ;-)

11:05 pdlogan: someone pull me back from the brink...

11:11 fogus_: I find the dynamic vs static discussions to be incredibly boring these days. (does that help?)

11:13 cemerick: Generally, I listen to both sides, and say, "all of the above, please" :-P

11:14 Perhaps that makes me naive *shrug*

11:16 pdlogan: agree with all of the above. I tried to stay out of the main debate and point out a couple 2-3 flaws... er, nevermind.

11:16 cemerick: pdlogan: sounds like I missed something…link?

11:18 pdlogan: it was mostly @stevedekorte taking the side of the dynamic and @psnively taking the side of the static

11:19 cemerick: ah

11:19 then maybe I didn't miss much :-)

11:19 twitter arguments/debates are exhausting

11:19 chouser: cemerick: yes, pompath

11:20 cemerick: chouser: stellar :-) Feel free to weigh in on that thread if you haven't already. Seeing "live" demand may motivate an implementor.

11:20 And by all means, describe it differently if need be.

11:20 pdlogan: yeah, not really much substance - a lot of talking past each other, false claims, people contradicting themselves, etc.

11:20 chouser: cemerick: ok. busy at the moment, will try to weigh in later

11:21 cemerick: chouser: sure, np. I don't feel that use case, so I worry about misrepresenting/misunderstanding requirements, workflows, etc.

11:22 pdlogan: There's often a "tastes great / less filling" air to such things. :-)

11:22 pdlogan: cemerick: exactly so

11:30 nimred: when running M-x slime this is what i get : http://clojure.pastebin.com/CxSmy9zD

11:30 is it OK ?

11:31 cemerick: nimred: there is no progn in clojure

11:32 hrm, or funcall or read-from-string

11:32 apgwoz: cemerick: (defmacro progn [& body] `(do ~@body))

11:32 cemerick: nimred: Clojure is not a Common Lisp impl :-)

11:32 apgwoz: but, i digress

11:35 nimred: cemerick where does this progn come from ?

11:36 cemerick: nimred: oh, you're not inputting that?

11:37 nimred: of course not

11:37 ordnungswidrig: hi, did anybody implement aco in clojure? (ant colony optimization)

11:37 nimred: where did i say i was inputing it ?

11:37 apgwoz: nimred: that's from emacs

11:37 nimred: cemerick 18:07 < nimred> when running M-x slime this is what i get : http://clojure.pastebin.com/CxSmy9zD

11:38 cemerick i just ran M-x slime

11:38 apgwoz: nimred: can you paste your slime related emacs config?

11:38 nimred: and http://clojure.pastebin.com/CxSmy9zD is output following M-x slime...

11:38 cemerick: nimred: Clearly, I misunderstood you.

11:38 apgwoz: nimred: the better way might be to run swank elsewhere, say with lein swank and then do M-x slime-connect

11:38 nimred: cemerick sure anyway since yesterday nobody understand me here

11:39 cemerick: Plenty of people have come in asking why Clojure fails to run various CL programs, etc.

11:41 nimred: apgwoz trying what you suggest me --> Versions differ: 2010-11-07 (slime) vs. 20100404 (swank). Continue? (y or n)

11:41 apgwoz: it should be fine, so type y RET

11:41 nimred: when running M-x slime-connect once i ran lein swank in my test-program dir

11:41 amalloy: apgwoz: it doesn't actually wait for a RET

11:41 apgwoz: amalloy: fair enough :)

11:42 nimred: apgwoz Connected. May the source be with you!

11:42 apgwoz: nimred: excellent!

11:43 the only way to run M-x slime with clojure is to specifically set it up. Judging by the output you had, it looks like it's setup to run some common lisp

11:44 nimred: apgwoz no : isn't (setq inferior-lisp-program "~/.clojure/clj-env-dir") enough ?

11:44 apgwoz: i *don't think* so, but i could be wrong.

11:45 nimred: i find it more convenient to do slime-connect though, so..

11:45 nimred: apgwoz so which way to directly run slime with clojure ?

11:47 apgwoz: nimred: technomancy would know better, he the author of swank-clojure

11:48 s/he/he's/

11:48 sexpbot: <apgwoz> nimred: technomancy would know better, he's the's author of swank-clojure

11:52 nimred: is new clojure-contrib's ./modules/complete/target/complete-*.jar what old clojure-contrib's ./target/clojure-contrib*.jar was ?

11:57 is new clojure-contrib's ./modules/complete/target/complete-*.jar what old clojure-contrib's ./target/clojure-contrib*.jar was ?

11:58 Bootvis: (nth i [e1 ... en]) is O(1), right?

12:04 amalloy: Bootvis: well...yes, because it always throws an exception. but if you reverse the order of the parameters, i think it's log32(n), which is practically 1

12:05 nimred: is new clojure-contrib's ./modules/complete/target/complete-*.jar what old clojure-contrib's ./target/clojure-contrib*.jar was ?

12:08 amalloy: nimred: calm down. irc is not google - it may take more than five minutes for someone who knows the answer to your question to notice you've asked it

12:13 nimred: BSIYBGBA

12:13 Bootvis: amalloy: thanks

12:19 nimred: pppaul is new clojure-contrib's ./modules/complete/target/complete-*.jar what old clojure-contrib's ./target/clojure-contrib*.jar was ?

12:28 amalloy first time i asked this question is about 8 hours ago. Still no answer. Your 5 minutes are far aaway...

12:35 cemerick: nimred: complete-1.3.0-alpha3.jar (for example) is only 1.8K; there is no corollary to 1.2.0's contrib jar. complete (AFAIK) simply offers a way for maven/lein to transitively depend upon all of the separate module's artifacts.

12:37 nimred: why isn't there any more clojure-contrib.jar ?

12:37 cemerick: nimred: depending upon complete has the same effect

12:37 Although it's likely to go away eventually in the 1.3.0 cycle.

12:42 nimred: so what do i have to set emacs swank-clojure-extra-classpaths to ?

12:53 is swank-clojure-extra-classpaths recursive ?

12:55 can it be set to ~/opt/clojure-contrib or do i have to copy *.jar from contrib to some directory and set swank-clojure-extra-classpaths to this new directory ?

13:26 rata_: hi

13:29 jlaskowski: hi

13:29 where is definition of fn* in the source code?

13:29 I'm reading clojure/src/clj/clojure/core.clj

13:30 and spot fn* a few times

13:30 amalloy: jlaskowski: it's a primitive used by the compiler

13:30 mostly there's no reason for you to use it

13:30 same for let*, and mostly anything ending with * :P

13:30 jlaskowski: I can see it when macroexpand-all

13:31 amalloy: yes

13:31 but it does'

13:31 nt have any clojure code

13:31 it's all in java

13:31 jlaskowski: that's even better :)

13:31 amalloy: you can go looking in src/jvm

13:32 jlaskowski: got it

13:32 found it

13:32 jvm/clojure/lang/Compiler.java:static final Symbol FN = Symbol.intern("fn*");

13:32 amalloy: yep

13:32 jlaskowski: thanks amalloy

13:33 amalloy: if you try to read the compiler code you'll go blind, though :)

13:33 jlaskowski: I'm not sure I can go blind after having spent a couple of monads trying to figure out monads in Clojure :-)

13:34 chouser: what some call blindness, others call enlightenment

13:34 amalloy: spent a couple of monads?

13:34 jlaskowski: s/monads/months

13:34 sorry

13:34 vibrant: is it wise to hold maps in sets?

13:34 amalloy: heh, np

13:34 vibrant: i mean is it going to incur a lot of comparisons when there are many of them?

13:35 amalloy: vibrant: no, it shouldn't be a problem

13:35 jlaskowski: you see, I don't see a difference between monads and months :-0

13:35 amalloy: they're all hashtables, so as long as they're persistent maps/sets rather than the java.util modifiable kind it should be just as cheap as storing anything else

13:36 jlaskowski: thanks again for your help

13:36 * jlaskowski going back to reading the code

13:38 amalloy: does swank-clojure support jumping to the definition of a symbol? if so, what's the emacs keybinding for it?

13:39 replaca: amalloy: M-.

13:40 amalloy: sweet! it works, even when the symbol is defined in lib/someLibrary.jar

13:41 replaca: how about that! :)

13:44 rata_: what's the interface for that ability of vectors to be called as a fn giving them the index?

13:46 raek: rata_: IFn

13:46 or more accurately, clojure.lang.IFn

13:46 rata_: raek: but that's just to behave as a fn, not the ability to give them an index

13:46 I thought it may be ILookup

13:46 amalloy: rata_: that's what they do when called as a function

13:47 rata_: and what's ILookup?

13:47 amalloy: &(supers (class []))

13:47 sexpbot: ⟹ #{clojure.lang.IMeta clojure.lang.Seqable java.io.Serializable clojure.lang.IObj java.lang.Comparable java.util.RandomAccess clojure.lang.IFn clojure.lang.Indexed clojure.lang.APersistentVector clojure.lang.Associative java.util.concurrent.Callable clojure.lang.Reversible clojure.lang.IEditableColle... http://gist.github.com/668073

13:48 amalloy: rata_: that's used for (get vector index), i believe

13:48 cemerick: rata_: ILookup exists to support keyword lookups

13:48 rata_: and Indexed?

13:49 cemerick: introduced in particular for reification of fast keyword lookup of slots in defrecords

13:49 amalloy: rata_: clojure.lang.APersistentVector contains the actual code for looking up by index

13:49 cemerick: rata_: efficient random access

13:50 rata_: cemerick: that's what I need :)

13:50 amalloy: (it basically just delegates to nth, which is defined in PersistentVector

13:50 rata_: and every Indexed can be called as (obj index)?

13:50 defn: most mature rails-like framework for clojure at this point in time?

13:51 Conjure, maybe?

13:51 amalloy: defn: moustache? i don't know much about it or rails, but it always seems to cme up when people mention rails, so...

13:51 cemerick: rata_: No, only implementing IFn or some derivative allows you to treat an instance as a function like that

13:51 It just so happens that most Indexed collections are also fns.

13:51 rata_: Indexed then doesn't imply IFn?

13:52 cemerick: certainly not

13:52 rata_: ok

13:52 cemerick: Indexed only implies interop with nth

13:52 raek: moustache is a very neat Ring routing lib. I wouldn't call it a rails-like framework, but Ring + Moustache + Enlive covers the VC of MVC, I think

13:53 defn: yeah ive used moustache

13:53 im just looking for something more frameworky

13:53 i know...dirty word

13:53 raek: Conjure is the only one I'm aware of

13:53 defn: That was my understanding as well

13:54 fogus_: defn: Conjure is rated the most frameworky by a popular vote!

13:54 defn: just thought I'd ask around

13:54 fogus_: I'm a code archaeologist

13:54 fogus_: defn: yay! We need more of you.

13:54 defn: That's why I care about "scaffolding"

13:55 cemerick: (inc fogus_)

13:55 sexpbot: => 1

13:55 defn: haha oh god I forgot I suggested someone build a karma plugin

13:56 * defn takes full blame

13:56 amalloy: yeah, ivey put it in. bad defn

13:57 (dec defn) ; :)

13:57 sexpbot: => -1

13:58 amalloy: sexpbot: can't recognize a joke when you see one?

13:58 defn: :(

13:59 amalloy: (inc defn)

13:59 sexpbot: => 1

13:59 defn: :D

13:59 fogus_: (inc fogus_)

13:59 sexpbot: You can't adjust your own karma.

13:59 fogus_: Oh well

13:59 amalloy: wait what happened to 0? did someone silently inc him?

13:59 defn: (inc fogus)

13:59 sexpbot: => 1

14:00 amalloy: waittaminute, (inc) is using => instead of ⟹

14:03 $karma amalloy

14:03 sexpbot: amalloy has karma 0.

14:04 leifw: (inc sexpbot)

14:04 sexpbot: => 1

14:04 amalloy: heh

14:04 leifw: any change he's smarter than that? can I use proper functions?

14:04 *chance

14:04 amalloy: he's not

14:04 inc, dec, karma is all you get for the karma plugin

14:05 tonyl: ping

14:07 fogus_: $karma fogus_

14:07 sexpbot: fogus_ has karma 1.

14:07 fogus_: so cool

14:07 clojurebot: Gabh mo leithscéal?

14:09 tonyl: lol that is a nice tool

14:10 amalloy: $karma

14:11 tonyl: $karma amalloy

14:11 sexpbot: amalloy has karma 0.

14:12 pjstadig: $karma sexpbot

14:12 sexpbot: sexpbot has karma 1.

14:12 amalloy: tonyl: i deserve a (dec) for $karma. i was seeing if he'd barf on that. i suspect he threw a NPE, but of course he hides those if they're not in an eval

14:12 bhenry: how come it couldn't be (karma sexpbot) instead of the $ trick?

14:13 amalloy: bhenry: $foo is sexpbot's general syntax for commands. (inc|dec foo) is a convenient alias

14:13 $inc bhenry

14:13 sexpbot: => 1

14:14 tonyl: $inc sexpbot

14:14 sexpbot: => 2

14:14 bhenry: oh okay

14:15 is karma persistent or in memory?

14:15 danlarkin: this... is annoying

14:15 amalloy: bhenry: persistent

14:15 pppaul: $inc sexpbot

14:15 sexpbot: => 3

14:16 pppaul: what does karma do?

14:16 pjstadig: annoy people

14:16 tonyl: :P

14:16 amalloy: mostly, yeah

14:16 clojurebot: No entiendo

14:17 pppaul: it would be cool if clojurebot used Esperanto

14:18 tonyl: why?

14:18 clojurebot: http://clojure.org/rationale

14:19 pppaul: why not/

14:19 ?

14:19 $help

14:19 sexpbot: You're going to need to tell me what you want help with.

14:19 pppaul: $help getting women

14:19 sexpbot: Topic: "getting" doesn't exist!

14:20 tonyl: i'm just wondering about the specific language, why not japanese or italian?

14:20 pppaul: Esperanto!

14:21 an icon language would be cool too, but i don't know if it would display well

14:21 tonyl: hehe

14:21 pppaul: also, i would like to add broken-english to the languages clojurebot should speak

14:21 leifw: lol

14:21 tonyl: or pirate

14:25 pdlogan: I notice the java interop for a specific library has trouble resolving methods when using the double-dot shortcut ..

14:25 but rewriting them out more step-wise they resolve fine. is this a known problem (or feature)?

14:26 (the jericho html parser, if anyone's interested)

14:26 amalloy: pdlogan: that *shouldn't* be a problem, but .. is semi-deprecated now that we have ->

14:27 pdlogan: oh I see

14:28 pppaul: love the ->

14:28 amalloy: pdlogan: would you mind gisting a snippet that works with (.foo (.bar baz)) but not with (.. baz bar foo)?

14:29 pdlogan: umk the -> works fine

14:29 amalloy: sure

14:32 amalloy: ok - here's one https://gist.github.com/0b1de72a59cfd98deaf5

14:32 (note I've seen the same problem without the use of % though)

14:33 amalloy: pdlogan: when you're using .. you should use getX, not .getX

14:33 pdlogan: crikey - I knew that.

14:33 erk

14:33 been a while

14:33 hiredman: if the method name in the exception has a dot in it, that means you have too many dots

14:35 pdlogan: I welcome the ->

14:36 amalloy: yeah. -> and ->> are magic

14:36 vibrant: so.. what's the difference between refs and atoms?

14:36 pppaul: (doc atom?)

14:36 clojurebot: Pardon?

14:37 amalloy: vibrant: atoms are atomic only to changes from within the (swap!) function

14:37 pppaul: $dec clojurebot

14:37 sexpbot: => -1

14:37 vibrant: amallo; and refs can take part in transactions?

14:37 amalloy: vibrant: right, with (dosync)

14:37 tonyl: (doc clojure.inspector.atom?)

14:37 clojurebot: java.lang.ClassNotFoundException: clojure.inspector.atom?

14:37 vibrant: amallo; ok, so i need refs since i need to change multiple objects atomically. thanks.

14:38 pppaul: yup

14:38 amalloy: vibrant: right. or a single atom holding all the objects

14:38 pppaul: that's a big atom

14:38 amalloy: i stay away from refs when i can, personally, since atoms are cheaper

14:38 vibrant: yea it would be more fuss i guess.

14:38 i have to store a map of units, a map of players, and each player has a map of units inside him.

14:39 so i'd make each player a ref and each unit a ref i thought.

14:39 and the global maps would be refs too i guess.

14:39 amalloy: hrm. i'd make each map a ref, not each unit in the map

14:39 the fewer mutable things you have, the better :P

14:40 tonyl: ,(use '(clojure.inspector atom?))

14:40 clojurebot: java.io.FileNotFoundException: Could not locate clojure/inspector/atom?__init.class or clojure/inspector/atom?.clj on classpath:

14:40 leifw: maybe an agent?

14:40 vibrant: amalloy; ok but then if i have a map of units, and then a map of players, and i change a unit

14:40 then if a player in the other map also has that uniti

14:41 then those are two different units then right?

14:41 and i want to have one 'instance' of a unit and if i modify it i want it to change both in the global unit map and within some player's unit map (if that player has that unit)

14:42 or any better way to accomplish this?

14:42 leifw: then maybe each unit should be an atom

14:43 vibrant: leifw; yeah, but that could lead to some race conditions i guess. if i modify multiple units with regard to some events that happen and should be theoretically atomic.

14:43 leifw: then you don't need a transaction, you just swap a unit with an altered unit, and if both the global map and a player's map hold references to it, you're ok

14:43 vibrant: doesn't sound like a big problem though.

14:43 amalloy: vibrant: it's hard to design without knowing more about your layout. you want a global map describing unit types, and each player has a map of {unit-type. number} or something?

14:44 leifw: personally, I like working with agents a lot more

14:44 vibrant: amalloy; i want a global lookup table of units by ID so {id -> unit}, and each player owns multiple units so basically {id -> unit} too (for a subset of the global ids map)

14:44 leifw: I'd just model the whole game state as a single agent

14:44 well wait

14:45 then normalize your data: keep the global lookup table, and then for each player, just keep a set of ids

14:45 anonymou1e89: i'm trying to call a function after using load-file, if I don't know the namespace of the file that I'm loading beforehand what would be the way to call a function defined in that loaded file?

14:45 amalloy: vibrant: yeah, i agree with leifw here

14:45 vibrant: oh, sounds good.

14:45 leifw: that way you don't have the same unit referenced in two places

14:46 amalloy: and then you don't have any race conditions or synchronicty issues. you can use either an atom of a map, or a map of atoms

14:46 vibrant: ok so we went down to one atom for the big unit map, plus one atom for big players map, and each plaer keeps a set of IDs

14:46 leifw: I'm still not sure about your problem of modifying multiple units in a transaction

14:46 amalloy: you have a map of players too?

14:46 leifw: what sorts of modifications are we talking about here?

14:47 vibrant: leifw; if they're in one big unit map which is an atom then it's no longer a problem.

14:47 amalloy: leifw: not a problem if the whole unit map is a single atom

14:47 leifw: fair enough

14:48 vibrant: amalloy; yeah. the map of actual users playing the game.

14:48 each user can have multiple units.

14:48 tonyl: anonymoule89: clojure.contrib.ns-utils/get-ns

14:48 amalloy: vibrant: is that more or less a constant? or can users join/quit at will?

14:48 tonyl: maybe that would help

14:48 leifw: I assume the sets of units can change, can the units themselves change as well (like, I dunno, decrease HP or something)?

14:49 vibrant: amalloy; haven't thought about quitting but they can join for sure.

14:49 leifw; yeah they can change

14:50 in fact i might put all units and players and everything else into one big map.

14:50 which would be an atom.

14:50 i'd just have to give them unique IDs

14:50 or maybe not, since i wouldn't be able to iterate on them by type.

14:50 at least not efficiently.

14:50 pppaul: is the apply in clojure different from the apply in lisp?

14:50 hiredman: java.util.UUID

14:51 leifw: haha I would still use an agent for the whole game state, and then implement functions for it like (shoot [state unit1 unit2]) and (join [state player units])

14:51 ,(doc apply)

14:51 clojurebot: "([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."

14:51 vibrant: lefiw; yea but agents are asynchronous no?

14:52 leifw: yeah, but they process the events they receive serially

14:52 amalloy: yeah, an agent might not be such a bad idea here

14:52 leifw: it just makes sense to me that you'd have some sort of game state, which reacts to user events

14:52 nimred: has swank-clojure dead ?

14:52 leifw: having it in a separate thread is nice too, and if you use an agent, you don't even need to think about threading, but you get it

14:53 hiredman: well

14:53 with a single agent you don't have to think about threading because you are single threaded

14:53 vibrant: leifw; yeah but it's a game server which holds state for all clients.

14:53 leifw; and should update the state on-line i think.

14:54 leifw: vibrant: you can have your clients watch the agent

14:54 I dunno, you're building a game server, which is inherently an async object, why not model it with an async language construct

14:55 but I digress, an atom will work fine, though I suggest you look in to agents and decide if you like them any better

14:56 hiredman: the issue with using a single instance of a clojure reference type to hold all your state is you have a single timeline which means no concurrency

14:56 vibrant: leifw; i just finished reading that chapter in joy of clojure :)

14:57 hiredman: if you want to be cool and concurrent you must allow for simultaneity

14:57 vibrant: hiredman; yeah you're right. so i'd have to make separate atoms for each unit then.

14:58 hiredman: something like ants.clj

14:58 leifw: hiredman: I was thinking about that; I don't think there's much concurrency in this problem. As I understand it, he has a game state, which changes as the result of actions in the game, but these actions may involve complicated sub-parts of the game state, which we can't predict very well.

14:58 for example (I am picturing this as something like starcraft), a bomb goes off, and you want lots of units' HP to decrease at the same time

14:59 vibrant: leifw; well watching atoms would be nice though. each player would just watch the units in his viewport, and get notifications from Clojure itself without me interfering.

14:59 leifw: though things like unit movement should probably be concurrent

14:59 technomancy: nimred: swank-clojure.el is dead, yes.

14:59 hiredman: leifw: what if multiple players throw multiple bombs at once?

14:59 vibrant: leifw; and i'd just update the watched units as the player/units move.

15:00 worst part i'm using a java physics library right now. and it's a big clunky blackhole.

15:00 hiredman: leifw: with a single reference each bomb's effects are applied one after the other, in a linear ordering

15:00 leifw: I am mostly comfortable with those actions getting serialized, because it's unlikely that the users clicked at *exactly* the same time

15:01 or, in real life, it is unlikely that multiple bombs go off at exactly the same time

15:01 vibrant: well if it's a big bomb fight

15:01 then there will be a lot of bombs going off :)

15:01 leifw: I am liking this game more and more

15:02 can you just make bomberman please

15:02 ohpauleez: how far out is the decimal point on time? :)

15:02 vibrant: question is if the cost of maintaining those atoms for each unit outweighs the cost of lack of concurrency or not.

15:03 leifw; well i've waited 15 years to make this game so i'm not about to simplify it hehe

15:03 leifw: ooh, I am even more excited

15:03 so, here's a scenario:

15:03 hiredman: leifw: it's not about the bombs going off, it's about the effects of the bomb going off, the point is if you want an accurate simulation you cannot keep a single timeline

15:03 leifw: I throw a bomb, and you throw down some area-of-effect shield thing

15:04 vibrant: hehe

15:04 leifw: hiredman: sure you can, if you can process the events fast enough

15:04 hiredman: no

15:04 processing events quickly is not a substitute for multiple timelines

15:04 leifw: *we* have a single timeline, unless you're that deep in theoretical physics

15:04 hiredman: absolutely not

15:05 vibrant: leifw; if it's going to be a multiplayer server ran on a 16-core server

15:05 then hiredman has a point.

15:05 and if it's in Clojure on top of Java :)

15:05 so it'll have it's slowness.

15:05 hiredman: at this point I think my not arguing with idiots on the internet policy kicks in

15:06 leifw: sorry, I don't mean to argue, I actually want to know why multiple timelines are necessary

15:07 hiredman: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

15:09 cemerick: hiredman: just because someone is wrong or isn't convinced of something doesn't make them an idiot :-(

15:09 pppaul: really?

15:09 leifw: I've read this before

15:09 in general I agree, I just think this problem doesn't fit the model

15:09 hiredman: the proposition that processing events quickly is the samething as concurrently processing events does

15:10 leifw: suppose you throw a bomb and I throw some shield thingy around the same group of units

15:10 what you would like is for one of them to take effect on all those units before the other

15:10 hiredman: leifw: I meant it, I will no longer dicuss this topic with you

15:11 leifw: ok, fuck you too

15:11 hiredman: no need to get nasty

15:11 leifw: likewise

15:12 vibrant: my game is already causing controversy

15:12 hooray!

15:12 leifw: haha you win, vibrant

15:12 rata_: is there any way to know what ns$f$fn__955$fn__957$fn__959 in my code is?

15:12 leifw: rata_, nested anonymous functions inside ns/f

15:13 amalloy: rata: it's a closure inside ns/f

15:13 leifw's answer is better tho

15:13 pppaul: (doc eval)

15:13 clojurebot: DENIED

15:13 pppaul: ooooooh

15:13 (eval '(+ 1 2 3))

15:13 rata_: yes, but which one? is there any way to know which number is assigned for every anon fn?

15:13 pppaul: ,(eval '(+ 1 2 3))

15:13 clojurebot: DENIED

15:13 amalloy: rata_: no

15:14 give your anonymous functions names, and then you can: &|(fn a [])|&

15:14 sexpbot: ⟹ #<box4317$eval5884$a__5885 net.licenser.sandbox.box4317$eval5884$a__5885@157f347>

15:14 nimred: technomancy swank-clojure.el but not swank-clojure ?

15:14 rata_: ok

15:15 pppaul: nimred, did you get clojure working?

15:15 nimred: pppaul yes and no

15:15 pppaul: cool

15:15 nimred: technomancy then what is https://github.com/jochu/swank-clojure for ?

15:15 pppaul: it should work on the command-line at least. rlwrap clojure

15:16 leifw: anyway, vibrant, I'll continue my example, hopefully it'll be helpful to you: what I imagine is that you want either the bomb or the shield to happen first, for all of the affected units. If you opt for a concurrent approach, you will in that case want some sort of ordering on the events

15:17 so just...be careful

15:17 nimred: pppaul clojure itself works fine and has always worked fine for me

15:18 clojure withing emacs...

15:19 vibrant: leifw; yeah that's a good point, but this will be a game with conventional arms so i don't imagine any magical shields.

15:20 amalloy: vibrant: body armor, kevlar, tree cover...

15:20 leifw: nimred: as I understand it (which is probably completely wrong), swank-clojure.el is gone, but swank-clojure is still there. you use swank-clojure in your running clojure session (I usually just use lein swank), and then connect to it with M-x slime-connect using the traditional slime.el

15:22 technomancy: leifw: yeah, that's the idea

15:22 vibrant: amalloy; yea but if someone is wearing armor then it's not like he suddenly throws it on a number of units like in the shield example

15:23 leifw: vibrant: do you have any physics in this?

15:24 vibrant: leifw; yeah but i'm thining of throwing it away since it's top-down. and the whole value is in multi-player interactions (alliances, trade, etc. not only guns)

15:24 amalloy: vibrant: whatever. there are tons of examples where this sequentiality is useful. say you order your units to take cover from incoming gunfire, or something

15:24 apgwoz: technomancy: at the conj, you presented from emacs. what were you using?

15:25 technomancy: apgwoz: little lib called epresent; it's on my guthub account

15:25 works off org-mode docs

15:25 apgwoz: ah, nice.

15:25 i'll check it out

15:25 thanks

15:25 technomancy: it's kinda simplistic; may work if your formatting requirements are light.

15:25 * leifw should probably quit pestering vibrant so he can make the damn game already

15:26 tonyl: what stage is the game? I would like to test it, if it's possible

15:26 vibrant: leifw; hehe well i got a flying triangle shooting bullets at walls 2 days ago. but now it's only a triangle again and it's barely flying.

15:26 tonyl ^ read above :)

15:26 leifw: mraw :(

15:27 vibrant: but i moved to client-server architecture so that's the reason for the regression.

15:27 tonyl: :P offer still stands when you have something :)

15:27 vibrant: once i have players interacting somehow and chatting maybe i'll put it up as an applet.

15:27 anyone has experience with clojure in applets? :)

15:27 pppaul: nimred how long have you been using emacs?

15:28 i want some swank

15:30 nimred: pppaul as you should guess i am a beginner

15:30 apgwoz: technomancy: i don't have much in the way of formatting requirements, though I suppose there probably isn't a way to force monospace is there?

15:30 pppaul: nimred, i think emacs has a pretty high learning curve

15:30 apgwoz: oh wait. org-mode supports monospace, so it might work

15:31 nimred: pppaul what is a pretty high learning curve ? (sorry for my bad english)

15:31 pppaul: nimred getting clojure working in emacs is as simple as pointing the inferior-lisp var at how you run clojure on the command line (clojure), and then M-x inferior-lisp

15:32 technomancy: apgwoz: monospace (with font-lock of any arbitrary Emacs mode) is one of the few things that works great. =)

15:32 pppaul: emacs takes a while to learn, though

15:32 nimred: leifw are your settings somewhere ? (personnal page, github, bitbucket...)

15:32 apgwoz: technomancy: amazing

15:32 cemerick: nimred: what tools are you more familiar with?

15:32 apgwoz: technomancy: i'll certainly be taking a closer look under the hood here

15:33 technomancy: apgwoz: I'm not the original author, but I added the font-lock support and published it to the git hubs.

15:33 cemerick: nimred: There is clojure support for a variety of editors and IDEs: http://www.assembla.com/wiki/show/clojure/Getting_Started

15:33 leifw: nimred: I have my dotfiles on github, which includes my emacs dir

15:33 nimred: cemerick what do you mean writing "tool" ?

15:33 leifw: but...you probably don't want to look at it

15:33 vibrant: nimred; i'm using intellij IDEA with la clojure and it's pretty good.

15:34 cemerick: nimred: I mean…if you're more used to vi, eclipse, netbeans, intellij, or textmate, those might be a better fit for you than emacs (which seems to be giving you a fair bit of trouble)

15:34 technomancy: another option would be to follow the official instructions instead of some random blog you found =)

15:35 just throwing it out there

15:35 apgwoz: technomancy: yup, i think i encountered this a few years ago. i tried another one too (then) that didn't work very well

15:35 nimred: technomancy official only describes elpa way. I do not want elpa.

15:36 technomancy: ok, your choice.

15:36 nimred: be sure if official would have described from scratch i would have follow offical

15:37 leifw https://github.com/search?type=Users&language=&q=leifw+emacs&repo=&langOverride=&x=0&y=0&start_value=1

15:38 leifw: nope

15:38 pppaul: (doc apply)

15:38 clojurebot: "([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."

15:38 leifw: hold up, I'm pasting just the relevant bits

15:38 pppaul: why does apply have 3 args?

15:38 ,(apply + '(1 2))

15:38 clojurebot: 3

15:39 cemerick: pppaul: so you can provide optional individual args and then an argseq

15:39 ,(apply + 1 2 [3 4])

15:39 pppaul: oh

15:39 clojurebot: 10

15:39 nimred: leifw ?

15:39 leifw: nimred: here you go https://gist.github.com/668222

15:39 pppaul: i guess that is pretty common

15:40 leifw: those are just the clojure-relevant parts of my emacs dir

15:40 cemerick: technomancy: There's got to be a fable or saying to suit this. Somewhere between "give a man a fish…" and "beggars can't be choosers", or something. :-)

15:42 leifw: nimred: fair warning, I used elpa like the cool kids

15:42 (err, for most of it)

15:42 hiredman: ~#93

15:42 clojurebot: 93. When someone says "I want a programming language in which I need only say what I wish done," give him a lollipop.

15:43 cemerick: hiredman: where are those pulled from?

15:43 hiredman: http://www.cs.yale.edu/quotes.html

15:43 tonyl: ~#42

15:43 clojurebot: 42. You can measure a programmer's perspective by noting his attitude on the continuing vitality of FORTRAN.

15:43 cemerick: hiredman: this'll be good, thanks :-)

15:44 nimred: leifw :/

15:44 looks like there is not a lot of emacs user there...

15:44 leifw: actually, no, I used elpa for everything but clojure stuff, for whatever reason the elpa packages were old when I set this up and I haven't fixed them

15:44 cemerick: I think Peter Norvig has a bunch of quotables like this somewhere on his site as well.

15:44 hiredman: https://github.com/hiredman/clojurebot/commit/cffd9b688b6b2f0a8a07c12a42d2dda14d7c17ed#L1R16 very literally pulled from there

15:45 leifw: so, yeah, go use that if you must not have elpa

15:47 fogus_: Just learned that you can directly destructure a Matcher... I just can't seem to get it to work. :-(

15:47 apgwoz: fogus_: does it destructure into the matched groups?

15:48 fogus_: Seems to... but alas

15:48 hiredman: interesting

15:48 wonder how thats done, Matcher doesn't implement any of the interfaces

15:48 amalloy: fogus_: really?

15:49 pdlogan: ~#11

15:49 clojurebot: 11. If you have a procedure with ten parameters, you probably missed some.

15:49 apgwoz: ah, it works with re-matches

15:49 pppaul: LOL @#11

15:49 fogus_: hiredman: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L731

15:49 pdlogan: (reminds me of get. oops. did I jusst say that out loud?)

15:49 er, git

15:49 pppaul: !#1

15:49 pdlogan: oops

15:49 hiredman: huh, neat

15:49 pppaul: ~#1

15:49 clojurebot: 1. One man's constant is another man's variable.

15:49 apgwoz: ,(let [[a b] (re-matches #"(\d+) (\d+)" "12 34")] (prn a) (prn 2))

15:49 clojurebot: "12 34"

15:49 2

15:50 hiredman: (doc re-matches)

15:50 pppaul: apqwoz, what are you aiming for?

15:50 clojurebot: "([re s]); Returns the match, if any, of string to pattern, using java.util.regex.Matcher.matches(). Uses re-groups to return the groups."

15:50 apgwoz: ,(let [[a b] (re-matches #"(\d+) (\d+)" "12 34")] (prn a) (prn b))

15:50 clojurebot: "12 34"

15:50 "12"

15:50 amalloy: re-matches returns a vector, so this isn't surprising

15:50 apgwoz: amalloy: true :)

15:50 pppaul: re-seq

15:50 fogus_: apgwoz: what amalloy said

15:51 hiredman: what in clojure returns a Matcher?

15:51 fogus_: ,re-matcher

15:51 clojurebot: #<core$re_matcher clojure.core$re_matcher@8f3052>

15:51 amalloy: &(re-matcher #"\d+" "blah 1")

15:51 sexpbot: ⟹ #<Matcher java.util.regex.Matcher[pattern=\d+ region=0,6 lastmatch=]>

15:51 hiredman: (doc re-matcher)

15:51 clojurebot: "([re s]); Returns an instance of java.util.regex.Matcher, for use, e.g. in re-find."

15:52 fogus_: ,(let [[date d m y] (re-matcher #"(\d{1,2})\/(\d{1,2})\/(\d{4})" "12/02/1975")] [date d m y])

15:52 clojurebot: java.lang.IllegalStateException: No match found

15:53 fogus_: HRPMH! Seems like that should work

15:53 apgwoz: but how is that any different than using re-matches?

15:53 amalloy: fogus_: matcher doesn't do a find until you tell it to

15:53 fogus_: apgwoz: That particular example would not, but the general case would be nice

15:54 apgwoz: fogus_: are you thinking maybe about named groups?

15:54 in which case you could use the keyword destructuring, etc?

15:55 amalloy: ,(let [[date d m y] ((comp re-find re-matcher) #"(\d{1,2})\/(\d{1,2})\/(\d{4})" "12/02/1975")] [date d m y])

15:55 clojurebot: ["12/02/1975" "12" "02" "1975"]

15:55 amalloy: fogus_: ^^?

15:55 fogus_: whoa!!!

15:55 hiredman: java regexes don't have named groups

15:55 fogus_: hmmm, but re-find returns a vector

15:56 apgwoz: hiredman: not according to the docs for Pattern \k<name>

15:56 hiredman: though, i'm looking at java 7's docs, so it's being added :)

15:56 amalloy: ,(let [[date d m y] (doto (re-matcher #"(\d{1,2})\/(\d{1,2})\/(\d{4})" "12/02/1975") re-find)] [date d m y])

15:56 fogus_: , (let [[date d m y :as foo] ((comp re-find re-matcher) #"(\d{1,2})\/(\d{1,2})\/(\d{4})" "12/02/1975")] foo)

15:56 clojurebot: ["12/02/1975" "12" "02" nil]

15:56 ["12/02/1975" "12" "02" "1975"]

15:57 hiredman: apgwoz: sure, when ever that gets released

15:57 amalloy: fogus_: hey you're right, it works on the re-matcher

15:57 apgwoz: well, then i'm still stumped at what composing re-find and re-matcher gets you over re-matches

15:58 in terms of destructuring

15:58 amalloy: apgwoz: lets you reuse the matcher to find all matches in the string

15:58 i suspect is what fogus_ is looking for

15:59 vibrant: this java lib is so annoying. any clojure lib for geometry/collision detection?

15:59 apgwoz: well, yes, re-matcher would give you a "compiled" regex to reuse. of course

15:59 amalloy: apgwoz: not just that. re-matches will only find the first match in a string

16:00 woodworm`: hi

16:00 amalloy: re-matcher will iterate through all matches in a string with repeated calls to re-find

16:00 apgwoz: ah, so it's more like an iterative search

16:00 amalloy: maybe. i dunno what fogus wants it for, but you asked what you gain: this is it

16:01 apgwoz: amalloy: right. i know i asked. thanks for explaining.

16:01 fogus_: I just want to see if it works. :p

16:01 vibrant: leifw; u dead?

16:02 woodworm`: I have a set with a single element which is an instance of a record. contains? on it returns false when it should return true. I can see that equals (=) returns true and hash is also the same (on the element and my look up key). .contains works as expected. The funny thing is, I cant reproduce this problem in isolation. Any ideas on what the issue is?

16:04 amalloy: woodworm`: why are you using contains? on a set? just call it directly: &|(#{5 1} 5)|&

16:04 sexpbot: ⟹ 5

16:04 leifw: vibrant: yeah I was on email for a bit

16:04 what's up

16:04 I am also about to go get some food

16:04 vibrant: leifw; http://briancarper.net/blog/520/making-an-rpg-in-clojure-part-one-of-many

16:04 about agents and refs etc.

16:06 leifw: this is not you, I take it

16:07 ok

16:07 vibrant: no, i didn't manage to put together a 20 page article in 10 minutes hehe

16:07 leifw: yeah, I see the problem

16:07 amalloy: is there a way to use {:keys [blah]} sorta in reverse? eg i have 4 locals, and want to create a map whose keys are the keyword-ized names and values are the current local values?

16:08 leifw: I think if instead of lots of agents banging on a single ref, you have the whole game as one agent that gets sent messages from a bunch of places, maybe it wouldn't be so bad?

16:08 dunno

16:08 amalloy: such a macro looks fairly easy, but i don't want to write it if it already exists

16:08 fogus_: amalloy: It worked like you hinted earlier: https://gist.github.com/668275

16:08 leifw: I've got to go though

16:08 hope it works out well for you

16:08 and uhh, find me at some point when you finish it

16:09 vibrant: ok, cu.

16:09 amalloy: fogus_: cool. i'm as pleased as you are to find that you can destructure Matcher objects

16:10 fogus_: Although the mutable tidbit is hideous!

16:11 amalloy: yessss

16:11 fogus_: but that's what re-seq is for

16:11 woodworm`: amalloy: thanks for the suggestion.

16:12 fogus_: amalloy: Right. JoC actually mentions to avoid using Matchers directly... this is one more reason to do so.

16:12 amalloy: yeah

16:21 rata_: someone sees why I'm getting a StackOverflow here? https://gist.github.com/668294

16:21 or as an added question, does anyone know how to improve the performance of that function?

16:22 (the "complex" fn doesn't take long to run)

16:23 bobo_: rata_: you should probably use loop/recur instead for recursion

16:23 or wait, i was confies by the names

16:23 rata_: I'm using loop/recur

16:23 :)

16:23 bobo_: get-complex != get-complezes

16:25 rata_: yes

16:27 nimred: which way to not display this annoying message in minibuffer "Polling "/home/nimred/tmp/slime.6853".. (Abort with `M-x slime-abort-connection'.)" ?

16:33 ohpauleez: rata_: You must be holding on to head somewhere, but I'm not spotting it

16:33 Just looking over the gist, things look ok to me

16:33 amalloy: ohpauleez, rata_: same here

16:33 looks fine but must be holding onto head

16:33 ohpauleez: to speed it up, you can use transients as long as this stays pretty isolated

16:34 ie: if you're just building up groups, totally go for transients

16:34 rata_: if I'm calling get-complexes from the REPL, am I holding onto head?

16:34 devinus: has there been any work porting clojure to VMKit ?

16:35 rata_: ohpauleez: I'm just building groups... how do I use transients?

16:35 devinus: supposedly VMKit runs eclipse already

16:35 ohpauleez: rata_: https://gist.github.com/594584

16:35 look at step-seq!, which is pretty similar to your call

16:36 essentially change the let to 'transient', change conj to conj! and add persistent! to your if statement

16:37 cemerick: fogus_: do you know the rationale for Matchers being destructurable? That just seems like a bad idea…?

16:37 ohpauleez: If that still isn't fast enough ping me

16:37 rata_: ok, done it :)

16:37 ohpauleez: rata_: pretty easy, right?

16:37 :)

16:37 rata_: yes :) I like it

16:37 technomancy: rata_: you were asking about telling apart compiled representations of functions; https://github.com/Seajure/serializable-fn may interest you

16:38 tonyl: ping?

16:38 clojurebot: PONG!

16:38 rata_: technomancy: I'll check it. thanks :)

16:38 ohpauleez: but I still have the StackOverflow problem

16:39 ohpauleez: Yeah, I can't spot it. It might be the REPL

16:39 rata_: I thought using tail-recursion with loop/recur could never produce a StackOverflow

16:39 amalloy: rata_: ot cam

16:39 bah

16:39 it can't

16:40 so something you're doing inside the loop must be doing it, or else the repl trying to show it might be

16:41 rata_: then I don't get what's wrong here... I'm just calling get-complexes from the REPL, that's all

16:41 ohpauleez: rata_: How big is the collection you're passing to it?

16:42 amalloy: rata_: if the collection is super-huge, then last-complex might be overflowing

16:42 rata_: ohpauleez: it's a map of 1000 key-value pairs

16:43 amalloy: how might it be doing that?

16:43 ohpauleez: hmm, that's not too big. But I suspect you're holding on to a head reference somewhere. I can't spot it, but that is a common cause of this problem

16:43 nimred: leifw what does ~/.clojure/ext content ?

16:43 amalloy: a lookup in the set could be traversing a tree. but i don't think 1k should be a problem at all

16:44 rata_: amalloy: in this case last-complex has always just one Integer within the set

16:45 ohpauleez: holding onto the head here shouldn't be a problem, as the fn is using loop/recur and that's a problem for lazy seqs... isn't it?

16:46 ohpauleez: let me pull your gist back up, hang on

16:47 rata_: the maximum input is a map with 977 key-value pairs

16:48 more than that is an stack overflow

16:48 ohpauleez: where did you find that?

16:49 rata_: calling the fn from the repl with different inputs

16:49 ohpauleez: well, that's sort of awesome because here's why...

16:50 split the collection in half, and process on two threads, then join the results

16:50 or use a lazy-seq

16:50 (assuming you have a function to generate the map for you

16:50 )

16:51 rata_: yes, I have a fn to generate the map

16:51 ohpauleez: also, you might find a speedup in chunk-rest over rest, not too sure

16:51 rata_: btw, it's amazing the difference between this fn and what it was half an hour ago... 7400 msecs vs 1200 msecs

16:51 ohpauleez: awesome! glad to hear it!

16:51 rata_: :)

16:54 the problem with splitting the collection in half is that "agents" that belong to the same complex can stay in different halfs

16:54 (what's the right word for "stay" there?)

16:55 tonyl: delay?

16:56 rata_: anyway, I could split it and give the whole expr to both, then join the results and use distinct to remove the duplicated complexes

16:57 even so, the stack overflow problem remains

17:02 vibrant: how to return non-nil values from a sequence?

17:03 bhenry: (remove nil? your-sequence)

17:03 vibrant ^

17:04 ,(remove nil? '(1 nil 2 nil 3 nil 4 nil))

17:04 clojurebot: (1 2 3 4)

17:04 alpheus: ,(filter identity '(1 nil 2 nil 3 nil 4 nil))

17:04 vibrant: thx

17:04 rata_: or (keep identity coll)

17:04 clojurebot: (1 2 3 4)

17:05 vibrant: oh yea, keep is sexy

17:05 tonyl: indeed

17:06 amalloy: rata_: you could improve your code a bit by using when instead of if when there's no else clause, and by using (or x y) instead of (if x x y)

17:06 neither of those should fix your problem but they'll make it nicer

17:08 rata_: amalloy: but I don't have any if there without else clause

17:08 vibrant: anything like map-non-nil which maps and only returns non-nil values from the func that is mapped?

17:09 amalloy: oh wow, so you don't. writing (if (cond) (then) (else) with no newline after (cond) is really confusing

17:09 rata_: vibrant: keep

17:09 vibrant: rata; hah :)

17:09 now it's even more sexy.

17:10 amalloy: rata_: using (empty?) is also discouraged; i'd use (if (seq remaining) (let...) groups)

17:11 rata_: amalloy: yes... I'm used to writing it so when the then clause is a small form

17:11 amalloy: rata_: i mean, that's not a crime, but it certainly confuses the heck out of me

17:12 rata_: amalloy: why is it discouraged? it's very descriptive and has no performance problem

17:12 amalloy: using empty?

17:12 rata_: yes, using (if (seq ...) ...) isn't very descriptive

17:13 ohpauleez: I think it's discouraged if what you're really expecting is nil, and then you should use nil?

17:13 amalloy: rata_: http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/empty?

17:14 rata_: I'm expecting '(), because remove and rest return '()

17:14 Raynes: Is there a map function that maps into subsequences? (sub-map (partial + 3) [1 2 [3 4]]) -> [4 5 [6 7]]

17:14 bhenry: amalloy: rata_ i think (not (empty? …)) is discouraged, but empty? alone is fine.

17:14 Raynes: That would be so useful.

17:15 bhenry: Raynes: write it. : P

17:15 Raynes: :p

17:16 rata_: does anybody else know why this isn't tail-recursing? https://gist.github.com/668294

17:16 bhenry: i wrote this to map keys in nested maps. https://gist.github.com/662618

17:16 don't know if it's any good, but it works

17:17 rata_: lazy-seq works with transients?

17:17 pppaul: maybe use next, rata_

17:18 rata_: but next returns nil instead of '()

17:18 pppaul: yeah

17:18 i thought that was what you wanted

17:18 i dono, i just joined so i don't know what the conversation is about %_%

17:18 rata_: no, I like '()

17:18 pppaul: https://gist.github.com/668294

17:19 what does chunk-rest?

17:22 does lazy-seq work with transients? or is it unsafe?

17:28 ohpauleez: with lazy-seq it doesn't stack-overflows and it runs in just 19 millisecs! that's impressive!

17:28 no, wait

17:29 ohpauleez: that sounds like you have no data

17:29 double check

17:30 rata_: yes, a zero was missing... it was just a map with 100 key-value pairs

17:30 with 1000 it still overflows

17:30 vibrant: how to return a seq with the first element copied to the end of it? like [1 2 3 4] -> [1 2 3 4 1]?

17:32 oh ok, concta

17:32 rata_: vibrant: one way could be (concat coll [(first coll)])

17:32 vibrant: cat

17:32 yea just found this obvious answer :) i was trying to use into but that prepended for a list.

17:33 Chousuke: don't use that too much though

17:33 you'll blow your stack :P

17:33 vibrant: (defn points->lines [pointseq]

17:33 (partition 2 (interleave pointseq (concat pointseq [(first poitseq)]))))

17:34 i'm converting a list of points defining a polygon to a list of lines

17:34 err rest pointseq should be there

17:34 Chousuke: seems fine then

17:35 rata_: I've appended the lazy-seq version... both overflow :(

17:35 https://gist.github.com/668294

17:35 vibrant: it's damn elegant, Clojure is

17:36 rata_: vibrant: yes :)

17:36 the lazy-seq version is just a bit slower than the one using transients, but I think I prefer the lazy one

17:36 vibrant: hm.. apply doesn't work with Java static methods?

17:37 rata_: but the stack overflow is still there

17:37 ohpauleez: rata_: I too like using laziness. It looks logical and concise

17:38 rata_: yes

17:38 apgwoz: technomancy: do you know if tables work in epresent?

17:38 ohpauleez: rata_: http://georgejahad.com/clojure/cdt.html

17:38 pppaul: has anyone used {:test ...} and (test ...)?

17:39 ohpauleez: With the laziness you definitely shouldn't be getting overflows

17:39 I'm at work and have to finish some things up, but if you push this entire thing to github, feel free to ping me

17:39 (in case you don't figure it out)

17:40 apgwoz: technomancy: nevermind, doesn't look like it. seems to be psuedo org-mode syntax

17:40 rata_: ohpauleez: the entire thing is in github... this is part of a library I'm developing

17:40 ohpauleez: link me

17:40 rata_: and it doesn't has to do with holding onto the head, because it overflows with dorun too

17:41 http://github.com/rhz/kapjure

17:41 sorry... you need the line

17:42 ohpauleez: https://github.com/rhz/kapjure/blob/master/src/kappa/language.clj#L60

17:42 ohpauleez: thanks

17:43 rata_: that's the old version though... the super-slow one

17:43 ohpauleez: keep poking at it, and I'll ping you later when I'm back in commission to see where you are with it

17:43 rata_: ok, thank you a lot :)

17:45 leifw: oh here's something that's bugged me for some time now

17:45 if I define a function with :pre and :post conditions, is there a way to disable them when I want code to run fast?

17:46 for example, I have some math utilities that I gave pre and post conditions to check my sanity, but they get run extremely frequently, and those conditions make up a significant overhead

17:47 short of commenting them out and re-evalling them, is there something like *warn-on-reflection* I can change that will affect the interpreter that way?

17:47 vibrant: any clean way to circumvent the fact that apply doesn't work on java static methods?

17:47 leifw: vibrant: example?

17:47 vibrant: leifw; it should work?

17:48 leifw: dunno, what's the error you get?

17:48 I was just going to try what you're trying myself

17:50 pdlogan: leifw: you probably have to wrap the java method invocation in a function.

17:50 * pdlogan trying...

17:50 vibrant: Caused by: java.lang.Exception: Unable to find static field: linesIntersect in class java.awt.geom.Line2D

17:51 I guess it doesn't know which one to pick since there are many methods with that name

17:51 just different signatures

17:51 ohpauleez: leifw: There is another contract library around somewhere on github, because of these issues and a few others with :pre and :post. I haven't used it, but I've looked through it

17:52 leifw: yeah, I think you need to wrap it in something that calls linesIntersect in first position with all positional arguments present, so it can determine which one to select

17:52 ohpauleez: fogus_'s trammel: https://github.com/fogus/trammel

17:53 it essentially decouples the contracts from the function

17:53 leifw: so (apply (fn [l1 l2] (Line2D/linesIntersect l1 l2)) lines)

17:53 ohpauleez: which is nice

17:53 leifw: which isn't really as nice as you'd hope

17:53 ohpauleez: leifw: ^^

17:53 leifw: maybe (defmacro apply-static [f & more] ...)

17:53 Chousuke: noooooooooooooooooo

17:54 leifw: if you expand the apply at macro expansion, maybe it works?

17:54 Chousuke: apply can't be expanded

17:54 leifw: ohpauleez: thanks, I'll look

17:54 pppaul: apply-macro

17:54 (doc apply-macro)

17:54 clojurebot: Huh?

17:54 Chousuke: unless maybe if you have a literal vector

17:54 which makes the apply pointless

17:54 leifw: yeah I guess so

17:55 well

17:55 Chousuke: anyway, hm

17:55 vibrant: pppaul; looks nice :)

17:55 leifw: using the anonymous function wrapper is the only correct way I can think of, in that case

17:55 Chousuke: you can always wrap that method in a named function

17:55 tomsw: Evening all. Does anyone know if it's possible to create a class with gen-class with some state accessible to all instances?

17:56 Chousuke: or destructure the line vecotr and call the static method afterwards

17:56 leifw: ohpauleez: do you have a link?

17:56 pppaul: apply-macro is my favourite!

17:56 ohpauleez: leifw: It's up above (fogus_'s trammel: https://github.com/fogus/trammel)

17:57 leifw: oh haha did not see that

17:57 thanks

17:57 ohpauleez: np :)

18:01 vibrant: humm.. so how do i return a vector from an anonymous function? this doesn't work, treating the vector as a function #([(.x %) (.y %)])

18:01 Derander: vibrant: (vec [2 3])?

18:02 leifw: vibrant: #(identity [elem ents])

18:02 or that

18:02 vibrant: oh yea just guessed hehe

18:02 Derander: identity is probably better

18:02 but I dunno

18:02 leifw: I seem to remember identity being suggested as idiomatic, but both work fine I'm sure

18:02 tomsw: (constantly [a b c])?

18:02 leifw: hah nice

18:02 Derander: ,(constantly [1 2 3])

18:02 clojurebot: #<core$constantly$fn__3551 clojure.core$constantly$fn__3551@1eee6b2>

18:03 leifw: ignores arguments though

18:04 romain_p: Hi, can someone tell me what is wrong with the following:

18:05 tomsw: oops. how about #(do [ ... ])? It's short (although sounds too imperative)

18:05 romain_p: (defn make-lines [data]

18:05 "Generates a collection of svg line elements based on the supplied data points"

18:05 (for [idx (count data)

18:05 prev-val (nth data idx)

18:05 this-val (nth data (inc idx))

18:05 :when (and prev-val this-val)]

18:05 (make-line idx prev-val (inc idx) this-val)))

18:05 leifw: romain_p: paste it please

18:05 err, pastebin it please

18:05 romain_p: leifw: ok, will do

18:06 leifw: romain_p: but I think, if make-line is something you expect to run (and it isn't running), you're being bitten by the fact that for is lazy

18:06 romain_p: wrap it in dorun or something to force it to execute

18:06 vibrant: i want to implement nth for an arbitrary java class, is there some protocol already containing nth or should i write one?

18:06 romain_p: the error I get is "cannot create ISeq from Integer" or something

18:07 leifw: romain_p: you want [idx (range (count data)) ...]

18:07 KirinDave: chouser: You around?

18:09 romain_p: leifw: really? I just wanted an index

18:09 leifw: the for loop is going to try to iterate over (count data), which is an integer

18:10 romain_p: leifw: i copied the whole source over at http://pastebin.ca/1985803

18:10 leifw: OK

18:11 vibrant: wow, my nth is overriding the orginal one.

18:11 leifw: I expect you want this: https://gist.github.com/668451

18:11 ,(doc for)

18:11 clojurebot: "([seq-exprs body-expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of e...

18:12 vibrant: http://pastebin.ca/1985804 any idea how to make (nth Vec2instance) work if Vec2 is a Java class?

18:12 leifw: romain_p: "binding-form/collection-expr pairs"... every other element in the for loop's binding forms vector needs to be a collection

18:13 hiredman: vibrant: you can't

18:13 romain_p: leifw: I want almost this, but not quite.

18:13 hiredman: nth works on certain interfaces, and certain classes

18:13 romain_p: I need the :when test to avoid an OOB exception

18:13 vibrant: hiredman; oh, shitty. so any elegant way to make it 'just work'? or do I have to convert manually if I want to use it in place of a vector?

18:14 romain_p: (or do I?)

18:14 hiredman: if you have control of the java class you can have it extend one of the interfaces

18:14 leifw: romain_p: just don't let idx range that far?

18:14 hold on there's a better way to do this

18:15 vibrant: hiredman; well.. i don't want to butcher java classes. i thought it'd be possible to do it externally after reading a bit about protocols. so i'll just convert i guess.

18:15 hiredman: nth is not a protocol yet

18:15 vibrant: ok

18:18 romain_p: leifw: tx, that does it (of course if you have a more elegant solution...)

18:18 leifw: I'm working on it, I forgot the name of a function but I'll have a more elegant one soon

18:20 romain_p: https://gist.github.com/668451

18:21 partition does what you want

18:21 actually, I'm missing the rebinding and the index, just a sec

18:22 romain_p: ,(doc partition)

18:22 clojurebot: "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a ...

18:23 leifw: all better

18:23 refresh that page

18:24 technomancy: partition's docstring needs "you probably want partition-all" appended to it

18:24 romain_p: leifw: OK, I refreshed it.

18:24 leifw: oh right, partition won't return the last thingy, you can drop that :when condition

18:25 in this case, you *do* want partition, not partition-all

18:25 romain_p: Now I'll need to spend some time with the docs :_

18:25 :)

18:25 thanks, it's much terser anyway

18:25 leifw: refresh one more time, should still work

18:26 technomancy: wow, an actual use case for partition... first time for everything I guess =)

18:26 leifw: heh technomancy :)

18:26 Derander: partition is my new inject

18:26 I'm trying to find a use case for it and I don't fully understand it

18:26 inject == reduce*

18:26 as soon as I find one I'm sure everything will look like a candidate for parttion

18:27 leifw: I've really only used it with interleave to create what I usually know as zip

18:27 romain_p: leifw: yup, still works

18:27 leifw: sweet

18:28 clojure has this annoying quality where it thinks "zip" is something totally different from what I think it is

18:28 romain_p: gotta get some shut-eye, but thanks a lot!

18:29 Derander: ,(partition 2 [1 2 3 4)

18:29 clojurebot: Unmatched delimiter: )

18:29 Derander: ,(partition 2 [1 2 3 4])

18:29 clojurebot: ((1 2) (3 4))

18:29 Derander: ,(partition 2 2[1 2 3 4 5 6])

18:29 clojurebot: ((1 2) (3 4) (5 6))

18:29 Derander: ,(partition 2 2 [1 2 3 4 5 6])

18:29 clojurebot: ((1 2) (3 4) (5 6))

18:29 Derander: ,(partition 2 3 [1 2 3 4 5 6])

18:29 clojurebot: ((1 2) (4 5))

18:29 Derander: huh. interesting

18:29 leifw: ,(partition 3 2 [1 2 3 4 5 6])

18:30 clojurebot: ((1 2 3) (3 4 5))

18:30 vibrant: wow this is elite, i just wrote a ray caster to detect line-of-sight in 20 lines of code, as opposed to a version I saw in Java in 100 lines.

18:30 leifw: ,(partition 3 2 [1 2 3 4 5 6 7])

18:30 clojurebot: ((1 2 3) (3 4 5) (5 6 7))

18:33 Derander: I am le tired

18:33 studybot_: ,(partition 2 3 [1 2 3 4 5 6])

18:33 clojurebot: ((1 2) (4 5))

18:35 leifw: Derander: me too, might have something to do with this class though

18:35 Derander: I just never sleep :P

18:40 Wilduck: So, I just picked up "joy of clojure" and got to the section on the .. macro, but someone mentioned it was deprecated. Should I ignore this section then?

18:40 KirinDave: chouser: Ping?

18:41 leifw: Wilduck: yes, -> is better

18:41 ,(doc ..)

18:41 clojurebot: "([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on t...

18:41 Wilduck: I guess I have to wait untill chapter 8 to learn about this then...

18:42 Derander: ,(doc ->)

18:42 clojurebot: "([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts ...

18:43 Derander: ,(doc ->>)

18:43 clojurebot: "([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the fi...

18:49 KirinDave: Hum

18:49 Anyone here use error-kit?

18:49 I'm having a weird error with it.

18:50 ohpauleez: KirinDave: Ironic isn't it. I have indeed used it, but have moved to using conditional

18:51 KirinDave: ohpauleez: Conditional?

18:51 ohpauleez: condition*: http://richhickey.github.com/clojure-contrib/condition-api.html

18:51 it's sort of a round 2 for error-kit

18:55 technomancy: it's more like round 2 for exceptions

18:55 KirinDave: Which is preferred?

18:55 And more importantly, does it have something like continues?

18:55 That's something I use heavily

18:55 ohpauleez: but with lessons learned from error-kit

18:56 hiredman: KirinDave: condition lets you catch and throw maps, basically

18:56 KirinDave: hiredman: But can you continue from the point of a raise?

18:56 In other words, can you have error handling strategies at the point of the rase?

18:57 hiredman: KirinDave: you can throw a map that contains a function to continue at if you would like

18:57 pppaul: ,(testing-vars-str)

18:57 clojurebot: java.lang.Exception: Unable to resolve symbol: testing-vars-str in this context

18:57 hiredman: it doesn't have built in functionality for it

18:58 KirinDave: hiredman: But that's the most awesome part of error-kit, and common-lisp style exceptions in general.

18:58 hiredman: *shrug*

18:58 pppaul: common lisp is going to hell

18:59 KirinDave: pppaul: So? That doesn't mean it isn't full of awesome stuff.

18:59 pppaul: yes

18:59 the hell of awesome

19:00 KirinDave: hiredman: I take it you've never used them.

19:00 LOPP: I <3 CL :P

19:00 KirinDave: hiredman: Even you can't be such a hater as to dismiss that power. It's pretty effin' incredible.

19:01 hiredman: as I said, you if you want to throw a continuation you can

19:03 technomancy: KirinDave: yeah, c.c.condition is not as ambitious as error-kit. on the other hand, it's more accessible, and a lot more people use it.

19:04 according to rich's conj talk, rebinding some kind of error-handler var is "good enough" to for most use cases of CL restarts.

19:04 KirinDave: technomancy: I'm glad to hear that.

19:04 technomancy: I was worried I agreed with Rich too much. :)

19:04 technomancy: hah

19:05 hiredman: I don't recall rich saying that

19:05 KirinDave: You can make a strong argument that separating handlers and continues is demonstrably better than classical error handling.

19:05 hiredman: I recall him saying that error handling was one of his envisioned use cases for dynamic vars

19:07 KirinDave: But I suppose having that power is unfamiliar and most people have their hands full not programming java-in-clojure.

19:09 hiredman: you can (binding [*handle-error* some-logging-function] (try .. (catch Exception e (*handle-error e))))

19:09 then any place inside the try set! *handle-error*

19:09 KirinDave: hiredman: But that means you're putting the logging/handling stuff up there at the top.

19:09 And yes, but why not formalize that to continues?

19:09 hiredman: you could

19:10 KirinDave: hiredman: So why do people seem to think that's not an awesome idea?

19:10 hiredman: *shrug*

19:59 Raynes: sexpbot: kill

19:59 sexpbot: KILL IT WITH FIRE!

20:02 pppaul: :)

20:02 rata_: how do I get a chunked seq from a non-chunked seq?

20:06 Derander: I have a hash map that goes {html-element html-element's-children, anotherone-..}

20:06 my goal is to get a list of html-elements whose children pass a filter

20:07 how should I go about this?

20:07 actually, I think I can do this better.

20:07 tomoj: rata_: why do you want to do that?

20:07 Derander: are you parsing html on your own?

20:07 clojurebot: Gabh mo leithscéal?

20:07 rata_: tomoj: to see if that increases performance

20:08 Derander: tomoj: well, I have a dOM

20:08 DOM

20:08 tomoj: I see

20:08 do you already know about the xml-zip stuff?

20:09 Derander: I do not understand zippers well enough to work with them

20:09 tomoj: right

20:09 well

20:09 as it happens

20:09 there's also zip-filter

20:09 Derander: yes

20:09 tomoj: which saves you from low-level zip work

20:09 Derander: I tried using zip-filter on an xml-zip of an html page

20:09 tomoj: right, it's really quite nice

20:09 Derander: I do not understand how the fuck zip-filter works, and there is no documentation anywhere

20:10 tomoj: if you like I can try to help you understand? or you never want to see it again? :)

20:10 Derander: my goal is to find the div with the largest number of immediate-children paragraphs

20:10 I do not know how to translate that into zip filter speak

20:10 tomoj: very interesting problem

20:10 er, solution

20:10 Derander: it's not bad at all w/ a dom

20:11 tomoj: which solves a problem I was talking about today.. :)

20:11 Derander: find all the divs, sort by children "p"s

20:11 tomoj: so what's the filter? div with child p's ?

20:11 Derander: yes

20:12 assuming regular html, divs are children of body, etc

20:14 internet flicker, last thing I would have seen was "tobiassp has left IRC"

20:14 tomoj: side question: can we always expect to find p's only in divs?

20:14 Derander: no

20:14 unfortunately

20:14 nor does every div have a p

20:15 tomoj: oh well

20:16 huh, can you even easily get your dom into a format that will work with zip-filter xml stuff?

20:17 Derander: tomoj: yes

20:17 tomoj: I went down this path earlier; I have a code branch that parses html into an xml-zip

20:18 tomoj: hm

20:18 take the winning div

20:18 if it has div ancestors, what should you do?

20:19 take the innermost div which still has the most p's?

20:19 oh, immediate-children

20:19 nevermind

20:20 Derander: tomoj: yeah

20:21 rata_: some clojure guru can help me with this? I'm getting a stack overflow https://gist.github.com/668294 (the lazy version, second file)

20:22 I don't even have a clue of what can be the cause of that overflow

20:22 it happens when I give get-complexes a map with more than 977 key-value pairs

20:32 tomoj: Derander: well..

20:32 I couldn't remember how it worked off the top of my head

20:33 so I think I solved your problem

20:33 there's gotta be a better way to do it, though

20:34 Derander: tomoj: you solved it?

20:34 tomoj: and yeah, I'm sure you can do it w/ zip filters

20:34 or something

20:35 well, I do have one question.

20:35 oh, never mind.

20:35 tomoj: https://gist.github.com/8b2564ef082b942f3af8

20:35 one problem I always had with xml-> was combining them

20:36 in this case it works out, but if your first xml-> returns a seq of locs, you can't just funnel that in

20:36 which seems weird because each stage of xml-> normally can pass seqs

20:39 Derander: yeah

20:39 perhaps a map or something?

20:40 sorry, brain is being split in too many directions

20:43 well, I've solved the problem w/ the DOM method

20:44 tomoj: Derander: you aren't doing automated browser stuff, are you?

20:45 Derander: tomoj: I don't think so

20:45 I'm just parsing html pages for content

20:45 tomoj: oh

20:45 what are you using for parsing?

20:46 Derander: a combination of HtmlCleaner, wc3.dom's stuff, and my own clojure code

20:46 tomoj: I need to find a parser soon

20:47 Derander: for html?

20:47 tomoj: did you investigate enlive?

20:47 yeah

20:47 Derander: I tried using enlive

20:47 I couldn't figure out how to make it do things like "find me the parent of this element"

20:47 I don't really need css selector searches

20:47 tomoj: I still don't understand it

20:47 Derander: there is already something that does what I'm doing, basically

20:47 called webmine

20:48 came out *this morning*

20:48 but I figure that I'll finish out this aspect of my project as a learning experience

20:48 tomoj: wow, thanks

20:49 I think I'll use that to write a nutch plugin

20:49 if I can figure out how to

20:49 nutch is in a bad way :(

20:49 rata_: help

20:49 Derander: not familiar with nutch

20:50 is there a builtin function that is like max, but that takes a function to determine the weight?

20:50 tomoj: rata_: can you paste the error?

20:50 Derander: basically (conj first reverse sort-by)

20:50 tomoj: Derander: no

20:51 but there is something in contrib I believe

20:51 Derander: eh, no worries

20:51 rata_: tomoj: https://gist.github.com/668294

20:51 Derander: I can just do first reverse sort-by

20:51 rata_: the error is a stack overflow

20:52 Derander: tomoj: the reason I'm doing this is:

20:53 I dump shit on my desktop.

20:53 tomoj: rata_: yes, but I want to see the stack

20:53 Derander: I want to write something that tries to categorize and understand meaning behind the shit I dump there

20:53 tomoj: Derander: dude that's brilliant

20:53 Derander: so right now I'm teaching it to autotag websites

20:53 tomoj: I want to build an app like that too

20:53 have you seen apache tika?

20:53 Derander: no

20:53 tomoj: it can parse PDF text out

20:53 Derander: dammmn

20:53 tomoj: which I need to categorize all these damn papers

20:53 Derander: I'm going to put that on my website

20:53 :P

20:53 desktop*

20:53 tomoj: it's pretty easy to use from clojure

20:54 it has html parser too I believe but I dunno what the hell they produce

20:54 Derander: I had a little glue code that would dump word frequencies of weblocs into mongodb

20:54 tomoj: nice

20:54 Derander: I realized that it would be better if it actually extracted the "content"

20:54 rata_: tomoj: ok

20:54 Derander: so I'm implementing readability's algorithm

20:54 tomoj: I just figured out how to get nutch to store crawl results in cassandra

20:54 Derander: nice

20:54 I've never worked with cassandra

20:54 tomoj: me neither

20:54 Derander: haha

20:55 well, I am going to go home now.

20:55 I'll see you later

20:55 tomoj: good luck

20:56 rata_: tomoj: https://gist.github.com/668294

20:57 tomoj: ok, hmm

20:57 ohpauleez: rata_: how's the battle going?

20:57 tomoj: it looks like your code is doing (filter p (filter p (filter p (filter p...)

20:57 from the stack at least

20:57 rata_: bad... I have no clue what could be the problem

20:57 tomoj: which is strange

20:57 you have no 'filter' in the code

20:57 rata_: tomoj: that could be the remove

20:58 tomoj: oh, yes

20:58 rata_: at line 11

20:58 ohpauleez: Of course, are you realizing the entire collection when you have to filter it? then making it lazy again?

20:58 * ohpauleez looks at the gist

20:58 rata_: with a doall there the problem disappears

20:58 tomoj: right

20:58 I had a similar problem

20:59 at least in symptoms

20:59 rata_: it's strange

20:59 tomoj: I had code that did (map + (map + (map + (map + ...

20:59 or something like that

20:59 are you building up a chain of remove operations and then running through the results of the chain only after building it very long?

21:00 rata_: yes, probably

21:00 amalloy: yes

21:00 tomoj: because then clojure has to go through that entire chain to check whether the first element is in the result

21:00 rata_: though the lazy-seq there should stop them to being so nested

21:01 tomoj: you can probably also solve it by putting a call to vec somewhere

21:01 not sure what the real solution is though

21:01 sorry, I don't understand the code :(

21:01 amalloy: rata_: the lazy-seq is exactly what's causing them to be nested

21:02 rata_: tomoj: it's like a connected-components for graphs

21:03 amalloy: then I don't understand lazy-seq at all

21:03 tomoj: you never change remaining

21:03 oh, yes you do

21:03 with the remove

21:03 I see

21:04 rata_: it should really be (rest remaining) there, but remaining works too

21:04 amalloy: rata_: tomoj had the same problem, as he says, and someone posted an excellent explanation of the issue on g.group

21:04 tomoj: huh, I don't think I saw that

21:04 amalloy: i think so, anyway. maybe it was #clojure, but i thought g.group

21:04 rata_: I remember that problem and I was hoping the whole evening this not to be the same problem

21:05 :P

21:06 amalloy: http://groups.google.com/group/clojure/browse_thread/thread/6f5064532546a852

21:06 tomoj, rata_ ^^

21:09 defn: hey everybody

21:09 Ruby is annoying me.

21:10 rata_: amalloy: then is this a clojure bug?

21:10 defn: {:foo => "bar", :bar => "baz"} -- this syntax is so heavy! {:foo "bar" :bar "baz"}

21:10 amalloy: rata_: no, it's clojure being exactly as lazy as you want

21:10 ohpauleez: defn: I feel that pain, every single day I have to work on php

21:10 amongst other, terrible, terrible pains

21:11 rata_: mmmm... but much is said about lazyness protecting your code from stack overflows

21:11 ohpauleez: defn: The advantage I have is I get to write server technology and system tools in Clojure and Python

21:16 defn: ohpauleez: to ruby's credit the new 1.9.2 syntax is {foo: "bar", bar: "baz"}, but still

21:16 there's so much syntactic sugar, but then this obvious pain point is just sitting there

21:18 hiredman: ~#2

21:18 damn

21:22 ~#2

21:22 clojurebot: 2. Functions delay binding; data structures induce binding. Moral: Structure data late in the programming process.

21:22 ohpauleez: alright! I'm glad that's back

21:25 hiredman: it should only be sending the first commit message for each watched repo the first time it runs :/

21:27 ohpauleez: clojurebot just knows that knowledge is power

21:39 tomoj: it would be cool if vars had timestamps

21:49 defn: tomoj: they can, if you want them to

22:00 tomoj: i take that back

22:04 tomoj: each commit for in transaction and committed values should have a commit timestamp

22:04 (the point field in the TVal object)

22:05 tomoj: TVal?

22:05 defn: src/jvm/clojure/lang/Ref.java

22:07 tomoj: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Ref.java#L47

22:08 tomoj: im just not sure if you can get at these values

22:08 tomoj: where do you intend to use timestamps?

22:09 tomoj: I don't actually

22:09 I was thinking of tests

22:09 * defn chuckles at himself

22:09 tomoj: automatically run only the tests that need to be run based on when each fn has last been changed

22:10 defn: that's sort of a biased watcher

22:10 wouldn't you agree?

22:10 tomoj: dunno what you mean

22:10 defn: are you talking about contiunous testing?

22:10 tomoj: yeah

22:10 defn: autotest, etc.

22:10 tomoj: right

22:11 defn: why wouldn't be monitoring the file be the best course of action there?

22:11 s/be//

22:11 sexpbot: <defn> why wouldn't monitoring the file the st course of action there?

22:11 * defn stabs himself

22:11 tomoj: maybe it would be

22:12 defn: a language feature to facilitate continuous testing just seems wrong-headed to me

22:12 the filesystem changes are more obvious, but there's probably something to what you're syaing

22:12 tomoj: well, hmm

22:12 imagine that when you change a function, the tests are run for every function which calls that functnio

22:13 I guess if that were useful, you don't have good isolation in your tests

22:13 defn: how much of lazytest have you read?

22:13 tomoj: none

22:13 never used it

22:13 defn: check out that, and midje

22:13 tomoj: midje the mocking framework?

22:13 I was actually originally thinking: mock with metadata

22:14 defn: i'd say it's more than just mocking,no?

22:14 tomoj: dunno

22:14 never looked at it

22:14 defn: it's cool -- brian marick has good ideas and knows testing

22:15 tomoj: (deftest test-multiplication (is (* ^3 (+ 1 2) ^6 (+ 3 3))))

22:15 I don't know testing

22:15 :(

22:15 well that made no sense

22:15 defn: and lazytest -- stuart sierra

22:15 good stuff.

22:15 tomoj: should've been (is (= (* ..) 18))

22:16 I was thinking it might be good to put expected values and actual use examples near eachother

22:16 amalloy: anyone know of a macro that's the opposite of :keys destructuring? i'd like to take N bound locals and cram them into a map, indexed by the keywordized versions of their names

22:16 tomoj: then you can switch off using the expected value or actually using the code to determine where the error really is?

22:16 amalloy: easy to write myself, but if one already exists i'd rather us it

22:16 tomoj: amalloy: I have just the thing

22:16 maybe

22:17 defn: not if i beat you to it

22:17 amalloy: #clojure: Competitive Helping capital of the world

22:18 tomoj: amalloy: https://gist.github.com/2f060dde83ac1bfbe551

22:19 something like that?

22:19 defn: gah!

22:19 tomoj: not sure if I understood what you meant

22:19 defn: note the date

22:19 defn: :)

22:19 amalloy: tomoj: yeah, i remember talking with you about this on #clojure back then

22:19 defn: i have too many sandbox directories...

22:20 it's in /one of these/ projects

22:20 tomoj: amalloy: I guess it doesn't solve you problem then?

22:20 amalloy: i don't want to rebind or modify any locals, just build a map of locals i already have

22:20 tomoj: I made a "scratch" lein project

22:20 amalloy: so, like, what?

22:20 defn: ls -la ~/git | wc -l => 54

22:21 tomoj: (mapmap [foo bar baz])?

22:21 amalloy: tomoj: right

22:21 tomoj: except mapmap is a terrible name

22:21 amalloy: sure

22:21 keywordize is my code name :P

22:21 hiredman: much better

22:22 amalloy: (defmacro keywordize [& vars] `(zipmap ~(map keyword vars) ~vars))

22:23 i mean, it's really easy to write, but i don't want to roll my own if one exists, is all

22:24 tomoj: hmm

22:24 that doesn't work for me

22:24 how would you call it?

22:25 (defmacro mapmap [ss] (into {} (map (juxt keyword identity) ss)))

22:25 or [& ss]

22:25 is what I thought you meant

22:29 amalloy: tomoj: sorry, semi-afk. that's probably what i meant

22:29 hiredman: https://gist.github.com/668652

22:30 amalloy: hiredman: haha, that's cute. i guess if i want to capture everything, that works

22:31 and tomoj, that one's exactly what i was looking for, though i'll play around a bit to understand why mine doesn't work

22:33 hiredman: because your's expands into a function call

22:33 ~vars

22:33 clojurebot: http://www.slideshare.net/mudphone/fun-with-vars

22:34 amalloy: oh, i see. so it'd have to be ~(vec vars) if i wanted to do it my way

22:40 tomoj: hiredman: thanks!

22:40 I'd never seen a decent use of &env before

22:40 Derander: is lein swank still hardcoded to 4005?

22:40 tomoj: thought you had to dig down to java

22:40 `lein swank PORT` or `lein swank PORT HOST`

22:40 Derander: ah, thanks.

22:40 ,(doc into)

22:40 clojurebot: "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."

22:42 hiredman: tomoj: https://github.com/Seajure/serializable-fn/blob/master/src/serializable/fn.clj

23:07 rata_: so strange, rand-nth throws an IndexOutOfBoundsException https://gist.github.com/668678

23:26 leifw: rata_: on what code

23:27 rata_: (defmethod choice clojure.lang.IPersistentVector [v] (rand-nth v))

23:27 leifw: well color me baffled

23:29 what do you pass in?

23:30 I mean, the only problem I can imagine is if you somehow passed in an infinite seq, which you can't do because it's a method of a vector...

23:30 so I dunno what I'm expecting you to say

23:30 rata_: wait me a sec... I'm at another bug right now... maybe solving this one solves that one

23:37 weird bugs

23:40 I'm going to work on these random bugs tomorrow

23:40 it's too late now

23:40 good night :)

23:40 see you

Logging service provided by n01se.net