#clojure log - Oct 27 2010

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

0:04 amalloy: hmm. ninjudd, lancepantz, Raynes? anyone interested in some cake behavior i don't understand?

0:05 Raynes: amalloy: Shoot. I'll be slow to reply. Little busy at the moment.

0:08 amalloy: Raynes: i have a project on computer A, which i've mounted as a directory on computer B via sshfs. on computer B, cake repl works when i'm not inside the sshfs tree; on computer A, cake repl works anywhere. but on computer B, if i navigate into my project, cake repl hangs forever (this is after cake kill all on both machines)

0:09 it warns me that the connection to the bake jvm is taking a long time

0:09 Raynes: That sounds like a monster. Join #cake.clj and reiterate your question. If you don't get a reply tonight, come back tomorrow, or post it on the clojure-cake google group.

0:10 tomoj: omg

0:10 Raynes: Unfortunately, I don't yet know enough about cakes internals to even know where to start on that one.

0:10 tomoj: 32:35 in http://vimeo.com/15046335

0:23 oh, I see chouser explained things below for vimeo users :)

0:31 cpfr: hey how do I add essentially java jars to clojars?

0:33 ah I see I generate the pom file by hand

0:34 amalloy: cpfr: you should be able to add them as deps

0:34 in project.clj

0:34 tomoj: you can also install the jar into your local maven repo@

0:34 cpfr: amalloy, this is a jar that isn't in clojars yet

0:34 amalloy: if they're in a standard maven repo, anyway. if you have them locally you can put it locally

0:34 tomoj: but that can be annoying

0:34 yeah, search jarvana or mvnrepository or something

0:35 cpfr: I want it to be since I want people to be able to use this package more readily

0:40 dnolen: wow, awesome, http://landoflisp.com/

0:45 tomoj: :D

0:46 trptcolin: dnolen: nice

0:51 technomancy: pushed the plugin subtask help to the help ns, so everyone has access to that now through the meta :subtasks

1:01 defn: if anyone wants the audio from rich's talk on sort of a shaky pen microphone: http://db.tt/TK5M0ch

1:01 it's listenable, but some of it is garbled

1:06 tomoj: defn: thanks!

1:07 was someone getting video?

1:09 defn: tomoj: yeah but no telling when it'll be online

1:10 tomoj: just good to know it will be out eventually

1:10 defn: :)

1:10 i have a "pencast" im putting up

1:10 i outlined the slides with my livescribe pen

1:10 so you can see the headings while you listen to the audio

1:10 tomoj: awesome

1:11 does the hand writing recognition work really well?

1:11 defn: it's more impressive than i thought it would be

1:11 my handwriting is so-so, but i do loopy d's and other little weird things

1:11 but it picks them up

1:11 tomoj: yeah.. I'm very pessimistic about anything like that

1:11 cool

1:12 defn: i mean it's not foolproof, you need to be conscious of it and draw something at least resembling the symbol you're trying to represent

1:12 but it's pretty liberal in its interpretation

1:12 i used it in a recent interview i had which was interesting

1:13 i could listen to my responses and their questions again

1:13 and watch my notes as i went along

1:14 tomoj: nice

1:14 _seanc_: Howdy folks, can anyone answer a quick question for a newbie?

1:14 I've been reading through a couple of clojure sites, but I have yet to find the meaning to '&'

1:15 like [x y & more]

1:15 tomoj: ,((fn [x & rest] rest) 1 2 3 4)

1:15 clojurebot: (2 3 4)

1:15 tomoj: it just gathers up the remaining args into a seq

1:15 naming the seq with the symbol that comes after the &

1:16 _seanc_: fascinating

1:16 Clojure is so neat, but definitely intimidating

1:19 bhenry1: anyone experienced in writing lein plugins?

1:19 lein help lists my newly made plugin, but lein plugin-name says it's not a task

1:20 defn: tomoj: did you see the cljc?

1:20 http://github.com/jarpiain/cljc

1:21 tomoj: no, wow

1:22 that binfmt looks like it might be what I recently needed

1:28 defn: _seanc_: dont be intimidated. there's a feeling of confidence that comes with a little practice.

1:29 _seanc_: you'll pick it up quick, just dont be expecting immediate feedback (until of course, you start up a REPL ;)

1:30 tomoj: i really have no idea what's going on in that source -- im trying to get my compiler chops up to par, any recommendations on books?

1:30 tomoj: no, I know nothing about compilers

1:30 defn: dragon book? i have been reading through lisp in small pieces...

1:30 tomoj: I was a philosophy major

1:30 defn: tomoj: i was a lot of majors, not CS... yet

1:32 I figure I'll just teach myself compilers -- dragon book, steal some assignments from google's curriculum search, and boom

1:32 (over the course of several months, possibly years ;)

1:37 tomoj: I don't feel like I need to learn about compilers

1:37 I hope I'm right

1:37 defn: tomoj: i dont think it hurts to get closer to the metal

1:37 there's a lot of open ground there for problem solving

1:37 s/open/fertile

1:38 so many of the libraries out there that spring up are based on exploiting powerful language features, not other libraries

1:38 there's usually the core requirement of something that actually solves the problem you want to solve

1:38 mashups are fun, but not as rewarding i think

1:41 tomoj: certainly doesn't hurt

1:41 just doesn't sound like any fun to me :)

1:49 zmyrgel: hi, I'm trying to convert Hughes Why FP matters papers haskell code into Clojure but I'm not that good in Haskell to get it done

1:49 could somebody check my progress so far to give pointers: http://clojure.pastebin.com/Wbm1vXmy

1:50 particularry the haskell code starting no line 79 is odd to me to comprehend

2:00 defn: zmyrgel: wow. that is crazy code. sorry i cant help...

2:04 zmyrgel: I think thats what the code should look like compared to what my stuff is currently

2:04 I'm trying to make chess engine in clojure and the lazy game tree would seem spot on to add to it

2:05 Problems for the tasks are that I haven't done anything bigger in Clojure or any functional language which is apparent when looking my results :)

2:06 duncanm: sigh, i still can't haven't come up with a way that i'm comfortable doing this - i want a (foo {:a 1, :b 2} inc), that returns {:a 2, :b 3}

2:06 i dunno how to write 'foo'

2:08 tomoj: you can't get anything working?

2:08 or the stuff you've got working has some unfavorable characteristics?

2:09 duncanm: (into {} (map #(vector (key %) (inc (val %))) {:a 1 :b 2}))

2:09 ,(into {} (map #(vector (key %) (inc (val %))) {:a 1 :b 2}))

2:09 clojurebot: {:a 2, :b 3}

2:09 duncanm: that's so-so

2:09 i guess i can call that update-map, kinda like update-in

2:09 tomoj: ,(letfn [(foo [f m] (into {} (for [[k v] m] [k (f v)])))] (foo inc {:a 1 :b 2}))

2:09 clojurebot: {:a 2, :b 3}

2:10 duncanm: tomoj: i wish something like that were part of clojure.core

2:10 Derander: I had to write something exactly like that in ruby for a project

2:10 zmyrgel: simple question, is let* just and alias for let?

2:10 duncanm: zmyrgel: you don't need to think about let* in clojure, it's always let*

2:10 tomoj: ,(macroexpand-1 '(let [x 1] x))

2:10 clojurebot: (let* [x 1] x)

2:11 tomoj: hope not

2:11 then every let infinite loops?

2:11 duncanm: i thought there's no difference between let and let* in Clojure, unlike, say, Scheme

2:12 zmyrgel: let* isn't even listed in API but it won't cause any errors / warnings either

2:12 tomoj: ,(let [[x y] [1 2]] [x y])

2:12 zmyrgel: gotta clean up my code then a bit :)

2:12 clojurebot: [1 2]

2:12 tomoj: ,(let* [[x y] [1 2]] [x y])

2:12 clojurebot: java.lang.IllegalArgumentException: Bad binding form, expected symbol, got: [x y]

2:13 tomoj: ,(macroexpand-1 '(let [[x y] [1 2]] [x y]))

2:13 clojurebot: (let* [vec__229 [1 2] x (clojure.core/nth vec__229 0 nil) y (clojure.core/nth vec__229 1 nil)] [x y])

2:14 zmyrgel: so let* is internal thing not to be messed around

2:14 duncanm: zmyrgel: so, in Scheme, if you use a let, later bindings cannot have to earlier bindings on the RHS

2:14 wait, i think i got that backwards

2:14 zmyrgel: yep, I know. I did some small snippets in Scheme before

2:14 duncanm: zmyrgel: so in Clojure, all lets have let* semantics

3:02 dum de dum

3:08 amalloy: duncanm: dum be doo, even?

3:15 notsonerdysunny: how can I avoid the slime from bringing up the backtrace when I know that I am handling the exception in a try-catch block?

3:16 ,(try (/ 1 0) (catch IllegalArgumentException e (prn "in catch")) (finally (prn "in finally")))

3:16 clojurebot: notsonerdysunny: No entiendo

3:16 amalloy: notsonerdysunny: i'm surprised it doesn't do that already. i'll take a look

3:16 notsonerdysunny: ~(try (/ 1 0) (catch IllegalArgumentException e (prn "in catch")) (finally (prn "in finally")))

3:16 clojurebot: the leiningen screencast is on full disclojure: http://vimeo.com/8934942

3:17 notsonerdysunny: thanks amalloy

3:20 amalloy: notsonerdysunny: are you sure it's trapping on the exception you throw, and not some other exception? i'm having trouble reproducing but my swank setup is kinda weird so it could be me

3:21 notsonerdysunny: can you just try the above expression...

3:21 I presume the above s-exp should go through fine..

3:21 amalloy: notsonerdysunny: it's some kind of classpath issue

3:22 when i run your sexp, i get an erithmetic exception just like you

3:22 but try changing it to (try (/ 1 0) (catch Throwable e (prn "in catch")) (finally (prn "in finally")))

3:22 ,(try (/ 1 0) (catch Throwable e (prn "in catch")) (finally (prn "in finally")))

3:22 clojurebot: amalloy: Gabh mo leithscéal?

3:23 notsonerdysunny: amalloy: yea it goes through fine

3:23 amalloy: for me that works, and i don't know why, but i think it's something to do with trouble finding the ArithmeticException class in some weird env. sorry i can't help more, i'm just off to bed

3:23 notsonerdysunny: thanks amalloy ... I will look around a little more

3:23 amalloy: good luck'

3:23 notsonerdysunny: amalloy: good night

3:26 ~(try (/ 1 0) (catch Throwable e (prn "in catch")) (finally (prn "in finally")))

3:26 clojurebot: clojurebot will become skynet

3:26 notsonerdysunny: ->(try (/ 1 0) (catch Throwable e (prn "in catch")) (finally (prn "in finally")))

3:26 sexpbot: ⟹ "in catch" "in finally" nil

3:26 notsonerdysunny: ,(try (/ 1 0) (catch Throwable e (prn "in catch")) (finally (prn "in finally")))

3:26 clojurebot: notsonerdysunny: excusez-moi

3:27 notsonerdysunny: ->(try (/ 1 0) (catch IllegalArgumentException e (prn "in catch")) (finally (prn "in finally")))

3:27 sexpbot: java.lang.ArithmeticException: Divide by zero

3:29 edbond: how to change a vector several times? Suppose I have changes vec [[1 4] [2 3]] in form [index value]

3:29 notsonerdysunny: ,(try (/ 1 0) (finally (prn "in finally")))

3:29 clojurebot: notsonerdysunny: Titim gan éirí ort.

3:29 notsonerdysunny: ->(try (/ 1 0) (finally (prn "in finally")))

3:29 sexpbot: java.lang.ArithmeticException: Divide by zero

3:34 hoeck: ,(apply assoc [:a :b :c] (apply concat [[1 4] [2 3]]))

3:34 clojurebot: [:a 4 3]

3:34 hoeck: edbond: ^

3:34 notsonerdysunny: How do i increase java heap space

3:34 is there a limit that is preset?

3:35 can I change it? I am using cake+slime+emacs

3:35 v-alex: notsonerdysunny: -Xmx512m

3:35 notsonerdysunny: see also java -X

3:35 sandGorgon: notsonerdysunny, try "java -X" to see all X options. The heap options are -Xms and -Xmx

3:36 notsonerdysunny: thanks sandGorgon and v-alex

3:37 edbond: hoeck: thanks

3:49 raek: ,(reduce (fn [v [i x]] (assoc v i x)) [:a :b :c] [[1 :x] [2 :y]]) ; <-- another variant

3:49 clojurebot: [:a :x :y]

3:59 hoeck: ,(reduce (partial apply assoc) [:a :b :c] [[1 4] [2 3]])

3:59 clojurebot: [:a 4 3]

4:00 raek: nice.

4:07 TobiasRaeder: morning everybody

5:19 eMortiferus: anyone know if there is a defacto way of checking what record-type some "thing" is of?

5:19 I have problem getting instance? to work reliably

5:19 AWizzArd: eMortiferus: can you give an Example?

5:20 eMortiferus: (defrecord lterm [var body]

5:20 T (t [this]

5:20 (println (type body))

5:20 (println (instance? lterm body))

5:20 (if (instance? lterm body) (println "int "))))

5:20 AWizzArd: (defrecord Foo []) ... (class (Foo.)) ==> your.namespace.Foo

5:20 eMortiferus: if I do (t (lterm. :x (lterm. :y :z)))

5:20 I get:

5:20 user.lterm

5:20 false

5:20 nil

5:21 So the type of body is user.lterm, but not (instance? lterm body)

5:22 angerman: hmm.... the error "Unable to resolve symbol" is not very helpful with a backtrace that doesn't tell me where to look ://

5:22 AWizzArd: eMortiferus: (instance? YourRecord obj) would work.

5:22 Hallo angerman

5:23 angerman: hi AWizzArd

5:24 eMortiferus: AWizzArd: Yeah, but then the above example should print true, not false. Could it be in the way I denote "MyRecord"? Now I write (instance? lterm body), I also tried writing (instance? user.lterm body), but then the loader complains

5:26 AWizzArd: It should be said that it did work a while, then I did some more development, and it stopped working, which made me unsure if (instance? .. ..) should work or not. If it is supposed to work then maybe this is an artifact of me not restarting the clojure session for 4 days, and some old and new versions of the classes are hanging around?

5:28 Chousuke: I don't think the class is available during definition of the record :/

5:28 AWizzArd: eMortiferus: try (do (defrecord Foo []) (instance? Foo (Foo.)))

5:29 If it is not available then the compiler should throw an error.

5:29 eMortiferus: AWizzArd: that returns true, but it seams to do something else then my example

5:30 AWizzArd: pardon my clumsy terminology, but it seams to check if the "Class" Foo is (instance? Foo (Foo.)), while I want to check if an "instance" of Foo is of type Foo

5:31 AWizzArd: Ahh forget what I said, I understand now that (Foo.) makes an instance

5:34 hoeck: eMortiferus: to, it looks like the instance? check uses the old version of lterm, the one that was present before compiling the defrecord and loading the new class

5:34 eMortiferus: if you do a (let [c lterm] (instance? c body)) it returns actually true

5:34 AWizzArd: eMortiferus: (do (defprotocol Lala (bar [this])) (defrecord Foos [x] Lala (bar [this] (println (class this) (instance? Foos this)))) (bar (Foos. 1)))

5:35 hoeck: I'm on clojure 1.2, btw

5:35 AWizzArd: This returns true for the instance? check for me.

5:35 eMortiferus: "user> (do (defprotocol Lala (bar [this])) (defrecord Foos [x] Lala (bar [this] (println (class this) (instance? Foos this)))) (bar (Foos. 1)))

5:35 user.Foos false

5:35 nil

5:35 user> "

5:36 AWizzArd: eMortiferus: for me this results in user.Foos true

5:38 TobiasRaeder: returns false for me aswell :/

5:38 eMortiferus: AWizzArd: Interesting, I will restart my clojure session and see what happends.

5:38 TobiasRaeder: what version clojure your running AWizzArd?

5:38 eMortiferus: AWizzArd: This is btw the code I am trying: http://pastebin.com/yVskNgUx

5:38 Chousuke: have you restarted the jvm?

5:39 redefining the record might be causing trouble

5:39 eMortiferus: Chousuke: No, it has been running for quite some time, with several iterations of the development, I restart it now and try

5:40 I am using "Clojure 1.2.0" btw

5:40 TobiasRaeder: i just tried it with a clean emacs

5:42 eMortiferus: Me too, does not work wit a fresh emacs/slime

5:44 AWizzArd: I am using Clojure 1.3 Alpha 1.

5:44 TobiasRaeder: ah :) im using1.2 aswell

5:44 that might be it

5:44 AWizzArd: yup

5:46 eMortiferus: AWizzArd: I will try 1.3 Aplha 2 and see what happends here

5:48 AWizzArd: With 1.3A2 it works :D

5:48 Thanks for the help everyone

5:48 AWizzArd: eMortiferus: but there may be other things in A2 which will not work.

5:48 It is still a fast moving target.

5:49 eMortiferus: AWizzArd: yeah I know, but this is just private play-code, so if I find bugs it is no crisis, I will submit bugreport and wait till it gets fixed:p

5:49 AWizzArd: good

6:53 zmyrgel: Could somebody aid me defining the taketree function on line 140: http://clojure.pastebin.com/Wbm1vXmy

6:53 it seems to need partial but how to make it work with the 'n' parameter?

6:55 Chousuke: (redtree (partial nodett n) ...)?

6:57 oh, I suppose you need the subtree argument too

6:57 in that case it would be (defn taketree [n subtree] (redtree (partial nodett n) cons nil subtree))

6:58 Clojure doesn't have currying like Haskell so you can't translate too literally :P

6:58 zmyrgel: I've noticed that

6:59 Chousuke: specifically, if you call (foo bar) for a function foo of two arguments, it won't give you a function of one argument

7:00 it would be nice if it did but unfortunately that's not feasible to implement in Clojure :/

7:00 zmyrgel: that needs the partial function?

7:00 Chousuke: yeah

7:00 zmyrgel: slowly starts to getting these stuff

7:00 Chousuke: or you can use the fn shortcut reader macro: #(foo bar %)

7:01 where % = %1 = first parameter

7:02 zmyrgel: Well, my current fixed version starts to seem pretty ok, we'll see how it works once I get it included to my chess engine project :)

7:59 fliebel: Is there any way I can 'reset' a zipper, short of doing root and then make a new zipper? I made a few functions that use a zipper, but threading the zipper through them would leave the successive functions with some random loc where the previous function left of.

8:17 zmyrgel: hi, do these let forms yield same result: http://clojure.pastebin.com/wC9UmPMJ

8:31 harto: hello - anybody know how to add jars to classpath for cake tasks?

8:32 i.e. my tasks.clj depends on an external lib, which is a project dependency, but I'm getting class not found

8:38 mister_roboto: it seems like all the samples i see lately are using (fn [] foo...) rather than #(foo ...) is the latter syntax considered ugly or something? wondering about the idioms

8:50 fogus_: mister_roboto: It often comes down to personal style.

8:50 mister_roboto: fogus_: ok. i was wondering if #() was starting to be a "deprecated" style

8:50 fogus_: not at all

8:51 mister_roboto: otherwise it seemed overly verbose for a lot of the one-liners i see posted here

8:51 but thanks!

9:20 tonyl: good morning

9:20 arkh: technomancy: thank you - if that was covered at the conj then I missed it o.0

9:43 technomancy: arkh: it wasn't mentioned; it's pretty new.

9:46 TobiasRaeder: @arkh, technomancy did i just miss something? whats new? :o

9:47 technomancy: TobiasRaeder: $ java -cp [...] clojure.main -m my-non-aotd.namespace

9:48 uses the -main defn in that ns

9:48 TobiasRaeder: ah nice :D

9:48 thanks

9:49 arkh: that seems like a good option to have

9:50 fliebel: I only wonder wh… Oh, m for main of course.

9:50 technomancy: I assume that also includes args?

9:50 technomancy: aye

9:51 reduces the need for AOT; a lot of people use AOT only for -main

9:51 FSVO a lot

10:10 apgwoz: are people here using plain ole paredit.el, or is there a clojure specific paredit.el that handles clojure's Character type better?

10:11 tomoj: paredit-beta.el

10:11 I haven't noticed any char problems

10:11 apgwoz: this morning I found myself really annoyed when doing case statements with \c, etc, which paredit proper uses \ as an escape key

10:12 tomoj: why does that cause problems?

10:12 paredit-beta.el does the same

10:13 apgwoz: because it turns the character into an integer as far as emacs is concerned, and not the string "\c" for which clojure's reader can read

10:14 hiredman: I've never had problems with character literals in emacs

10:14 apgwoz: maybe i should just update paredit

10:14 tomoj: \ is paredit-backslash?

10:14 apgwoz: yes

10:16 two things are possible, i'm either making shit up, or doing something incredibly wrong

10:16 i tend to think i'm doing something wrong (maybe just using an old paredit)

10:17 since, i don't see the wrong behavior at work right now, but saw it this morning on my laptop, to the point where i turned off paredit when editing characters.

10:57 bhenry1: Ruby Learning Clojure 101 activity has died off in the final two weeks.

11:44 _rata_: hi

12:00 has anybody seen jkkramer?

12:03 stuarthalloway: chouser: did you ever get the clojure projtools stuff to do a secure GET from assembla?

12:04 chouser: stuarthalloway: I don't remember, let me check.

12:05 stuarthalloway: I have some modifications to the code...

12:05 duncanm: is there a common predicate to identify both a PersisentList and a PersistentVector?

12:05 ,[(seq? (vector)) (seq? (list))]

12:05 hmm

12:05 no response

12:06 stuarthalloway: http://paste.lisp.org/display/115960

12:06 I am trying to do an HTTP GET of the user profile that returns the email address as well as the id, which requires that one be logged in

12:07 if I could get that to work, I could move all the accounts from assembla to Crowd/JIRA/Confluence

12:07 MayDaniel: duncanm: sequential? ?

12:08 duncanm: MayDaniel: ah, thanks

12:09 technomancy: stuarthalloway: jweiss mentioned last night he may be able to help with the jira migration

12:09 stuarthalloway: technomancy: I emailed him back but got bounced

12:09 chouser: stuarthalloway: I must have been able to log in -- I was using the script to attach patches to tickets and such

12:10 stuarthalloway: technomancy: the next step is deciding what the next step is. Please have jweiss look over the site and make a list of things he thinks need doing

12:10 jweiss: stuarthalloway: that's odd - sorry about that. try jeffrey.m.weiss@gmail.com

12:10 chouser: stuarthalloway: http://github.com/Chouser/clojure-projtools/blob/master/src/net/n01se/clojure_projtools.clj#L43

12:11 stuarthalloway: chouser: I see it in the code, but haven't been able to get it to happen

12:11 Not worth too much effort here: I can scrape the 120 users by hand, or people can recreate the accouns on their own

12:12 chouser: ok. it's entirely possible they've changed things on their side since I last used this code.

12:12 jweiss: stuarthalloway: a selenium ide script might work - i have written those before

12:12 to read the fields from the webui and type em in on the new one (if there's a simple mapping)

12:16 LOPP: guys I have a problem with using recur

12:17 stand-by for code

12:17 user> (defn get-no-markup [seqe num-open-bracket]

12:17 (if (empty? seqe)

12:17 seqe

12:17 (case (first seqe)

12:17 \< (recur (rest seqe) (inc num-open-bracket))

12:17 \> (recur (rest seqe) (inc num-open-bracket))

12:17 :other (if (= num-open-bracket 0)

12:17 (cons (first seqe)

12:17 (recur (rest seqe) num-open-bracket))

12:17 (recur (rest seqe) num-open-bracket)))))

12:18 basically the function returns input character sequence with parts left out that are within tags

12:18 however it won't let me use recur like that

12:18 even though it's the last sentence in each code path

12:19 what do I do?

12:19 MayDaniel: LOPP: recur needs to be in tail position

12:19 LOPP: that makes it damn useless

12:20 jweiss: lopp, just turn your code inside out to calc the values to pass to recur *inside* the recur form instead of outside

12:21 LOPP: oh god

12:22 that will make some buttugly code

12:22 dnolen: LOPP: please use a pasting service

12:22 LOPP: what's that?

12:22 MayDaniel: LOPP: gist.github.com

12:22 LOPP: oh I see what you mean

12:22 like pastebin

12:23 chouser: recur is for tail recurion. If you don't want tail recursion, use regular named-function recursion.

12:24 jweiss: LOPP - something like (recur (rest seqe) (if ... case... ))

12:24 jonasen: A simple example generating Pascal's triangle using chousers new double-list: http://gist.github.com/649317

12:25 LOPP: chouser but then I will blow the stack]

12:25 the string HTML page sized

12:26 chouser: LOPP: that's true in really every language -- if you aren't using tail recursion, you will consume stack, regardless of whether or not your language has a special 'recur' keyword.

12:26 LOPP: jweiss: right I can do that but where do I call cons?

12:27 chouser: jonasen: you're using double-list! yay! :-) Note that conls will probably be renamed to conjl soon, but will act exactly the same.

12:27 consl -> conjl

12:27 LOPP: http://pastebin.com/YJK5btCx

12:27 here's my second try

12:27 with single recur invocation right at the end

12:28 still doesn't work :(

12:28 chouser: that's not the tail position

12:28 LOPP: what would be a tail position?

12:28 chouser: see, this is actually good.

12:29 in langauges like scala and scheme that do tail-call optimization, one could write code like this and believe it was safe from blowing the stack, but be wrong.

12:29 jonasen: chouser: It's fun to try all this ne stuff in Clojure..

12:29 LOPP: Oh I thought you liked the code :(

12:29 chouser: clojure's helping you learn what the tail position *isn't*. :-)

12:29 LOPP: :D

12:30 I am unsure about the "correct" way to do this kind of sequence processing

12:30 chouser: LOPP: try thinking of it this way: the tail position is where an expression will be the return value of the outer expression.

12:30 so, in (do a b c) the tail position is c

12:30 LOPP: so the second one fails because recur should be in position of apply?

12:30 chouser: in (if foo? x y), both x and y are tail positions

12:31 MayDaniel: LOPP: With `case`, you don't need an :else/:other/:default to match a default clause.

12:31 chouser: LOPP: generally to convert a non-tail recursive fn to a tail-recursive one, you have to add a new argument to act as an accumulator of what you will eventually return.

12:31 LOPP: in other words it fails because I have apply wrapped around recur in return expression?

12:32 chouser: LOPP: right. In (apply foo bar) or (+ a b c), none of the interior items [foo, bar, a, b, c] are in a tail position

12:32 LOPP: ok, do you reckon using let sentence in such fashion is constructive or is the first version better?

12:33 I'm having a hard time with design in clojure since I'm used to imperative thinking

12:34 in java I'd probably go with string buffer, a for loop, and I'd add the right characters to string buffer

12:35 amalloy: LOPP: the idea is very much the same in clojure. you need an accumulator of some sort, like a stringbuilder, which you append to and pass along with each instance of recur

12:35 dnolen: LOPP: the beauty of tail recursive functions is that they can be composed, you can't compose for loops. you just have to write them over and over again. Depending on what text editor you use, you might not notice ;)

12:36 LOPP: amalloy: so you recommend using a mutable java object like string buffer to store the result rather than clojure seq?

12:36 amalloy: no

12:37 LOPP: ok...a vector then?

12:37 amalloy: sure, something like that

12:37 have you seen a tail-recusive version of summing a list?

12:38 LOPP: I can't see using cons in this case since it adds to the front, so I'll need something that is cheap to add in the back

12:38 amalloy: LOPP: vectors add in back cheaply

12:38 LOPP: and using str to append to string at the end will probably be slow as hell

12:38 chouser: Another option is to use the 'reduce' function.

12:39 anytime you can use loop/recur you could also use reduce, though it's not always better.

12:39 amalloy: ,((fn [sum [x & xs]] (if x (recur (+ x sum) xs) sum)) 0 [1 2 3 4 5 6])

12:39 clojurebot: ping?

12:39 ->((fn [sum [x & xs]] (if x (recur (+ x sum) xs) sum)) 0 [1 2 3 4 5 6])

12:39 sexpbot: ⟹ 21

12:40 LOPP: hm

12:40 amalloy: LOPP: you see how i've added a sum parameter, which is used to track intermediate results? it doesn't have to be mutable, because i replace it with a new number every time i recur

12:40 jsanda: hey folks, i'm trying to extend a protocol on a java type and getting the error message, "interface core.Translatable is not a protocol" and i don't understand that because prior to this code in the same file i extend the protocol on a defrecord

12:40 LOPP: though concatenating strings probably has same cost as making a shitload of new vectors each step

12:40 replaca: LOPP: one option that people use is simply to accumulate a sequence of strings (or generate one by map or some such) and then apply str to the result

12:41 jsanda: can anyone shed some light on that error?

12:41 chouser: note that it's recuring on (at least) two args: the accumulator (sum) which is growing, and the input ([x & xs]) which is shrinking

12:41 LOPP: aha

12:42 amalloy: LOPP: appending to vectors isn't that expensive, because they're persistent and can have pointers to the same data

12:42 LOPP: you think I'm better off using them rather than str function?

12:42 amalloy: meh. i don't know what your actual problem is; i joined after that

12:43 i'm just demonstrating tail recursion

12:43 LOPP: aha

12:45 amalloy: what is your actual goal, anyway?

12:45 LOPP: to throw tags out of a piece of HTML

12:45 I don't need any fancy parsing

12:45 chouser: nested angle brackets even, which aren't actually valid html

12:46 LOPP: I just want everything between < and > to disappear

12:46 I know

12:46 amalloy: LOPP: use a regex global replace instead?

12:46 LOPP: I haven't thought of that

12:46 amalloy: or are you using this as a learning problem to figure out recursion in clojure?

12:47 LOPP: I was thinking I can use regex, then I remembered I can match things but not delete things with regex

12:47 now I realize how stupid of me

12:47 chouser: (clojure.string/replace "this<is>ok" #"<.*?>" "") ; doesn't handle nested brackets

12:47 LOPP: just replace with ""

12:47 yeah...what a brainfart

12:47 I don't think I'll need to handle nested

12:47 chouser: but tail recursion is really useful to understand

12:47 LOPP: I know

12:47 chouser: as is correct use of HOF like 'reduce'

12:48 so we're happy to help with those if you're still interested. :-)

12:48 LOPP: first I'll have to try out earlier suggestions

12:48 been busy typing

12:48 amalloy: chouser: fwiw, .*? is much slower than [^>]*

12:48 LOPP: fwiw?

12:49 amalloy: for what it's worth

12:49 chouser: amalloy: ok

12:49 LOPP: ah

12:49 :)

12:49 I thought all regexes are about the same

12:49 since it compiles into a state machine?

12:49 or am I wrong yet again

12:50 amalloy: well your second statement is correct

12:50 chouser: can backtracking regex engines compile to a state machine?

12:50 LOPP: ok backtracking...

12:50 but using a reluctant quantifier

12:50 shouldn't be slower IMO

12:51 amalloy: the state machine created by .*? is much slower at matching because of the way *? is implemented

12:51 LOPP: transitioning a state is a constant time operation IMO

12:51 amalloy: one sec i'll find the link

12:51 LOPP: and with each character you do 1 state transition

12:52 amalloy: http://www.regular-expressions.info/repeat.html

12:52 contains, in fact, a discussion of how to match html tags

12:53 and near the end, under An Alternative To Laziness, it explains why .*? is slow

12:54 LOPP: read it

12:54 interesting

12:55 so while transitioning states is constant

12:55 you need to consider each character multiple times if you need to do backtracking and your regex does the least backtracking

12:55 amalloy: yeah, in fact it does no backtracking at all

12:56 that page is fantastic if you want to get better acquainted with regexes

12:58 LOPP: oh java, you so crazy

12:59 on another topic, if clojure gonna get ported to Java 7 anytime soon?

12:59 technomancy: clojure runs fine on openjdk 7

12:59 LOPP: I see it will have some kind of support for dynamically typed languages

12:59 of course

12:59 that's not the same as port :)

13:00 all java code runs fine on newer version than it's compiled for

13:00 that's directive #1 on Oracle's list

13:01 cemerick: adding support for invokedynamic would hardly qualify as a "port" IMO

13:01 LOPP: cemerick: I am unaware about the actual extent of new stuff

13:02 cemerick: That would be the biggest item, and it's "just" an optimization.

13:02 LOPP: the only interesting thing for me in Java 7 is the array bounds check elimination optimizer

13:02 cemerick: Now, ClojureCLR, *that's* a port. Poor dmiller2718 ;-)

13:03 LOPP: they are gonna drive Java into the ground with all these featureless versions

13:03 can't wait for CLR port...C# is a tons better language

13:04 cemerick: If you're using Clojure, why do you give a toss about Java vs. C#?

13:07 LOPP: well.. if you are working with Windows

13:07 C# gives you easier access to Win32 and DLLs with PInvoke

13:07 it also have better gui

13:07 anchors > layout managers

13:08 cemerick: well, fair enough, but that's due to the CLR and .NET, not C#

13:09 LOPP: with java you break your balls to make your app have an icon with menu in task bar or if you want to make it a service

13:09 ok that's true...it's not different as far as using a clojure goes

13:09 cemerick: You should check out swt sometime. There's lots of thick-client goodness in there.

13:10 LOPP: it's just that Sun/Oracle is so frustratingly incompetent at adding language features

13:10 I work with java and I rage every day


13:11 cemerick: Breathe, man, breathe.

13:11 :-)

13:11 LOPP: :D

13:11 if you don't work with java you won't understand this

13:11 cemerick: I still do, I get you.

13:12 There are upsides to the glacial rate of language change though.

13:12 LOPP: I was ecstatic when I worked with delegates and C# properties

13:12 and events

13:13 holy crap that alone would solve like 95% of my java problems

13:14 and that was in 3.0, now they have added lambda functions, lazy sequences, multi methods

13:14 KirinDave: So, I'm still staring a bizarre problem in the face.

13:14 I have a gen-class form with a static method

13:14 And when I try and compile, the compiler complains a var that is clearly bound is in fact unbound.

13:18 dnolen: KirinDave: sounds like you're using 1.3.0-alpha2 ?

13:19 chouser: no, I think he said 1.2. He means a method marked as static in gen-class

13:21 dnolen: chouser: I see.

13:21 KirinDave_: Sorry, my network is unreliable

13:22 This is the module I'm trying to compile: https://gist.github.com/be11b181842fce78ade5

13:22 KirinDave: This is the module that it complains about, and the error: https://gist.github.com/47de41199aabd74df3c0

13:23 It makes no sense, because if I load the module (after clearing the .class files, of course), it loads just fine.

13:23 And protocol-machine only does one simple thing right now: https://gist.github.com/b26834d128610b428f2b

13:24 cemerick: KirinDave: have you fixed the :static metadata in core yet?

13:24 KirinDave: cemerick: Yes

13:24 There, updated.

13:25 cemerick: ok; and you can load the namespaces in question without any AOT artifacts, but you cannot load the resulting gen-class'ed classfile without getting the error?

13:25 KirinDave: cemerick: As long as I don't have the compiled files around

13:25 What's really weird

13:25 is that the compile works the first time

13:25 Subsequent compiles (and loads) fail.

13:25 If I delete the class files, it all works.

13:25 cemerick: Well, that's not actually odd.

13:26 LOPP: doesn't the newest version have static vars by default?

13:26 I remember hearing something along these lines

13:26 cemerick: The compiler looks for previously-compiled classes, and loads them if they're there instead of loading the source file. So, the problem is the loading of compiled classfiles.

13:26 KirinDave: Right.

13:26 So does this suggest some sort of error in the way clojure is compiling these files?

13:26 cemerick: have you tried just throwing a (def b13 :foo) at the top?

13:27 KirinDave: No, i suppose it'll be re-def'd

13:27 cemerick: well, that's what adding the dummy would test

13:28 KirinDave: cemerick: So, now it complains about b12

13:28 cemerick: ok, good

13:28 KirinDave: Maybe instead of declaring the vars, I should def identity them.

13:29 cemerick: Sure, add dummies for all of those nodes in the graph.

13:34 KirinDave: Ah, it worked.

13:34 cemerick: That's... really weird.

13:34 Becuase I _do_ def the symbols.

13:34 But if I remove all declares and instead predef the symbols

13:34 then it works.

13:35 cemerick: yeah, I think it's an oddity w.r.t. :static that might not apply anymore

13:35 chouser: I presume this is the cause of KirinDave's troubles http://github.com/clojure/clojure/blob/master/src/clj/clojure/genclass.clj#L205

13:36 oh bugger, nevermind

13:36 KirinDave: ??

13:36 cemerick: it's been a *long* time since I looked at genclass.clj

13:36 :-(

13:37 KirinDave: So I can only interpret that as a bug.

13:37 Unless it's documented somewhere...

13:38 cemerick: Perhaps. Don't take my word for it.

13:38 The specific lifecycle of an AOT init class is a mysterious thing.

13:53 kumarshantanu: hi, I am looking for a way to find the current namespace...can somebody throw a pointer?

13:53 cemerick: *ns*

13:53 Raynes: -> *ns*

13:53 sexpbot: java.lang.SecurityException: Code did not pass sandbox guidelines: (#'clojure.core/*ns*)

13:53 Raynes: Heh.

13:54 kumarshantanu: cemerick: thanks!

13:56 cemerick: KirinDave: In any case, if you can distill that into a 10-liner example, that'd be a good bug report.

13:56 KirinDave: cemerick: I think I can

13:57 cemerick: Reading the genclass source, I don't see why changing the static param into emit-forwarding-fn should impact the semantics of the loading of required namespaces.

14:05 LOPP: clojure doesn't have a fn for regex find+replace?

14:05 sethtrain: LOPP: clojure.contrib.str-utils.re-sub

14:05 Raynes: (find-doc "re-")

14:06 There is a replace function in clojure.string

14:06 But, you might as well just use .replace

14:06 LOPP: well

14:07 gotta install some build tools for clojure already

14:07 can't even use this contrib stuff

14:07 Raynes: clojure.string isn't contrib.

14:12 LOPP: what's the difference between use and require?

14:12 dnolen: clojurebot: use

14:13 I forget how do you ask clojurebot something?

14:13 nDuff: LOPP, whether the references are made available under their own namespaces or copied into the local namespace

14:13 dnolen: or is he out of commission?

14:13 raek: LOPP: the difference is how you refer to the vars of the other namespace

14:14 cemerick: clojurebot's been down for a while

14:14 raek: (require 'foo.bar) (foo.bar/some-function ...)

14:14 cemerick: -> (println "Enter sexpbot!")

14:14 sexpbot: ⟹ Enter sexpbot! nil

14:14 raek: (use 'foo.bar) (some-function ...)

14:14 Raynes: http://stackoverflow.com/questions/3408076/difference-in-clojure-between-use-and-require

14:14 raek: LOPP: ...but mostly you use these with the :as and :only options:

14:15 (require '[foo.bar :as bar]) (bar/some-function ...)

14:15 (use '[foo.bar :only (some-function)]) (some-function ...)

14:15 :as introduces a shorter alias for the namespace

14:16 hiredman: ping?

14:16 raek: :only makes use only make some of the vars available without namespace prefix (in any case, you can always us the full namespace qualified name)

14:17 Raynes: hiredman: Have you considered factoring out your sandboxing stuff into a separate library? Maybe contribify it.

14:29 jlaskowski: hi

14:29 in c.c.monads

14:30 there's flatten* function used

14:30 where can I find what it does?

14:30 I can find the one without the star

14:30 but not the one w/ it

14:32 raek: you could do something like this:

14:32 (in-ns 'clojure.contrib.monads)

14:32 (resolve 'flatten*)

14:32 that will tell you where it is defined

14:32 lrenn: it's private.

14:32 http://github.com/clojure/clojure-contrib/blob/master/modules/monads/src/main/clojure/clojure/contrib/monads.clj

14:33 jlaskowski: is it idiomatic to name private functions this way?

14:34 raek: no, the asterisk usually means something like "related variant to"

14:34 tomoj: defn: happen have that keynote audio link handy still?

14:34 raek: like bound-fn and bound-fn*

14:35 jlaskowski: thanks

14:35 that helped a lot

14:35 found it

14:45 KirinDave: So, static gen-class methods in my project, just totally broken. :\

14:46 Pretty brutal as brutal things go

14:48 cemerick: KirinDave: def'ing as opposed to declaring the vars is a no-go?

14:48 KirinDave: cemerick: Oh it works

14:48 As in it doesn't fail

14:48 but now it doesn't generate the static method

14:48 cemerick: you've done a clean build?

14:49 KirinDave: Yes

14:50 cemerick: what happened between the time it was generating the static method and now?

14:50 Raynes: ivey: I merged pushed your karma plugin to master. I lowered the default karma value to zero (makes more sense to me) and added some cooldown functionality so as to not encourage abuse.

14:51 KirinDave: cemerick: It was never generating the static method

14:51 i just got it to stop bailing with that erroneous error on compile

14:52 aha, progress

14:53 cemerick: KirinDave: https://gist.github.com/69ec769dc32b2995fae7

14:53 static methods in genclass work

14:53 (honestly) :-)

14:53 LOPP: Raynes: talking about Karma STM Conflict resolver?

14:53 KirinDave: I think they do

14:53 But

14:53 I suspect something I am doing is pissing them off.

14:53 Wouldn't be the first time something worked fine except in AOT.

14:53 Raynes: LOPP: A sexpbot plugin.

14:53 KirinDave: ... Honestly i am starting to wonder if i made a mistake picking clojure for this project tho

14:53 cemerick: Them? heh

14:54 KirinDave: I'm watching my co-worker hit a lot of problems trying to get scala to talk to clojure cleanly

14:54 Sure, this code worked well

14:54 LOPP: you work with scala and clojure? :) lucky guy

14:54 cemerick: KirinDave: problems, meaning?

14:55 KirinDave: cemerick: Poor Thomas is just having a hell of a time trying to pass things into clojure functions, for example.

14:55 cemerick: Puzzlement. Why?

14:55 KirinDave: And clojure maps trying to be java.lang.Maps but there are no template parameters.

14:56 alpheus: Is it dumb of me to put gigantic data structures into a set to get rid of duplicates?

14:57 chouser: I wrote a clojure library that is consumed effortlessly by our Java programmers

14:57 using gen-class with static methods, among other things.

14:58 Raynes: (inc ivey) for writing a neat karma plugin :>

14:58 sexpbot: => 1

14:59 ivey: Raynes: very cool. i'll pull so i can see the cooldown code

15:01 cemerick: (inc chouser), FWIW

15:01 sexpbot: => 1

15:01 cemerick: wha?

15:01 (inc chouser)

15:01 chouser: (inc cemerick), for (inc chouser)

15:01 cemerick: hrm

15:01 sexpbot: => 2

15:01 => 1

15:02 cemerick: waitaminute, karma?!

15:02 This is going to either get fun or be a disaster. :-)

15:02 KirinDave_: chouser: Maybe at some point I could offer you some sort of wonderful favor in exchange for some insights on java interop

15:02 chouser: Chief among my problems is passing maps back and forther.

15:02 err, forth.

15:03 Like, we need to exchange freeform data. Clojure is exceptionally good at this and Java, not so much.

15:03 Raynes: cemerick: Probably the latter. Hopefully the fact that you can't adjust someone's karma more than three times in 5 minutes will discourage abuse.

15:03 chouser: hm, I don't think we used maps. I think everything I offer the Java side implements an appropriate interface, so they're always calling specific methods of my objects.

15:03 KirinDave: (dec KirinDave_)

15:03 sexpbot: => -1

15:03 KirinDave: Awww

15:03 cemerick: KirinDave: is j.u.Map not good enough somehow?

15:04 KirinDave: Well

15:04 cemerick: Evidently because it doesn't provide template parameters there is some problem.

15:04 Or so Thomas said. I have no effin' clue.

15:04 That's what I thought it'd be.

15:05 chouser: can he not cast the map to a specific type of generic map?

15:05 cemerick: clojureMap.asInstanceOf[Map[KeyType, ValueType]]?

15:05 chouser: I never did try to put scala and clojure in the same project

15:06 fogus_: have you?

15:07 cemerick: I did in the very early days.

15:07 Haven't in many years though.

15:07 fogus_: chouser: Just as an exercise. Not in a production env.

15:15 ataggart: is anyone aware of a way to resolve ambiguous method resolution when dealing with nill args?

15:16 chouser: we

15:16 ew

15:16 maybe ^String (do nil)

15:16 bleh

15:16 ataggart: yeah, I tried typehinting and cast

15:16 neither worked

15:17 ,(.append (StringBuilder.) nil)

15:17 clojurebot: java.lang.IllegalArgumentException: More than one matching method found: append

15:17 ataggart: ,(.append (StringBuilder.) ^String nil)

15:17 clojurebot: Metadata can only be applied to IMetas

15:17 ataggart: ,(.append (StringBuilder.) (cast String nil))

15:17 clojurebot: #<StringBuilder null>

15:17 ataggart: orly

15:17 hmm

15:19 jarpiain: maybe ^String (identity nil)

15:20 ataggart: cast seems to work

15:20 which makes sense since that's how one would resolve it in java

15:41 jarpiain: ataggart: (.append (StringBuilder.) (cast String nil)) calls append(Object)

15:41 ataggart: jarplain: thank you! I was beating my head against a wall trying to figure out why another more complicated example wasn't working.

15:42 ok, so cast doesn't truly work

15:45 rhickey: cast just does a type check, it doesn't (can't) have polymorphic return type. could if it was a macro

15:45 ataggart: jarpiain's suggestion of ^type (identity nil) works

15:45 it'd be nice if typehinting nil worked

15:46 maybe I'll work on that tonight

15:46 hiredman: ping?

15:46 clojurebot: PONG!

15:46 rhickey: nil reads as null, nowhere to put a hint

15:47 ataggart: drats

15:48 While you're here, there are a number of tickets that could be closed with the patch attached to https://www.assembla.com/spaces/clojure/tickets/445

16:09 ossareh: I should really know this, but I just can't rationalise it - what is the *key* difference between [] and '() ?

16:10 I see examples of this quite often ["a" '(1 2 3) "c"] - why would it not be written as ["a" [1 2 3] "c"] ?

16:12 dnolen: ossareh: different datastructures, list and a vector, it could easily be written the second way.

16:13 ossareh: I guess being a java 1.5+ guy I've only really used Lists, particularly in their generic sense, is a list vs vector conversation in clojure similar to the one that would be had in java ?

16:14 dnolen: ossareh: not really, lists have O(n) lookup and vectors have constant time lookup. lists are rare in clojure unless you're manipulating code in macros.

16:15 near constant time rather.

16:17 ossareh: aha, so in java you can myList.get(x) which is the same as (nth our-vector x)

16:18 OK, I get it.

16:18 Thanks dnolen

16:18 I'll probably ask again in a few weeks ;)

16:19 bobo_: do i remember wrong if i think arraylist has constant time lookup?

16:20 dnolen: bobo_: it does, but I was only referring to list and vectors in clojure, not java.

16:21 bobo_: yeh, but then you could perhaps compare it to linkedlist vs arraylist?

16:43 vibrant: ok so what if i have something like (def game {:player { some map } :units [vector of maps]})

16:43 should i make everything one big atom, or the vector an atom, or individual units atoms?

16:46 raek: when making them interact with each other, it's probably easier to have the as their own refs/atoms

16:46 I read some interesting articles about game programming in functional languages

16:47 vibrant: because right now i have :animations there and when I want to add one I can either make a function getting and returning the game object (without using atoms), or make a function which swap!s something in a global game object

16:47 raek; i didn't gety our first sentence

16:47 can you point me to those articles? but i guess they won't discuss atoms unless they are about games in clojure.

16:48 raek: http://www.st.cs.uni-sb.de/edu/seminare/2005/advanced-fp/docs/sweeny.pdf

16:48 I found that interesting

16:49 I was thinking about when you want to apply rules of physics, etc

16:49 vibrant: ok. well right now i have a triangle which rotates

16:49 raek: thing A uses special power on thing B

16:50 vibrant: now i want to make it shoot :)

16:50 raek: ah, here it is: http://prog21.dadgum.com/23.html

16:51 and here http://prog21.dadgum.com/54.html

16:52 I have a feeling that it is easier to do a shoot function that only has to do touch the two involved parties, rather than having a one that gets the whole world and creates a new world with some things changed

16:53 especially if you want to make these changes concurrent

16:53 vibrant: right now the shoot function has to append something to the game map {:animations []}

16:53 append that bullet

16:53 then some animate function will have to step all the animations in there modifying them of course

16:54 raek: ref ganularity is indeed not a trivial issue...

16:56 vibrant: yeah so maybe i should just have a global +animations+ vector?

16:56 according to these articles

16:58 raek: clojure lets you mutate certain explicit points in a controlled manner. I would guess that the article doesn't explore that possibility very deeply.

16:58 I am by no means experienced in making games in clojure

16:58 vibrant: i'm determined to write one.

17:02 raek: but a general idea could be to model things that behaves as an entity that changes over time but still remains identifiable with a ref or atom

17:02 if a unit only consists of the keys :image, :pos, and :hp, all these might vary during the game

17:03 vibrant: yup

17:03 raek: but a ref is something that represents an identity

17:04 the states a ref changes between might have nothing in common

17:05 either, the identities of the objects could be their indicies in the units vectors of the world

17:05 or it could be their ref

17:05 I think the latter case would be simpler

17:06 I got to go now, but good luck and happy hacking!

17:07 vibrant: ok thanks!

17:09 nickik: whats the best way to get 1 from "1"?

17:10 tonyl: (Integer/parseInt "1")

17:11 ->(Integer/parseInt "1")

17:11 sexpbot: ⟹ 1

17:11 tonyl: ,(Integer/parseInt "1")

17:11 clojurebot: 1

17:11 tonyl: yeah clojurebot is up

17:12 drewr: ,(Integer. "1")

17:12 clojurebot: 1

17:12 nickik: ,(Integer. "1")

17:12 clojurebot: 1

17:12 nickik: hehe

17:12 is that the same or does parseInt provide something more=

17:13 drewr: parseInt can also take a radix

17:13 philjordan: also note that Integer obviously is limited in range

17:14 you might want (BigInteger. "12345678901234567890") instead

17:17 rhickey: Anyone tried Google Closure js lib, esp the template engine?

17:21 * rhickey imagines a macro package that lets you write Google Closure templates in Clojure

17:21 wlangstroth: yep - they're nifty, but kind of an extra step; anything specific?

17:22 chouser: mongodb's query language is (mostly) homoiconic js objects.

17:23 which nearly led me to design a homoiconic minilanguage for its map and reduce steps too, before I came to my senses.

17:24 rhickey: ick

17:24 wlangstroth: rhickey: ah, yes - that would convenient for an all-Clojure set-up; you wouldn't have to switch gears mentally to JavaScript

17:24 chouser: the minilanguage would have of course been expanded, via javascript "macros" into javascript source strings and then eval'ed. bleh.

17:24 rhickey: most interesting is generating Closure template fns that run on the client

17:25 nickik: @rhicky did you see the presentation of the "The Deadline" Guys too?

17:25 rhickey: nickik: yes

17:26 I always thought GXP was a great design, but largely ignored

17:26 nickik: GXP?

17:27 rhickey: http://code.google.com/p/gxp/wiki/WhyGxp

17:27 dysinger: <3 that rhickey's clojure book list has a hammock at the bottom. :)

17:28 rhickey: dysinger: the list is maxxed out, so I couldn't add the stand :(

17:33 nickik: rhickey: In dylan multimethods you can dispatch stuff like integer = 1. Did you consider something like that for clojure?

17:49 duncanm: is there a char->integer method somewhere?

17:49 i mean, integer->character

17:50 nickik: try char

17:50 duncanm: ah

17:50 Character/forDigit

17:50 nickik: ,(char 99)

17:50 clojurebot: \c

17:50 nickik: ,(inc \c)

17:50 clojurebot: java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number

17:50 duncanm: i want (char 1) -> \1

17:50 raek: duncanm: from where did you get the integer?

17:50 LOPP: it's easy

17:50 nickik: ,(int \c)

17:50 clojurebot: 99

17:51 raek: if you got it from read(), then (char the-int) should be fine

17:51 LOPP: char c -> int i = c - '0'

17:51 ,(int (\6 - \0))

17:51 clojurebot: java.lang.ClassCastException: java.lang.Character cannot be cast to clojure.lang.IFn

17:51 LOPP: ,(int (- \6 \0))

17:51 clojurebot: java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number

17:52 LOPP: man, clojure has a problem with perfectly good java code :P

17:52 goddamn wrappers

17:52 raek: what I actually wanted to say was that you have to consider what the integer represents... is it a unicode code point number (like the one read() returns)? is it a digit?

17:52 LOPP: ,(int (- (char \6) (char \0)))

17:52 clojurebot: java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number

17:53 raek: \0 is already a character

17:53 LOPP: I know

17:53 but not char

17:53 it's Character

17:53 raek: ,(- (int \6) (int \0))

17:53 clojurebot: 6

17:53 LOPP: that's why I can't do arithmetric with it

17:53 ok

17:54 that works I guess

17:54 raek: no, you can't do arithmetic with chars/Characters because they don't represent numbers

17:54 well

17:54 LOPP: char does

17:54 raek: they can be coded as numbers (which is the interpretation of the cast)

17:54 LOPP: try to substract two chars in java, I think it works

17:54 nickik: ,(first (seq (str 1)))

17:54 clojurebot: \1

17:54 nickik: ugly :)

17:55 LOPP: (.toCharArray (.toString 1))

17:55 :P

17:56 raek: ,(-> 1 str first)

17:56 clojurebot: \1

17:56 LOPP: ,(Character. 1)

17:56 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Character

18:02 LOPP: found it

18:02 (Character/forDigit 9 10)

18:02 ,(Character/forDigit 9 10)

18:02 clojurebot: \9

18:39 * raek discoveres Land of Lisp

18:40 raek: ...and it mentions Clojure!

18:41 technomancy: it also implies that CLOS is hot stuff... o_O

18:43 dnolen: technomancy: what, you don't like CLOS ?

18:51 technomancy: not so much

18:51 it has a lot of features

19:06 hiredman: ping?

19:06 clojurebot: PONG!

19:10 nickik: i orderd the land of lisp. I want to support people that write books on lisp today. He sais on HN. I used Commen Lisp but tried to include some aspects of the new lisps.

19:12 http://landoflisp.com/ follow the arrow down its well worth it !!!!!

19:13 n8

19:19 amalloy: hi, #clojure! nice to be back since my office, despite being a web company, has had no internet connection all day

19:19 tomoj: that happened to us, but the engineer had a mobile clear router thingy :)

19:21 amalloy: well, this happens to be a day our DBA/IT guy is out of town, so...

19:23 ohpauleez: amalloy: Weird, I was in a similar situation too

19:24 amalloy: crazy

19:25 ohpauleez: amalloy: Were you at conj?

19:25 amalloy: ohpauleez: no, sadly not

19:25 but we're definitely not in the same company :P

19:26 ohpauleez: haha

19:26 I also was sadly not at conj. I had to cancel my plans

19:26 amalloy: we're a startup in sf, with ~8 engineers. two pauls, but no deGrandis's

19:28 ohpauleez: ahh. Too bad. I hear that dude is a total ace engineer :P

19:33 amalloy: ohpauleez: well, we're hiring! let him know if you see him

19:46 _seanc_: Howdy folks. I have another question pertaining to the '&' and it's usage. In some sample code there had fn [&], how would you reference the passed in arguments in that circumstance?

19:49 Raynes: _seanc_: (fn [&]) doesn't work.

19:49 tonyl: has to be (fn [& rest])

19:49 Raynes: However, (fn [& args]) just tells Clojure to put all arguments passed after the & into a sequence named args.

19:49 tonyl: can change rest for whatever name you want

19:50 _seanc_: Ok, perhaps the code wasn't correct. I'm not savvy enough to catch those things

19:50 amalloy: ,((fn [& args] args) 1 2 4 :a)

19:50 clojurebot: (1 2 4 :a)

19:50 Raynes: -> ((fn [x & args] (println x args)) 1 2 3 4)

19:50 sexpbot: ⟹ 1 (2 3 4) nil

19:50 Raynes: amalloy: You're a traitor, you know. Working on sexpbot, but still using it as a backup when clojurebot isn't working. :P

19:50 _seanc_: Trying to familiarize myself enough with Clojure to try my hand at Compojure. I appreciate your help guys :)

19:50 amalloy: Raynes: i need to get into the habit of using sexpbot. clojurebot seems to be down a lot more

19:51 Raynes: tbh it's just the -> vs , thing. , is so easy to type

19:51 Raynes: amalloy: sexpbot's sandbox isn't quite as good. I need to fix a few bugs in clj-sandbox in order to get a sandbox that works pretty much the same as clojurebot's. Right now it's running on a whitelist rather than a blacklist, which it should be running off of.

19:51 &(println "ohai")

19:51 sexpbot: ⟹ ohai nil

19:52 amalloy: yeah, i've noticed it refusing a lot of totally reasonable requests

19:52 Raynes: I'm accepting suggestions for new evaluation prefixes. It's actually more challenging than you might expect, since sexpbot is in so many channels, many with other bots. It's difficult to choose prefixes that people don't accidentally use, and aren't already used by other bots.

19:53 I could just steal clojurebot's sandbox for the time-being, but I'd really, really rather not.

19:54 Anyways, & works the same as ->.

19:54 amalloy: ah

19:54 Raynes: per-channel prefixes perhaps?

19:56 Raynes: That's a possibility. Gets complicated for lots of channels though. That complication goes away if you have a default prefix with overriding prefixes for various channels. It's still a little blah, because then you have people in other channels trying to use the evaluation with one prefix that only works in channel x.

19:56 amalloy: yeah

19:56 i was thinking the other way though: N default prefixes, with per-channel "don't use this" settings

19:59 Raynes: Licenser: You wouldn't happen to be around, would you?

19:59 amalloy: &"do you mind spaces before the &?"

19:59 & "or after?"

19:59 sexpbot: ⟹ "or after?"

19:59 Raynes: What he said.

20:00 amalloy: yeah, that's what i guessed, but figured i might as well check

20:00 ,"what about you?"

20:05 Raynes: so what do you think about several prefixes with per-channel "but not these prefixes" settings? that sounds easy enough for me to add if you like it

20:06 Raynes: amalloy: It can't hurt. Go for it. I'm improving the timer plugin at the moment.

20:06 And by improving, I mean breaking of course.

20:07 amalloy: cool. well at the moment i'm on a netflix/tv marathon, but i can do it by tonight or tomorrow prolly

20:07 Raynes: Cool. When you do, I'll make the prefix a period for Clojure.

20:08 There is only one channel that sexpbot is in (that I can think of) where a period would cause problems.

20:08 amalloy: ah

20:08 nice

20:08 what about when the answer to someone's question is .replace

20:13 but i guess that's a fairly rare case, and it's pretty easy to ignore if he does that

20:18 Raynes: amalloy: That's a sucky edge-case. Damn you people and your one-word replies.

20:18 amalloy: Anyways, it was just one idea.

20:18 amalloy: yeah

20:18 the general idea is still good; that's just a detail

20:18 Raynes: It might be a good idea to post a mailing list thread and just see what everybody would be happy with.

20:18 Of course, I'm not going to really focus on the perfect prefix until I have the perfect evaluation. If it isn't as good as clojurebot's, it shouldn't even be here.

20:54 amalloy: Raynes: what do i have to do to enable eval?

20:54 Raynes: amalloy: -> #clojure-casual

21:40 hiredman: ping?

21:40 clojurebot: PONG!

21:41 tonyl: is clojurebot fully functional?

21:42 *ns*

21:42 ,*ns*

21:42 clojurebot: #<Namespace sandbox>

21:45 amalloy: tonyl: he's sandboxed - he won't do things that might be evil

21:45 ,(def println 'delete-my-hard-drive)

21:45 clojurebot: DENIED

21:46 tonyl: understandable

21:47 ->(def println 'delete-pri)

21:47 sexpbot: ⟹ #'net.licenser.sandbox.box7352/println

21:47 tonyl: ->println

21:47 sexpbot: ⟹ delete-pri

21:48 amalloy: but he's fully functional in that he evaluates clojure stuff:

21:48 ,(take 15 (iterate (fn [[a b]] [b (+ a b)]) [1 0]))

21:48 clojurebot: ([1 0] [0 1] [1 1] [1 2] [2 3] [3 5] [5 8] [8 13] [13 21] [21 34] ...)

21:48 amalloy: ,(map second (take 15 (iterate (fn [[a b]] [b (+ a b)]) [1 0])))

21:48 clojurebot: (0 1 1 2 3 5 8 13 21 34 ...)

21:48 tonyl: great

21:49 wonder what was the problem

21:49 who manages clojurebot?

21:49 amalloy: in what?

21:49 hiredman owns him

21:49 other people contribute some, but he's the "manager", if you like

21:50 tonyl: ok, i'll look into the source code, just wondering how it works

21:50 amalloy: clojurebot: source?

21:50 clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

21:52 tonyl: thanks amalloy

21:53 trptcolin: so i just submitted my first clojure.contrib patch (ticket 35 on assembla) - do i need to post to the mailing list or will the powers-that-be just find my patch since i marked the ticket as "Test"?

21:54 cemerick: trptcolin: and tag the patch file with "patch"

21:54 hiredman: ~contrib ticket #35

21:54 clojurebot: {:url http://tinyurl.com/27bhpfo, :summary "clojure.contrib.trace/deftrace does not work with function definitions with doc-strings", :status :test, :priority :normal, :created-on "2009-10-09T19:22:46...

21:56 trptcolin: cemerick: tagged.

21:56 hiredman: that's pretty rad

22:01 hiredman: ~ticket search recur

22:01 clojurebot: ("31-recur-across-try.diff" "31-recur-across-try2.diff" "#31: GC Issue 27:\tDisallow recur across try" "#258: can't recur from case special form" "#31: GC Issue 27:\tDisallow recur across try" "#31: GC Issue 27:\tDisallow recur across try" "#283: recur ignores rest args" "#283: recur ignores rest args" "#444: Infinite recursion in Keyword.intern leads to stack overflow" "#92: GC Issue 88: \t Add :let support for 'doseq'

22:01 hiredman: ~ticket #31

22:01 clojurebot: {:url http://tinyurl.com/25ll5ey, :summary "GC Issue 27: Disallow recur across try", :status :test, :priority :normal, :created-on "2009-06-17T16:06:57-03:00"}

22:07 hiredman: ugh, time to rewrite for jira

22:17 technomancy: trptcolin: bizarre that docstrings affect dotrace.

22:17 oh wait, deftrace... never mind. I only use dotrace.

22:18 trptcolin: right, i don't think i've used deftrace either

22:23 technomancy: did you see i moved the subtask help stuff last night? i'm wondering if it could also have applications for `lein help` at the base level...

22:24 technomancy: I haven't gotten a chance to look at it... was doing some profiling of test.

22:25 trptcolin: ah ok, cool no worries

22:44 _seanc_: Hey guys, I'm looking through the Clojure site and a few others, I can't find what `^String` means. Am I to believe that is some kind of shortcut for Java classes?

22:44 amalloy: _seanc_: it's a type hint

22:44 you're telling the compiler "this object will be of type String"

22:45 if it doesn't have hints it will use reflection to find the appropriate methods to call when doing java interop; hints can speed up execution by using actual method calls instead of reflection

22:46 (do not overuse this feature)

22:46 _seanc_: I'm looking through the hiccup source, the defn escape-html has this. Doesn't make sense to me

22:47 amalloy: link?

22:47 clojurebot: your link is dead

22:47 _seanc_: http://github.com/weavejester/hiccup/blob/master/src/hiccup/core.clj

22:47 amalloy: ugh, screw you clojurebot

22:47 _seanc_: escape-html is asserting that the result of (as-str text) will be a String

22:48 that way, the compiler can resolve the (replace) calls at compile time instead of run time

22:49 _seanc_: wow, that confuses me. Ugh

22:50 amalloy: yeah, just ignore any type hints you see; pretend they're just for the compiler, though some people prefer to use them for other purposes

22:50 you won't lose anything

22:52 _seanc_: Alright, thanks amalloy

22:59 amalloy: ,1

22:59 clojurebot: 1

22:59 amalloy: ->1

22:59 sexpbot: ⟹ 1

22:59 amalloy-sexpbot-: ⟹ 1

22:59 amalloy: .1

22:59 amalloy-sexpbot-: ⟹ 1

22:59 amalloy: woo

23:00 cemerick: whoa, they're multiplying!

23:01 amalloy: cemerick: just added a feature to sexpbot to let him use different eval prefixes in different channels, so he doesn't need something globally unique

23:01 Nafai: cemerick: Question, is there a tools.nrepl client implemented yet?

23:05 technomancy: multiplying sexpbots? let's keep it PG-13 in here.

23:06 http://wondermark.com/136/

23:06 sexpbot-test: "Wondermark » Archive » #136; Which may not be appropriate for Children"

23:06 dysinger: technomancy: :)

23:08 hiredman: ugh

23:08 amalloy: heh. my adjustment to sexpbot has (set (get ...)) - almost looks like mutable state!

23:09 hiredman: so I need to add ignores for multiple other sexpbots now?

23:09 amalloy: hiredman: no

23:09 Raynes: amalloy: If you're going to test sexpbot anywhere, do it in #(code) or #clojure-casual.

23:09 hiredman: What's your problem with sexpbot? And me, for that matter.

23:09 You seem to make it a goal to ignore me.

23:09 amalloy: Raynes: i know. i tested him in tempchan and stuff, but wanted to 100% confirm it in #clojure before committing

23:10 since the whole idea was to have per-channel settings

23:10 cemerick: Nafai: Yes, it's there already; see clojure.tools.nrepl/connect, and the tests for examples

23:10 the docs will get some more love shortly

23:10 Nafai: Cool

23:10 Raynes: I guess he has me ignored as well.

23:11 I wonder what I ever did to him. :\

23:12 amalloy: oh haha, sorry. i see what you mean; i thought i'd logged him out of #clojure

23:13 defn: Raynes, maybe he's off doing something else, but regardless don't worry about it. Some people on IRC take issue with anything that contributes to "noise", where noise is a very ambiguous term meaning many things.

23:14 amalloy: defn: Raynes isn't actually offended, bet you a million dollars

23:14 defn: amalloy: a million? that's all you got?

23:14 replaca: technomancy: are user plugins in the current lein?

23:14 defn: amalloy: did you get a chance to listen to the audio i posted?

23:14 amalloy: no, what audio?

23:14 defn: the rich talk at clojureconj

23:14 one of them anyway

23:15 i have the other one one the new 1.3 performance stuff

23:15 havent ripped it yet

23:15 Raynes: I'm not really offended. I just have no clue what I ever did to cause such dislike. I should have asked him at the Conj, when he could only physically ignore me. :\

23:16 Nafai: defn: link to the audio?

23:17 technomancy: replaca: yeah.

23:21 defn: Nafai: sure

23:22 Nafai: http://db.tt/TK5M0ch

23:22 it cuts off the first minute or two but the good stuff came later anyway

23:22 Nafai: Thanks!

23:23 replaca: technomancy: cool, thx

23:23 technomancy: when you do a lein cmd for it, will it pull straight from a repo?

23:23 defn: how does one convert a decimal to a ratio?

23:24 tomoj: a decimal, really?

23:24 or a float/double?

23:24 defn: didn't mean the type there, sorry

23:24 double

23:24 i have 2.666667, but (rationalize... is not giving me what I need

23:25 tomoj: that's a difficult problem

23:25 defn: :)

23:25 (hopefully one that someone else has solved! :)

23:25 tomoj: I think all you can really do in most cases is find ratios which approximate the double well

23:25 maybe you try to pick the lowest denominator which has low error

23:26 defn: you need to guess at closed forms

23:26 yeah

23:26 good idea

23:26 trying that out...

23:26 tomoj: dunno how low you'd have to restrict the error to get good results

23:27 technomancy: replaca: yeah, that's merged in snapshot. "lein plugin install swank-clojure 1.3.0-SNAPSHOT"

23:27 cemerick: defn: Hey :-) Have you recovered from the conj yet?

23:28 defn: cemerick: wow. still working on it to be perfectly honest. the last night was just a blur.

23:28 my brain was loaded sufficiently to induce a plane-coma

23:29 sproust: I was stuck at the airport the whole sunday. Broken part on plane, and full flights due to "parent week."

23:29 defn: what the hell is parent week?

23:30 cemerick: defn: Same here. Then there was breakfast with Rich, Christophe, and Laurent. That didn't help. :-)

23:30 sproust: BUT we had tethering from a cell phone and our laptops :-)

23:30 technomancy: man... there is nothing like committing to git on a plane.

23:30 sproust: (and some Clojure goodness)

23:30 defn: sproust: did we meet?

23:30 technomancy: oh... except pulling from another passenger using gitjour.

23:30 tomoj: I think you can actually work it out formally

23:31 where are these doubles coming from?

23:31 defn: technomancy: we need to do a *nerd-version* of "I'm on a boat.", except it's "On a Plane", with git.

23:31 sproust: defn: Yes. Was sitting on the right side for a while with Julie, talked between talks.

23:31 (In the front)

23:31 hiredman: technomancy: yes, that is something for adrenaline junkies

23:31 defn: tomoj: something i have no control over programatically, 2.66667 is all i get

23:32 tomoj: but I mean.. how are they created?

23:32 defn: sproust: michael?

23:32 technomancy: ,o/

23:32 clojurebot: Invalid token: o/

23:32 tomoj: if they're created from fractions with small denominators, this method will work well

23:32 technomancy: ...

23:32 ~o/

23:32 clojurebot: \o ... High five!

23:32 * defn kills himself due to the ascii

23:32 sproust: Is there an end to clojurebot? How many billion features does it have?

23:32 tomoj: because if the denominator is low enough, you will find a low denominator that closely matches the double

23:33 defn: must. get. bigger.

23:33 clojurebot: skynet?

23:33 clojurebot: I will become skynet. Mark my words.

23:33 technomancy: sproust: that's just request/response. composability

23:33 defn: tomoj: mmm, interesting

23:33 tomoj: but if the denominator gets too big, it will exceed the double error rate and you'll get weird results, I think

23:35 defn: tomoj: im just messing with some recurrence relationship homework

23:35 tomoj: basically you're taking a grainy picture of the reals and breaking it up into subsets of the rationals like {a/b in Q | b<i}

23:35 defn: i figured out how to programatically do it

23:35 tomoj: I started on it, but haven't finished

23:35 defn: there's a common factor -- i just got bored calculating the first 10 in a sequence

23:35 i just wanted to map over a sequence

23:36 tomoj: can you use it to approximate pi as a fraction?

23:36 defn: hell no

23:36 im avoiding the problem

23:36 tomoj: oh, I see

23:36 defn: :)

23:36 that'd be fun to write though

23:36 im just doing homework and am sick of working out 10 calculations per problem in the problem set

23:41 replaca: technomancy: perfect. How'd you know that's what I wanted to install? :)

23:43 defn: cemerick: how far did you and george get on the CDT discussion?

23:43 cemerick: defn: we have a plan for Eclipse / NetBeans

23:43 really, any Java-based IDE that uses JDI

23:49 tomoj: defn: https://gist.github.com/abd1d5806736a8a60fa1

23:54 defn: cemerick: glad to hear it

23:54 kudos

23:55 cemerick: well, let's see how well we can get the thing built first :-)

23:55 defn: i have faith.

23:55 cemerick: heh

23:56 defn: george is one of the smartest guys ive ever met

23:56 or at least i perceived him that way

23:56 cemerick: I only go to talk with him for an hour or two, but that doesn't seem unreasonable. :-)

23:57 defn: the only people i had trouble talking with over the conj were people who insisted on talking about their crappy .NET jobs

23:57 not many of them, but a few

23:57 it's like "yeah dude, I get it, your life sucks -- we're here to have fun."

23:58 cemerick: heh

23:58 defn: i kid the .NET people, im just being snarky

23:58 cemerick: The jobs may suck, but C# is pretty damn nice as things go.

23:58 defn: what i was /going/ to say was I don't think I met anyone who didn't seem less than abnormally intelligent

Logging service provided by n01se.net