#clojure log - Apr 09 2010

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

0:00 technomancy: Licenser: right, dependency on leiningen is implied for plugins; you don't need to add it explicitly

0:00 defn: aww i dont wanna give up my swank-clojure-project

0:00 * defn throws a tantrum

0:01 Licenser: hmm didn't worked for me on the other hand it seems I don't need the refference any more due to changes in code :)

0:01 technomancy: (defun swank-clojure-project () (interactive) (shell-command "lein swank") (slime-connect 4005)) ;; =)

0:01 defn: haha technomancy

0:01 well played

0:01 and thank you

0:03 Raynes: $walton juxt

0:03 sexpbot: Raynes: http://getclojure.org:8080/examples/juxt

0:03 Raynes: Aw.

0:03 defn: haha yes, juxt is broken atm

0:03 $walton concat

0:03 sexpbot: defn: http://getclojure.org:8080/examples/concat

0:04 Raynes: defn: Does walton not use any examples that don't get through clj-sandbox?

0:04 If so, I imagine a whole bunch of everything is broken.

0:04 And if that's the case, I might have motivation to go through most of the clojure.core API tonight.

0:04 So that Licenser can push a new release tomorrow.

0:04 :p

0:05 defn: Raynes: they're supposed to if no good examples are found -- there is a bit of logic that needs some TLC in walton to make that work properly i think

0:05 technomancy: Licenser: "lein-search" might be a general enough name

0:05 * Raynes still has motivation.

0:05 technomancy: since the other tasks seem to also involve searching

0:05 Raynes: Because sexpbot's evaluation is generally useless at the moment.

0:05 Licenser: technomancy: heh I came up with exactly that name :D

0:06 technomancy: I'm going to have to do a "plugin roundup" blog post soon

0:06 this is good stuff

0:06 Licenser: and it seems to work, this plugin stuff, if you don't need lein internal deps (they don't seem to like me) works great :)

0:07 lein search clj-sandbox

0:07 Results for clj-sandbox:

0:07 clj-sandbox/clj-sandbox: 0.2.9-SNAPSHOT, 0.2.8-SNAPSHOT, 0.2.7-SNAPSHOT, 0.2.6-SNAPSHOT, 0.2.5-SNAPSHOT, 0.2.4-SNAPSHOT, 0.2.3-SNAPSHOT, 0.2.2-SNAPSHOT, 0.2.10-SNAPSHOT, 0.2.1-SNAPSHOT, 0.2.0-SNAPSHOT, 0.1.3-SNAPSHOT, 0.1.1-SNAPSHOT, 0.1.0-SNAPSHOT

0:07 :)

0:07 Raynes: $((juxt (partial + 3) (partial + 4)) 5)

0:07 sexpbot: DENIED!

0:07 Raynes: :(

0:07 technomancy: cools

0:07 Raynes: showertime

0:08 pandawa: SOWERTIME

0:08 brian__: noob question on macros > a macro to do this: (def <exp> 1) -> (defmacro useless [expr ] (it works) but I would like to see the actual code from macroexpand, but I just get ( macroexpand-1 (useless b))

0:08 #'user/b , any way to do that?


0:08 (list 'def expr 1))

0:10 sorry , the macro is: (defmacro useless [expr ]

0:10 (list 'def expr 1))

0:10 carkh: you miss a quote in your macroexpand

0:10 brian__: ok

0:10 carkh: ( macroexpand-1 '(useless b))

0:10 brian__: thx

0:15 Licenser: hmm there is no version 2.1.0 of clojure.contrib :P

0:16 there we go [lein-search/lein-search "0.1.0-SNAPSHOT"] in the dev dependencies and many worries are gone :D

0:16 defn: tomoj: still can't get it to work

0:16 tomoj: how did you include the js?

0:16 tomoj: I didn't, I just got it to work in my toy example

0:17 defn: right, but when you did your toy example, what path did you use to include your dummy js

0:17 tomoj: (wrap-file my-app "resources/public"), resources/ on the classpath, js file in resources/public/foo/bar.js, then /foo/bar.js will serve the js file

0:18 (I didn't have any dummy js)

0:18 * defn sighs

0:18 defn: i give up for now

0:18 tomoj: just take out the ..'s

0:18 defn: yeah, did that, still nothing

0:19 tomoj: also take out the resources/public/

0:19 but I guess you probably tried that too

0:20 carkh: what is wrap-file returning ?

0:21 tomoj: a ring app

0:21 defn: #<file$wrap_file__2697$fn__2698 ring.middleware.file$wrap_file__2697$fn__2698@3d80ac61>

0:22 carkh: so there's no way to inspect the underlying file object ?

0:22 tomoj: you don't have an underlying file object at that point

0:22 carkh: maybe by calling the function with a fake request object

0:22 well that funtion is returning something

0:22 tomoj: wrap-file returns a function which knows how to get at the underlying file object

0:22 carkh: and that thing has a path

0:23 tomoj: that function returns a ring response.. dunno what's in it

0:23 carkh: if it's like older compojure must be a function looking like this : (fn [request] ...returns something in a pure way ..)

0:24 tomoj: yeah

0:25 carkh: so maybe try calling it like this (my-returned-function {:uri "/foo/blah"})

0:25 that's all based on compojure knowledge, which might not apply anymore =/

0:26 tomoj: looks like there's a file object indeed

0:26 carkh: ah then just inspect it and you can test easy !

0:26 tomoj: the :body of the response will be a File I think

0:26 carkh: oh but that's defn not you ....hum sorry

0:27 defn: yeah i really have no idea what to do here -- the code is on github carkh if you're interested

0:27 http://github.com/defn/walton

0:28 carkh: well you have to investigate what's the path of that file object

0:28 defn: oh, how?

0:28 carkh: hum

0:29 tomoj: you were right about :uri

0:29 that might work

0:29 you also need :request-method :get though

0:29 carkh: ((wrap-file my-app "resources/public") {uri "the/path/as/in/browser"})

0:29 ah right

0:29 just build a fake request =P

0:29 tomoj: need a / in front though

0:30 carkh: and uri is a keyword

0:30 tomoj: (walton-web {:uri "/foo/bar.js" :request-method :get})

0:30 not sure if some middleware is going to barf on that though

0:31 though, if the

0:32 if the File object were coming through, the path would be correct

0:32 and if the path were correct, it would work :)

0:32 carkh: it might be pointing to a place that does not exist

0:32 you can create any goofy File object you want

0:33 ,(java.io.File. "c:/hello/world")

0:33 clojurebot: #<File c:/hello/world>

0:33 tomoj: yeah, but it checks to see whether the file exists

0:33 carkh: wrap-file does the chack ?

0:34 check*

0:34 tomoj: if the file doesn't exist, it just defers to the app it's wrapping

0:34 yeah

0:34 hiredman: http://weblogs.java.net/blog/2009/06/11/asm-now-supports-invokedynamic oooh

0:34 tomoj: well, the function wrap-file returns does, anyway

0:36 carkh: last ressort : you could copy the wrap-file code into your own wrap-fil and instrument it to see what's hapenning

0:38 defn: tomoj: carkh: wrap-file does complain when the path doesn't exist

0:38 tomoj: we're talking about different paths

0:39 if the root path doesn't exist wrap-file will barf at compile time

0:40 if the path the http client requests doesn't exist under the root path, it should just run your app, not complain

0:48 * defn buries his head in a bowl of pudding

0:51 Licenser: defn: you share?

0:51 defn: Licenser: go on and stick your head in!

0:52 Licenser: woooh

0:54 defn: tomoj: i think i fixed it

0:55 im created a route which will match a regex for .js and .css and serves up a static file using (file-response)

0:57 now i just need to remove these pesky line numbers...

0:57 tomoj: carkh: thanks for your help

1:00 tomoj: wrap-file is supposed to do that stuff for you :(

1:00 oh well

1:03 defn: how can i turn a string into executable clojure?

1:03 like "(+ 1 2 (+ 3 4))" => (+ 1 2 (+ 3 4))

1:03 Licenser: read?

1:04 tomoj: ,(read-string "(+ 1 2 (+ 3 4))")

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

1:04 defn: oh right, thanks

1:05 what about if I want to take the value returned by (read-string "(1 2 3)"), and quote it? I can't (quote (read-string "(1 2 3)"))

1:08 Licenser: it is already quoted

1:10 scottj: say you want to share setup and tear down among several tests, how would you do that? right now I have a let inside a deftest and I have a bunch of is statements that actually test different stuff bc I want to share the let. I don't want a let around all the tests bc then it won't happen each time test is executed

1:21 lancepantz: scottj: fixtures in clojure.test

1:29 brian__: wondering why I get this 'nil' in a macro: (macroexpand-1 '(useless-3 :toys :count toys))

1:29 (defmethod count-cat [:toys :count] [category action value] nil) , the macro is here: http://clojure.pastebin.com/qVsw04Za

1:34 hiredman: ,( 'dosync ( 'alter expr3 'inc ))

1:34 clojurebot: java.lang.Exception: Unable to resolve symbol: expr3 in this context

1:34 hiredman: ,( 'dosync ( 'alter 1 'inc ))

1:34 clojurebot: nil

1:34 hiredman: you are calling the symbol 'dosync as a function

1:35 brian__: I thought the ' stopped that

1:36 hiredman: lists are function calls

1:36 (foo bar) is a list

1:37 brian__: so you can't create a list in a macro?

1:37 hiredman: you can

1:37 lancepantz: ,(first (re-seq #"\d+" "foo:123"))

1:37 clojurebot: "123"

1:37 lancepantz: ,(int (first (re-seq #"\d+" "foo:123")))

1:37 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Character

1:37 hiredman: http://clojure.org/reader

1:38 brian__: quoting quotes the immediately following form

1:38 lancepantz: ^ why does that not work

1:38 hiredman: 'foo is the quoted symbol foo

1:39 ('foo) is trying to call the symbol foo as a function

1:39 brian__: ok

1:39 hiredman: lancepantz: what is the output of re-seq?

1:40 lancepantz: ("123")

1:40 brian__: but in halloways book, he uses 'if to stop if from evaluating

1:40 hiredman: brian__: right, that is what quoting does

1:40 lancepantz: i guess i need to use parseInt

1:40 hiredman: lancepantz: and after you call first on it?

1:40 lancepantz: "123"

1:40 brian__: but not in a list?

1:40 hiredman: and what does int do?

1:40 brian__: sure in a list

1:40 lancepantz: coerce to an integer?

1:41 hiredman: what does the doc say?

1:41 brian__: then why not ( 'dosync ... ?

1:41 lancepantz: At times it is necessary to have a value of a particular primitive type. These coercion functions yield a value of the indicated type as long as such a coercion is possible:

1:42 hiredman: brian__: 'dosync evaluates to the symbol dosync

1:42 if the symbol was not quoted it would evaluate to the function named by the symbol dosync

1:42 brian__: so is it possible to put dosync in a macro?

1:42 hiredman: yes

1:43 ,'dosync

1:43 clojurebot: dosync

1:43 hiredman: ,dosync

1:43 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/dosync

1:44 hiredman: ,['(+ 1 2) ('+ 1 2) (list '+ 1 2)]

1:44 clojurebot: [(+ 1 2) 2 (+ 1 2)]

1:47 brian__: ok, thnks

1:48 defn: when do you use require vs use?

1:50 lancepantz: use becomes a pain in the ass if you don't pass :only

1:50 Apage43: require allows you to alias a namespace instead of pull all of its symbols in

1:51 which allows you to avoid conflicts with their names.

1:53 defn: i think i have circular use deps

1:53 Apage43: rather, require just loads a lib and makes it available for use. use both loads it and pulls its symbols in.

1:53 defn: im not sure how to resolve them

1:54 Apage43: how did -that- happen

1:54 defn: ignorance

1:55 Apage43: i think the way to deal with that is to move the stuff around such that there aren't circular deps.

1:55 lancepantz: hahah

1:55 defn: Apage43: yeah but these pieces are logically not supposed to be in the same file

1:56 Apage43: but they depend on each other?

1:57 if so, there needs to be some abstraction

1:57 of those parts.

1:57 defn: yes. i have some layout code for an HTML doc which gets used in my -main, and some of the methods from the core which contains -main are used in the layout

1:57 Apage43: because even if they're 'supposed' to be seperate, they aren't seperate if they have circular deps.

1:57 yeah

1:57 you should probably pass those functions as params to the layout code

1:58 defn: *nod* -- maybe require :as, and then use them with their namespaces

1:58 Apage43: instead of have the layout code ref them directly.

2:03 defn: Apage43: nod that makes sense

2:44 licoresse: morning all

2:53 defn: is it possible to take a string like "abc", and use it as #'abc?

2:56 cemerick: ,(-> "clojure.core/+" symbol find-var)

2:56 clojurebot: #'clojure.core/+

2:56 cemerick: defn: ^^

2:58 defn: booya, thank you

3:20 slyphon: hrm

3:20 so, there doesn't appear to be a way with clojure.contrib.condition to have a "catch-all"

3:21 i guess i could use "derive"

3:35 defn: http://www.getclojure.org:8080/examples/concat <-- now with fancy syntax hilighting and docstrings (sometimes)

3:42 cemerick: defn: very nice :-)

3:42 defn: cemerick: it just died -- it's been acting... unpredictably...

3:43 Licenser: defn: sweet!

3:43 defn: aka it is a bug-ridden festering pile of code garbage :)

3:43 cemerick: It might be worthwhile to weight the ordering of samples based on who msg'ed them. e.g. list samples from Rich, chouser, Chousuke, hiredman, et al. ahead of other random people.

3:43 I mean, assuming the number of samples is large

3:44 defn: cemerick: yeah that's something ive considered for sure

3:44 cemerick: hrm, there's only 7 for seq, so maybe that doesn't matter

3:44 defn: cemerick: it's still building the list

3:44 if you refresh you can see them crop up

3:44 cemerick: ah

3:44 defn: but now it's dead again

3:44 * defn bangs head against wall

3:44 Licenser: cemerick: one reson migt be that the whitelist is still not really entirely full

3:45 cemerick: oh, there's a whitelist? Close enough, then.

3:47 Licenser: cemerick: yap for functions that are allowed and that are note

3:47 so if seq is used freuqently in a function not in the whitelist all this exampels fall out

3:50 Raynes: cemerick: "Not entirely full" is an understatement. I'll be trying to remedy that situation tonight.

3:50 defn: Raynes: Ping me with a new clojars sandbox version, would you?

3:51 Raynes: defn: Ask Licenser. I don't push new versions.

3:51 Licenser: I can gladly push 0.2.11

3:52 * Raynes starts wading through the clojure API.

3:52 Licenser: heh

3:53 pushed 0.2.11

3:53 w/o snapshot since I start to find this silly

3:53 defn: i just got an ebook reader. i htmlized the .core source and and have been reading it front to back

3:54 Licenser: :)

3:54 Licenser: heh

3:54 esj: salute

3:54 defn: esj: 'lo

3:54 Licenser: Raynes: I propably should work backwords on the api but I fear we'll get many ugly conflicts from merging

3:55 Raynes: Licenser: If you just keep me updated on what letter you're on, I think we can avoid conflicts.

3:56 _ato: defn: very nice

3:56 Licenser: Raynes: I talk about merge conflicts, if be both add something to say :list-fns we'll have to sort out later who added which so we can add all together

3:56 defn: _ato: thanks, but still a lot to do

3:56 zmila: defn examples/subseq - the doc is strange and the two examples are the same

3:57 defn: zmila: the doc is correct

3:58 Raynes: Licenser: Oh, I see.

3:58 defn: but the formatting might make it a little difficult to see they are all related

3:58 zmila: also, i will be removing duplicates soon

3:58 Raynes: Licenser: How about this: I'll just bite the bullet and do this as fast as possible. :p

3:58 Licenser: had that happen once again, wasn't fun since it means provreading the entire block again to see what changed :P

3:58 heh

3:58 or we agree on me just adding to a different flile or suffix

3:59 or you on a different sufix

3:59 _ato: defn: looks like you might also need to escape characters like <

3:59 Licenser: like :list-fns-lice and :list-fns raynes

3:59 defn: _ato: hehe, yes, examples/h1 is a good example :)

3:59 Raynes: Licenser: That would work.

3:59 We can create two of each category.

4:00 One for each of us.

4:00 Want to do that?

4:00 spariev: defn: very cool stuff, I with I could help somehow, was (and still is) very busy at work

4:00 defn: oh, maybe not -- since i added syntax highlighting it seems to have escaped the html for me

4:00 Licenser: yea and every now and then one of us can empty them and merge them together in the real things

4:00 sure lets do it that way

4:01 Raynes: Licenser: Alright. I'll fix that up. Give me a few.

4:01 defn: _ato: do you have a specific example?

4:01 Licenser: sure sure

4:01 _ato: defn: subseq

4:01 "test(s) one of <, <=, > or"

4:02 defn: ahhh yes

4:02 i see the problem now

4:02 Licenser: _ato: it shows well for me

4:02 defn: it shows for me as well actually

4:02 _ato: it renders cause the browser guesses and unmangles it, but that doesn't mean it's not a problem ;-)

4:02 defn: :)

4:06 Raynes: Licenser: You add to the ones without a suffix, and I'll add keys with the same name, with a -r suffix.

4:06 Licenser: Raynes: better is I think that you add to -r I add to -l that also gives us a proove read effect when adding the other's stuff to the real deal

4:09 _ato: eg, last example here the browser can't fix for you: http://getclojure.org:8080/examples/pre

4:09 Licenser: yap true

4:10 Raynes: Licenser: Okay. I modified the default tester to remove nil values before it constructs the whitelist, this way I can now add the prefixes with a nil value until we modify them.

4:10 I also made it into a pretty -> form. :D

4:10 Licenser: cool :)

4:17 defn: _ato: thanks

4:20 Raynes: Licenser: http://github.com/Licenser/clj-sandbox/blob/master/src/net/licenser/sandbox/safe_fns.clj Is this what you had in mind?

4:20 Licenser: yap that about it :)

4:20 Chousuke: defn: would it be possible to get the docstrings of things as mouseovers on the symbols?

4:21 Licenser: very neat

4:21 Raynes: This way, we can just copy and paste them into their right place whenever we need to.

4:21 Nice idea, man.

4:21 slyphon: gah, a 'let' inside of a handle in handle-condition is causing a NPE

4:21 * slyphon is going to bed

4:22 slyphon: in clojure.lang.LispReader, no less

4:22 gah!

4:25 Licenser: :)

4:30 Raynes: Licenser: Should stuff like promises, futures, and other concurrency-related stuff be considered safe?

4:30 Licenser: hmm I'm not sure about them, I think not since they trick timeout

4:31 Raynes: Okay. We'll slap them inside of the unsafe fns or something later. Not going to worry about them for now.

4:33 Licenser: *nods*

4:34 I think for contrib we can whitelist a few entire namespaces since they are non evil

4:34 Raynes: ,(distinct [1 2 3 3 4 5 2 2 3])

4:34 clojurebot: (1 2 3 4 5)

4:34 Raynes: Oh, that's awesome.

4:34 Licenser: heh

4:34 Raynes: How come I've never heard of distinct?

4:34 :o

4:34 I mean, I think I've written like 5 functions to do the same thing over the past year.

4:34 Licenser: because you'd have called it unique

4:35 Raynes: :>

4:36 Licenser: I thought we put doc on the safe function list ages ago?

4:36 $(doc doc)

4:36 sexpbot: ------------------------- clojure.core/doc ([name]) Macro Prints documentation for a var or special form given its name

4:36 Raynes: Maybe I just put it on my own whitelist.

4:36 Yeah, I did.

4:37 Was there any reason we didn't put it in safe-functions? I can't remember.

4:37 All it requires is that print-doc is whitelisted.

4:37 Doesn't seem to be dangerous at all.

4:38 Licenser: it is a macro :P

4:38 Raynes: Is that bad? :o

4:38 Licenser: it will never appear in the test

4:39 Raynes: Um.. I added the threading macros a while back. >.>

4:39 Licenser: ^^

4:39 won't make any difference

4:40 Raynes: I'm confused. :<

4:40 Licenser: so you're wokring from the api docs on clojure org?

4:40 Raynes: http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core

4:40 Licenser: try fn-seq on something like a macro

4:40 okay

4:41 Raynes: Licenser: Your fn-seq wont work on macros? How is it letting the threading macros by then?

4:41 Licenser: Raynes: it expands the macros to functions

4:41 that is the truck

4:41 erm trick

4:42 Raynes: Okay, so if print-doc is added, doc will work?

4:42 :o

4:43 Licenser: yap

4:43 Raynes: Awesome. Confusing, but awesome.

4:44 Licenser: ,(macroexpand '(doc doc))

4:44 clojurebot: (let* [m__1734__auto__ (clojure.core/meta (clojure.core/resolve (quote doc))) al__1735__auto__ (:arglists m__1734__auto__) docstring__1736__auto__ (:doc m__1734__auto__)] (if m__1734__auto__ (.replaceAll (clojure.core/str al__1735__auto__ "; " docstring__1736__auto__) "\\s+" " ") (clojure.core/-> hiredman.clojurebot.code-lookup/contrib :vars ((clojure.core/partial clojure.core/filter (clojure.core/fn [a__1737__auto__] (clo

4:44 Raynes: Licenser: Clojurebot uses a special doc.

4:44 Licenser: ah cool

4:44 that makes he happy

4:44 I always forge that :P

4:44 Raynes: Hehe.

4:45 Licenser: as long as doc and var is allowed but I'm not sure if allowing var is nice or not

4:45 Raynes: ,#'var

4:45 clojurebot: java.lang.Exception: Unable to resolve var: var in this context

4:45 Licenser: var is a special form

4:45 Raynes: Oh.

4:45 Licenser: ,(var doc)

4:45 clojurebot: #'clojure.core/doc

4:45 Licenser: seems clojure bot thinks it's save enough

4:45 Raynes: I don't think it will harm anything.

4:46 Licenser: well you get the var object which might be sneaky evil

4:46 * Licenser cries they have started drilling down the wall next to my window it is freaking loud

4:46 Raynes: :p

4:47 If it hasn't killed clojurebot yet, it's probably safe enough to add. At least until somebody gets murdered by it.

4:47 Licenser: nah clojurebot has holes in it, ask _ato he found one the other day

4:48 Raynes: Well _ato is a sneaky ba... :|

4:48 Licenser: even found one in clj-sandbox

4:48 heh

4:48 he is the reason for removing .

4:48 Raynes: Well, var is out. :\

4:49 _ato: ,((.get (.findInternedVar (:ns (meta #'inc)) (read-string "eval"))) '(+ 1 1))

4:49 clojurebot: 2

4:50 _ato: ^ that's the one that cause Licenser to remove .

4:50 as you can see it uses var

4:50 Licenser: yea :P

4:50 evil _ato

4:50 nteon: any philosophical reason PersistentStructMap can't be used with the transient functions? or is it just not implemented yet?

4:51 Raynes: Just a shame to not be able to whitelist doc. :\

4:51 Chousuke: I don't think transients would make much sense with structmaps

4:51 Raynes: Seems like such a benign macro.

4:51 But has embedded evil.

4:51 x_x

4:52 Chousuke: nteon: if you need them, you can just transform the structmap into a regular map

4:53 Raynes: Licenser: Speaking of ., have you made any progress with fixing that?

4:55 Licenser: nah still in vacation :P

4:55 +

4:55 Raynes: Hehe.

5:00 Licenser: Where should enumeration-seq go? :o

5:01 Licenser: wow that is a good question, I'd put it in cast functions

5:02 Raynes: ,(doc error-handler)

5:02 clojurebot: Pardon?

5:03 Licenser: heh

5:04 Raynes: Not sure what to make of agent-related functions.

5:04 Don't think I've touched any of them.

5:06 This is disappointing.

5:07 I can add find-doc, but not doc.

5:07 :>

5:07 I miss the old doc that took a string.

5:08 ZabaQ: Is it possible to use clojure-mode/clojure-swank with the latest slime cvs?

5:12 Raynes: I don't think so.

5:14 Borkdude: I need more chapters from TJoC or CiA

5:14 Raynes: Borkdude: I agree.

5:15 Borkdude: Annoy chouser.

5:15 And _fogus_

5:15 They're sleeping when they could be writing. Should be illegal.

5:15 defn: it is in some states

5:16 nteon: Chousuke: thanks, I just rewrote it to use a regular map, since it was pretty isolated

5:16 transients speed up my code by about 5x, which is nice

5:17 licoresse: .

5:18 Borkdude: why not automatically do transients in Clojure in e.g. loops

5:20 esj: Borkdude: They're teasing us with status updates on the chapters....

5:20 Chousuke: Borkdude: that's not as easy as it sounds

5:21 bsteuber: guess we all want to have a clojure compiler that gives output as fast as C :)

5:21 Chousuke: Borkdude: besides, loops aren't very idiomatic in clojure anyway :)

5:21 Borkdude: Chousuke, what would be the added value of having a persistent vector in my loop here:

5:21 (loop [x 0 v (transient [])] (if (> x 5) (persistent! v) (recur (inc x) (conj! v x))))

5:22 Chousuke: nothing, really, but

5:22 ,(into [] (range 6)) uses transients as well :P

5:22 clojurebot: [0 1 2 3 4 5]

5:23 Chousuke: explicit loops are often silly; use existing functions instead

5:23 Borkdude: ok, so when you are using a lot of persistent things where you might want to use transients you have to consider if something like that already exists?

5:24 ,(doc into)

5:24 clojurebot: "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."

5:24 Chousuke: you should always consider using existing things

5:24 but the bigger problem is that there's no easy way to tell if auto-transients are safe

5:24 it's not a trivial code optimisation

5:25 the compiler might someday do it, but for now I don't think it's beneficial enough justify the effort

5:25 Borkdude: when a function is referential transparent?

5:25 Chousuke: how do you know that?

5:26 more specifically, how do you know that the value in the loop will always be something that supports transients?

5:26 Borkdude: you don't ... but maybe you can give warnings like with warn on reflection

5:27 Chousuke: but the code is valid. You shouldn't warn on valid code :/

5:27 Borkdude: reflective code is also valid

5:29 Chousuke: the reflection-warning check is done at compile. there is no way to check at compile time whether a value will be transientable or not

5:29 at compile time*

5:29 it would require a static type system :)

5:30 now, the compiler could do dynamic optimisations and transformations based on profiling and whatnot but that's far from trivial

5:30 Borkdude: ure. As of Clojure 1.1.0, vectors, hash-maps, and hash-sets are supported.

5:30 You can check for that?

5:31 bsteuber: chousuke: sometimes there is, if you have control of the calling code or stuff

5:31 but in general a lot of hard inference algorithms are needed to do this kind of optimisation right

5:31 Chousuke: yes. and then you need to ask, is it worth it?

5:31 I don't think it is, at this point

5:31 Borkdude: Chousuke, are you involved in developing clojure/contrib?

5:32 Chousuke: I have a CA, but I haven't done much lately.

5:33 I'm optimistic that the compiler will become smarter once it gets rewritten in Clojure, though.

5:33 at least it will be easier to develop

5:36 Borkdude: Are transients only meant to be encapsulated by functions, loops, etc?

5:36 Not for direct use in a var I mean?

5:36 Chousuke: yes.

5:36 transients should never be stored anywhere

5:37 certainly not in a var, as any operation on the transient would then render the var's content invalid

5:37 Borkdude: I can do this:

5:37 (def g (transient []))

5:37 (conj! g 3)

5:37 Chousuke: you can, but that's invalid code.

5:37 Borkdude: (persistent! g)

5:38 defn: is it possible to use ansi-color in a slime repl?

5:38 Chousuke: well, okay, pointless code :)

5:38 Borkdude: maybe the compiler should prohibit it?

5:38 Chousuke: Borkdude: Again, too much work for little benefit

5:38 defn: im messing with lazytest and would like to get some color

5:38 Borkdude: it's like having safe and unsafe code in C#

5:39 Chousuke: C# is statically typed

5:39 Because Clojure is dynamic, things like this become much more complicated

5:39 you can't even tell in the general case whether that code works with transients at all

5:40 since the transient function, assoc! etc. might be redefined at runtime

5:40 granted, that's unlikely, but it does show that the optimisations might break in unexpected ways

5:41 Borkdude: Chousuke, isn't that also the case for a lot of other functions in Clojure?

5:42 When there are checks for invalid code

5:42 Chousuke: Are there such checks at compile-time?

5:42 I can't think of any.

5:42 except some macro form checks

5:43 which don't actually care about values at all :)

5:44 Borkdude: I was thinking of recur being last in place, but that's a macro form check ;)

5:44 Chousuke: yeah.

5:44 Raynes: Licenser: You know, the Clojure API is nearly as large as I thought it was. I'm already over half way through it. :o

5:44 Chousuke: and recur can't be redefined anyway, since it's a special form :P

5:45 though...

5:45 Borkdude: and a lot of checks are don't by the compiler but go wrong in Java when casting things etc?

5:46 Chousuke: ,(loop [recur 1] (when (< recur 3) (print "hey") (recur (inc recur))))

5:46 clojurebot: heyhey

5:46 Chousuke: Borkdude: those are runtime checks, but the JVM does them for us

5:46 Borkdude: hmm yues\

5:47 yes

5:48 Chousuke: The clojure compiler is simple and rather stupid for now (it does some optimisations, but AFAIK only if they're necessary for decent performance)

5:48 the JVM does the rest

5:48 Borkdude: like what?

5:49 Chousuke: Well, there's the locals clearing thing that was added most recently I think

5:50 I suppose that one is not strictly necessary, but it removed a big gotcha

5:50 Raynes: Don't call little CC dumb. :( She's so young.

5:50 Chousuke: heh :P

5:50 okay, it's willfully ignorant

5:50 Borkdude: simple is not dumb

5:50 what is this local clearing thing about?

5:51 Chousuke: previously, local references in functions were only cleared on tail-calls (function exit). Now the compiler clears them after their last use.

5:52 Borkdude: ah ok

5:52 when does that gain performance boost?

5:52 I mean, a lot

5:52 Chousuke: well, it keeps references to things for a shorter time, allowing them to be GC'd earlier

5:52 Borkdude: and by cleared, you mean, garbage collected?

5:52 Licenser: Raynes: sweet

5:52 Chousuke: cleared meaning the reference is nulled

5:53 Borkdude: ok

5:53 Chousuke: so that the GC can claim it if there are no more references

5:53 Raynes: Licenser: In between rocking out in my computer chair to Adam Lambert songs, even. :p

5:53 Chousuke: I think this was more of an usability optimisation though

5:54 because many people (including me) ended up assuming things get cleared at last use and unwittingly held references to sequences that should have been let go, leading to memory leaks

5:55 Licenser: heh

5:57 Borkdude: because you didn't exit the function? I don't see it before me

6:00 Chousuke: Borkdude: the problem manifested in functions like (defn foo [aseq] (let [sum (reduce + aseq)] aseq-still-exists-here! ...)

6:01 even though the rest of the code doesn't use aseq and reduce could have let it all get garbage collected while it's reducing, the whole sequence ends up in memory because the function parameter refers to it.

6:01 Borkdude: Chousuke, yes but how long would it take before you would exit the function? I can't imagine causing it very big memory leaks?

6:01 nteon: is assoc faster on vectors than maps?

6:01 is that a silly question?

6:02 Chousuke: Borkdude: imagine a lazy sequence of 100000000 numbers

6:02 defn: ,(doc assoc)

6:02 clojurebot: "([map key val] [map key val & kvs]); assoc[iate]. When applied to a map, returns a new map of the same (hashed/sorted) type, that contains the mapping of key(s) to val(s). When applied to a vector, returns a new vector that contains val at index. Note - index must be <= (count vector)."

6:02 Chousuke: Borkdude: without the optimisation, all of those numbers would end up in memory at one time

6:02 Borkdude: with the optimisation, only a few of them would

6:03 nteon: defn: yes, I guess I could test for myself.

6:03 defn: nteon: my guess is faster on a vector

6:03 but i dont know for certain

6:03 Chousuke: hmm

6:03 Borkdude: Chousuke, a reference to the lazy seq would be held, but not all of its items would be realized necessarily?

6:04 Chousuke: Borkdude: the problem is that if a reference to the seq's head is held, all subsequent items in the seq must be kept as well

6:04 Borkdude: whereas reduce doesn't actually need to hold the head, it can just go through the rest of the seq and let the head be GCd

6:05 Borkdude: which allows it to reduce over sequences that would never fit in memory in full

6:05 Borkdude: Chousuke, so it would depend on what you would do with aseq in the let, still a reference to the head isn't necessary?

6:07 Chousuke: Borkdude: a reference to aseq is not necessary after it has been passed to reduce, because it's not used in the rest of the function

6:07 Borkdude: what reduce does with the reference is irrelevant, actually.

6:07 Borkdude: Chousuke, I know, but even if there was one, it doesn't mean that aseq would be fully consumed into memory?

6:07 Chousuke: Borkdude: yes it would

6:08 Borkdude: ah, I don't get that part yet

6:08 Chousuke: Borkdude: because reduce walks the entire seq

6:08 Borkdude: and as long as there is a reference to the seq's head outside reduce, the entire seq must be held

6:09 this is because lazy seqs cache their items

6:09 Borkdude: ok, but what if there isn't a reference to the head, but to some other elt?

6:09 Chousuke: walking over a lazy seq twice doesn't actually run the thunks twice

6:09 references to the elements themselves are not an issue

6:10 but if you mean a reference to the tail of the seq, then that might be an issue as well

6:10 the tail of a list is the head of another list :)

6:11 if you have a reference to the tail of a list, then the element before the tail can be GC'd, but obviously not the tail

6:12 eg. (def x (rest '(1 2 3))) allows the list node holding 1 be GC'd

6:13 at least after x is fully realised :P

6:14 Borkdude: hmhm, and previously it did not collect '(1 2 3) before the function was exited?

6:14 Chousuke: it could not, because the aseq reference still existed

6:14 Borkdude: isn't there a blog post about this I can read maybe?

6:15 Raynes: Funfact: Only one function in clojure.core starts with a q.

6:15 Chousuke: I'm not aware of nay.

6:15 any

6:15 Raynes: ,(quot 2 3)

6:15 clojurebot: 0

6:15 Chousuke: heh

6:15 but there are two operators which start with a q

6:16 Raynes: orly

6:16 Chousuke: and one looks like a typo of the other ;(

6:18 hm

6:18 Borkdude: I think I'm starting to grasp it now Chousuke

6:18 Chousuke: ,(reduce print nil [1 2 3 4])

6:18 clojurebot: nil 1nil 2nil 3nil 4

6:18 Chousuke: oh shoo, it prints nils like that :(

6:21 hm, time to get some food. Later

6:22 Raynes: Licenser: You haven't added any functions have you? Looks like I'm going to be done by 7-8AM CDT

6:23 (doc repeat)

6:23 clojurebot: "([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."

6:24 Raynes: (doc replicate)

6:24 clojurebot: "([n x]); Returns a lazy seq of n xs."

6:24 Raynes: How useless. :o

6:26 Borkdude: Chousuke, suppose I have this example:

6:26 (defn foo [aseq] (do (print (reduce + aseq)) (last aseq)))

6:27 in the new situation, what will be collected before (last aseq) if I feed (range 1000000) as aseq into foo

6:27 Raynes: Licenser: I'm changing list-fns to seq-fns, because most of these fns work for seqs in general.

6:27 Borkdude: or at least cleared I mean

6:28 _ato: Borkdude: nothing will be cleared before (last aseq)

6:29 although aseq will be cleared while (last aseq) runs

6:29 (well the reference is cleared just before entering the call to last aseq)

6:31 Raynes: ,(set [1 2 3 4 2 3 2 5])

6:31 clojurebot: #{1 2 3 4 5}

6:31 Raynes: Wish I'd know about that yesterday.

6:31 I ended up doing (into #{} ..)

6:31 :(

6:40 ,(time (+ 3 3))

6:40 clojurebot: 6

6:40 "Elapsed time: 0.112 msecs"

6:40 Raynes: ,(macroexpand '(time (+ 3 3))

6:40 clojurebot: EOF while reading

6:40 Raynes: ,(macroexpand '(time (+ 3 3)))

6:40 clojurebot: (let* [start__5472__auto__ (. java.lang.System (clojure.core/nanoTime)) ret__5473__auto__ (+ 3 3)] (clojure.core/prn (clojure.core/str "Elapsed time: " (clojure.core// (clojure.core/double (clojure.core/- (. java.lang.System (clojure.core/nanoTime)) start__5472__auto__)) 1000000.0) " msecs")) ret__5473__auto__)

6:42 Licenser: yea bad news :(

6:43 Raynes: Licenser: Not like it's that useful from a bot or something anyways.

6:44 Licenser: Anyways, I'm almost done with the entire API, when I am, I'll merge the results and get rid of the suffix duplicates. Don't bother adding any functions yourself.

6:44 opqdonut: how can I access static fields through an object?

6:45 Borkdude: opqdonut (Object/field

6:45 I thikn

6:45 opqdonut: no

6:45 only works for Class/field

6:45 Raynes: Same way you do normally.

6:45 Borkdude: ah

6:45 opqdonut: for an object i get java.lang.Exception: No such namespace: Object

6:45 Raynes: (.method obj args) should work.

6:46 opqdonut: the doc for the dot special form explicitly says that when the first arg is an object it looks up only instance fileds

6:46 Raynes: In that case, just use the class that you made the object out of?

6:46 opqdonut: well, you see, I don't know the class

6:47 sure, I can use java's reflection and that's what I'll do

6:47 but it's ugly ugly ugly

6:47 Raynes: Eh? Well. I don't have any magic to help you out. :\

6:48 Licenser: opqdonut: try java.lang.Object

6:49 opqdonut: errr?

6:49 I can't give both the object and the class

6:50 it's not a huge thing, it's just weird that clojures . works differently from java's . here

6:50 in java object.field looks at static fields of the class too

6:52 hoeck: ,(. Integer MAX_VALUE)

6:52 clojurebot: 2147483647

6:53 hoeck: opqdonut: ^^

6:53 Raynes: ,(. 3 MAX_VALUE)

6:53 clojurebot: java.lang.IllegalArgumentException: No matching field found: MAX_VALUE for class java.lang.Integer

6:53 Raynes: hoeck: ^

6:53 hoeck: right, sorry

6:54 Raynes: You tried, buddy, you tried. <3

6:54 opqdonut: ,(.. 3 getClass (getField "MAX_VALUE") (get nil))

6:54 clojurebot: 2147483647

6:55 Borkdude: hehe

6:56 hoeck: ,(clojure.lang.Reflector/getStaticField (class 0) "MAX_VALUE")

6:56 clojurebot: 2147483647

7:00 Raynes: Licenser: I just got to the end of the core API. :D

7:00 Adding final touches and then pushing.

7:00 Borkdude: Raynes, what are you doing exactly?

7:01 Raynes: Borkdude: Adding every function in clojure.core that I deem safe to the clj-sandbox default whitelist.

7:01 Borkdude: ah ok

7:02 hello mfex

7:02 raek: ok, this has probalby been asked a thousand time already, but is there any way for making line numbers get passed to the compiler when evaluating in slime?

7:02 Licenser: Raynes: ayay then I just revert for simplicity

7:11 Raynes: Licenser: Pushed. After you look it over, please push a new version to clojars.

7:13 Licenser: I wil

7:13 hoeck: raek: I'm always using (require '[my.ns :reload]) in the repl :/

7:15 raek: and slime-load-file works too, but only for whole files

7:18 basically, it should be possible to get accurate line numbers for evaluated expressions without modifying clojure, by using clojure.lang.Compiler/load instead of eval

7:19 Raynes: Licenser: I'm going to proof-read the docs later. I keep seeing "cause" instead of "course". :p

7:19 Licenser: :P

7:20 Raynes: You foreign people!

7:20 ;>

7:21 Licenser: :P

7:21 well we can't spell but we can code

7:21 Raynes: Hehe.

7:24 Licenser: Raynes: I'll move them in the usual functions

7:25 Raynes: ?

7:31 esj: is there a specific method of disconnecting emacs slime from swank such that one can reconnect later ?

7:31 i keep getting beachballed on attempting to reconnect

7:33 Chousuke: Borkdude: nothing

7:33 Borkdude: as _ato seems to have responded :)

7:33 Licenser: ah you did that already now I stop bing confused

7:34 Borkdude: Chousuke, I didn't do an async call to you, so I was waiting all the time..

7:34 Licenser: I was looing what Ib roke for liek 15 mintes

7:35 Borkdude: But what keeps a reference to the head of aseq in my example?

7:37 Chousuke: Borkdude: the fact that you use it in the call to last

7:38 Borkdude: last needs to walk the seq to get to the last item

7:39 Raynes: Licenser: Haha, yeah.

7:39 Borkdude: hmm, so lazy-seq is actually always a lazy-list?

7:39 Raynes: Owie. Brain freeze.

7:40 Chousuke: Borkdude: the other way around. lists are sequences

7:40 Borkdude: but not all sequences are lists...

7:40 so there is maybe a more clever way to do it?

7:41 Chousuke: well you could make a function that reduces a function over the seq and then also returns the last item

7:42 but I think that's the only way to do it if you want to avoid walking it twice and thus having to hold the whole seq in memory

7:42 Borkdude: ,(doc lazy-seq)

7:42 clojurebot: "([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls."

7:43 licoresse: /.

7:43 Chousuke: and just to clarify, seqs and lists are practically functionally identical. the word "list" is usually used to mean PersistentList instances

7:43 esj: Chousuke: so while the seq is walked by (last ...) say, the GC cannot clear elements that have already been passed by ?

7:43 Chousuke: as opposed to lazy seqs or seqs over a vector

7:44 esj: it can at that point, but the seq will still be in memory *before* the call to last, because reduce will have walked it once alreadt

7:45 esj: Chousuke: understand (I think), thanks.

7:45 Borkdude: doesn't lazy-seq look at the underlying kind of seq what is the most efficient way of accessing?

7:45 Chousuke: Borkdude: no.

7:45 a_strange_guy: it cant

7:45 Chousuke: Borkdude: seqs are never indexed

7:46 Licenser: pushed new version

7:46 Chousuke: Borkdude: if you make a seq over a vector, it basically degrades into a list

7:46 Borkdude: so seqs are always walked in the list style?

7:46 Chousuke: yes.

7:47 a_strange_guy: they only supprort first rest and next

7:48 Raynes: a_strange_guy: You're strange. :)

7:49 a_strange_guy: Ive hoped that no one would notice ^^

7:50 Licenser: Raynes: pushed :)

7:50 Raynes: Licenser: Yay! :>

7:51 Licenser: thanks for the great work mate, you're doing a incredible job

7:51 Raynes: Thank you. It was hard work, typing those function names. ;)

7:52 Borkdude: ok got it, tnx

7:52 I gtg now

7:52 Licenser: yea that is hard

8:05 Raynes: ,(with-out-str (println "Hai"))

8:05 clojurebot: "Hai\n"

8:15 esj: is there an assoc equivalent for deftypes ?

8:15 chouser: doesn't assoc work on deftypes?

8:16 * esj prepares to be embarrased.... checking

8:16 chouser: oh, only for IPersistentMap ones ("records")

8:16 Raynes: I thought you had to implement IPersistentMap.

8:16 Ah, yes.

8:16 chouser: You don't have to implement it yourself though

8:16 esj: the doc says it implements it

8:17 chouser: (deftype F [a b] clojure.lang.IPersistentMap) (assoc (F 1 2) :b 10)

8:17 esj: perfect !

8:17 chouser: planned: (defrecord F [a b]) (assoc (F 1 2) :b 10)

8:18 esj: thanks, I misread the doc

8:18 so IPersistentMap would join ILookup and IObj :)

8:19 thanks gents. deftype/protocol are awesome, I'm annoyed I didn't pick up on them earlier.

8:38 * raek just discovered http://blog.fogus.me/2010/03/23/clojures-mini-languages/

8:38 raek: nice summary, fogus!

8:43 wlangstroth: morning all. Hail Clojure.

8:44 Raynes: Is there a way to get all of the defmethods defined in a namespace?

8:44 esj: wotcha wlangstroth

8:45 Raynes: Something like methods, but that is namespace specific.

8:47 wlangstroth: Raynes: doesn't the backtick do something magical like that?

8:49 chouser: ,(filter #(= clojure.lang.MultiFn (:tag (meta %))) (vals (ns-interns 'clojure.core)))

8:49 clojurebot: (#'clojure.core/print-dup #'clojure.core/print-method)

8:53 Raynes: chouser: That gets the multimethods, but not the methods.

8:53 chouser: oh sorry, what did you want?

8:54 all methods for a particular defmulti, but then filtered on where they're defined?

8:54 Raynes: Indeed.

8:54 Like methods.

8:54 Just namespace specific.

8:54 chouser: I don't think that information is preserved currently

8:54 Raynes: That sucks. :\

9:06 fogus: raek: Thanks!

9:07 esj: more deftypes: is there a way to access constr using named fields something like - (deftype F [a b]) (F :b 2 :b 1) ?

9:26 bah - stupid question, sorry.

10:03 defn: i have a dream

10:04 wlangstroth: defn: does it involve ice cream?

10:05 defn: wlangstroth: funny you should ask

10:05 wlangstroth: of course it includes ice cream

10:06 wlangstroth: defn: then I'm all ears

10:06 defn: but seriously folks, anyone have any suggestions on building intelligent auto-indentation

10:07 pprint does not get me very far (i dont think)

10:07 carkh: that problem is *hard*

10:07 pprint is configurable i think

10:07 Licenser: yea the question is what is inteligent

10:07 defn: yeah i figured carkh :

10:07 :\

10:08 Licenser: emacs goes with: next line is idented two more spcaes then the last opening (

10:08 carkh: what is wrong with pprint ?

10:08 defn: Well I think I can define "intelligent" with a set of a dozen rules or so

10:08 carkh: defn : that's what you think

10:08 you need to pprint code as opposed to data ?

10:08 defn: carkh: perhaps im missing some functionality of pprint

10:09 but pprint '(blah blah blah), does not yield desirable results for nested functions

10:09 it seems to only wrap

10:09 carkh: but what are you trying to pprint ?

10:09 code or data ?

10:09 defn: code

10:09 carkh: i seem to remember there was an experimental flag for that in pprint

10:10 Licenser: (doc pprint)

10:10 clojurebot: Excuse me?

10:10 Licenser: ,(doc pprint)

10:10 clojurebot: Excuse me?

10:10 Licenser: ,(doc clojure.contrib.pprint)

10:10 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.pprint

10:10 Licenser: ,(doc clojure.contrib.pprint/pprint)

10:10 clojurebot: "([object] [object writer]); Pretty print object to the optional output writer. If the writer is not provided, print the object to the currently bound value of *out*."

10:10 defn: *code-dispatch*?

10:11 carkh: The pretty printer supports two modes: _code_ which has special

10:11 formatting for special forms and core macros and _simple_ (the

10:12 *code-dispatch* looks like this is the dispatch function for code

10:12 (with-pprint-dispatch *code-dispatch* (pprint code))

10:12 there you go

10:13 Licenser: defn: btw Raynes was so nice to go through the rest of the core API so 0.2.12 is out

10:13 defn: Licenser: great

10:13 carkh: defn : you can find more docs about pprint there : richhickey-clojure-contrib-d1e831b\doc\pprint\

10:14 it just sounds silly to redo that work as it's already pretty good

10:14 defn: ,(use 'clojure.contrib.pprint)

10:14 clojurebot: java.lang.IllegalStateException: write already refers to: #'clojure.contrib.monads/write in namespace: sandbox

10:15 defn: ,(use '[clojure.contrib.pprint :exclude (write)])

10:15 clojurebot: nil

10:15 defn: (with-pprint-dispatch (pprint '(reduce + (map #(+ 1 % 4) [1 2 3 4 5 6 7 8 9]))))

10:15 ,(with-pprint-dispatch (pprint '(reduce + (map #(+ 1 % 4) [1 2 3 4 5 6 7 8 9]))))

10:15 clojurebot: (reduce + (map (fn* [p1__8899] (+ 1 p1__8899 4)) [1 2 3 4 5 6 7 8 9]))

10:16 defn: close but no cigar

10:16 Licenser: I think clojure does not actually wite things like \n

10:17 carkh: defn: that's not a pprint problem you have here, that's the reader transforming #() to (fn [] ..)

10:17 Licenser: hmm is there a way to map over a nested list without destroying it's structure?

10:17 defn: ,(with-pprint-dispatch *code-dispatch* (pprint '(reduce + (map #(+ 1 % 4) [1 2 3 4 5 6 7 8 9]))))

10:17 clojurebot: (reduce + (map #(+ 1 % 4) [1 2 3 4 5 6 7 8 9]))

10:18 carkh: ohh

10:18 there is some magic going on there

10:19 Chousuke: it probably looks at the parameter list

10:19 p1__nnnn is not a very common parameter name :)

10:19 carkh: thi spprint thing is awesome, too bad it's a tad slow

10:20 Licenser: ,(with-pprint-dispatch *code-dispatch* (pprint '(reduce + (map (fn [p1__8899] (+ 1 p1__8899 4)) [1 2 3 4 5 6 7 8 9]))))

10:20 clojurebot: (reduce + (map (fn [p1__8899] (+ 1 p1__8899 4)) [1 2 3 4 5 6 7 8 9]))

10:20 Licenser: ,(with-pprint-dispatch *code-dispatch* (pprint '(reduce + (map (fn* [p1__8899] (+ 1 p1__8899 4)) [1 2 3 4 5 6 7 8 9]))))

10:20 clojurebot: (reduce + (map #(+ 1 % 4) [1 2 3 4 5 6 7 8 9]))

10:20 Licenser: ,(with-pprint-dispatch *code-dispatch* (pprint '(reduce + (map (fn* [x] (+ 1 x 4)) [1 2 3 4 5 6 7 8 9]))))

10:20 clojurebot: (reduce + (map #(+ 1 % 4) [1 2 3 4 5 6 7 8 9]))

10:20 Licenser: ah fn* is the sneaky thing

10:21 Chousuke: makes sense.

10:21 no-one's going to use fn* directly in their code

10:21 defn: oh someone will :)

10:21 Licenser: I might .P

10:21 (doc fn*)

10:21 clojurebot: No entiendo

10:21 Chousuke: well those are a statistically insignifcant minority :P

10:21 carkh: defn : so does that solve your problem at all ?

10:22 Chousuke: fn* is not even an official part of the API

10:22 it might go away

10:22 defn: carkh: heh unfortunately i don't think so

10:22 carkh: so what's the missing part ?

10:23 defn: carkh: i dont see where it does any reformatting, when i use *code-dispatch* it just gives me *out* which looks like the code i put into it

10:23 i used with-out-str on it to see what happened and received the same thing

10:23 carkh: that's because you're passing one-liners

10:23 defn: yes, all of the input will be one-liners

10:24 it must be reformatted with indentation and newlines

10:24 carkh: allright so you need to make your own pprint-dispatch function

10:24 you have examples in the pprint source

10:24 defn: *nod*

10:24 thanks carkh

10:27 jfields: I'm trying to slurp a file that might not exist, is there a file-exists? or another better way to handle this?

10:28 S11001001: jfields: catch FileNotFoundException

10:28 Licenser: (.exists (File. f))?

10:28 S11001001: .exists would have a race condition anyway

10:29 jfields: thanks.

10:44 AWizzArd: How can I make emacs replace tabs with spaces without resulting in visable differences in my Clojure code?

10:47 noidi: AWizzArd, afaik M-x untabify

10:47 I'm not sure though, since I don't have Emacs at hand at the moment

10:53 slyphon: ?3

10:56 esj: AWizzArd: yup, noidi is right, and it affects the selection, not the buffer.

11:01 AWizzArd: yes okay, untabify works

11:01 I will have to see how I can automatically use this when saving a buffer and/or doing C-c C-k

11:01 thanks for the tip

11:03 drewr: AWizzArd: you shouldn't be getting tab chars in your code to begin with (with clojure-mode at least)

11:04 AWizzArd: drewr: is that also true for the clojure mode from October 2009?

11:04 hoeck: AWizzArd: (setq-default indent-tabs-mode nil)

11:04 AWizzArd: hoeck: k, will try that, thx

11:14 drewr: AWizzArd: not sure; I have indent-tabs-mode set to nil like hoeck mentioned, so maybe that's been taking care of me

11:22 Borkdude: I got some problems setting up emacs with swank on ubuntu

11:23 File error: Cannot open load file, swank-clojure-autoload

11:23 tomoj: elpa?

11:23 clojurebot: elpa is a package manager for Emacs: http://tromey.com/elpa

11:29 Borkdude: my ubuntu vm is freaking out while installing a flash plugin that was needed to display some github site

11:30 so I couldn't follow anything you said after I asked about the swank error, except tomoj saying: elpa

11:31 Chousuke: Borkdude: hm, github still requires flash for something?

11:31 Borkdude: in my freshly installed ubuntu with firefox it asked for it yes

11:32 tomoj: Borkdude: that's all I said

11:32 are you using elpa, or not?

11:32 Chousuke: they replaced some flash stuff with HTML5 and canvas a while ago

11:33 Borkdude: tomoj I'll see if I can get that started

11:35 tomoj: elpa -> install clojure-mode and swank-clojure -> install leiningen -> add leiningen/lein-swank to dev-deps -> lein-swank -> slime-connect

11:35 that's what I do

11:35 Borkdude: hmm tomoj I already setup clojure.jar and clojure-contrib, etc through git

11:35 tomoj: no need

11:36 unless you want to :)

11:36 Borkdude: tomoj what will happen if I want to be up to date with new clojure versions, if I go the elpa way

11:38 tomoj: if you're using something like leiningen or maven, it doesn't matter

11:39 e.g. with lein-swank, you can put whatever version of clojure in your project.clj deps

11:39 (though, the clojure-contrib snapshot apparently hasn't been updated in a while..)

11:39 stuartsierra: yes it has

11:40 tomoj: oh, yes, it's just named differently from clojure snapshot?

11:40 stuartsierra: It's named clojure-contrib-SNAPSHOT

11:40 I mean "clojure-contrib" with version "1.2.0-SNAPSHOT"

11:40 tomoj: whereas clojure is 1.2.0-master-SNAPSHOT, strange

11:40 stuartsierra: yeah, my mistake, but I'm hesitant to change it again

11:41 chouser: or my mistake going ahead with "-master". Hard to say.

11:41 stuartsierra: It was useful while "-new" was around, less so now.

11:41 tomoj: I noticed semver doesn't even want a - after 1.2.0

11:42 oh, guess that doesn't matter for snapshots, though?

11:43 stuartsierra: semantic versioning doesn't really allow for development snapshots.

11:44 tomoj: which is ok since they won't be tagged anyway, I guess

11:45 stuartsierra: The problem with Clojure is that we're all too darned impatient to wait for numbered releases.

11:46 And people writing Clojure libraries think numbered releases aren't worth bothering with.

11:49 hamza: hey guys, I have one namespace that holds os specific classes that i only want to load it if I am on say windows, in java I would do this using reflection what would be the lisp way of achiving this? if i try to load this namespace say in linux it would crash because classes aren't present

11:50 stuartsierra: (if (= "windoze" (System/getProperty "os.name")) (require 'windoze-stuff))

11:52 cgrand: require or load?

11:53 stuartsierra: load if you want two different files that define the same namespace for different OS's

12:00 hamza: stuart: load does work when running from clj files but when i jar the application it fails?

12:01 stuartsierra: hamza: 'load' take a path without an extension, like "foo/bar/baz" for the file foo/bar/baz.clj or foo/bar/baz.class

12:03 hamza: (load "win_stuff") load it like this, and from repl it works fine but it cant find the class inside jar

12:03 stuartsierra: Check that the jar contains win_stuff.clj or win_stuff.class

12:06 hamza: it contains both win_stiff.clj and win_stuff__init.class

12:10 stuartsierra: then it should work, I think

12:10 maybe you need an extra directory layer, i.e. "foo/win_stuff.clj"

12:11 hamza: just noticed something, it searches clojure folder inside the jar not my applications namespace, clojure/app/win_stuff.clj not found but file is in app/win_stuff.clj

12:12 stuartsierra: that's weird

12:12 (doc load)

12:12 clojurebot: "([& paths]); Loads Clojure code from resources in classpath. A path is interpreted as classpath-relative if it begins with a slash or relative to the root directory for the current namespace otherwise."

12:12 stuartsierra: Aha!

12:13 You need (load "/app/win_stuff")

12:14 hamza: thanks, now got it..

12:15 stuartsierra: good

12:28 hamza: one more question, i have two files win_stuff and uni_stuff, they both provide same api. i load uni_stuff throug use in ns decleration and load win_stuff via load but functions in win_stuff does not override the calls in uni_stuff.

12:32 stuartsierra: If think you should only load one or the other, not both.

12:33 hamza: but if I load one, lein can not compile the file because functions does not exist, second file is just a dummy file to get lein to compile the jar

12:34 stuartsierra: maybe define an file that just 'declare's all the functions in your API, then 'load's the appropriate implementation.

12:57 SirNick: Hello, so I have been playing around with clojure a bit but ran into a problem while trying to make a map of the words to their counts given a list. It seems I only get the first 8 counts. Perhaps I am using transients incorrectly? Does anyone have any insight on why this might not be working: http://paste.pocoo.org/show/BtKBoDa0rGsBDXxfFYvN/

12:59 technomancy: SirNick: yeah, that's not how transients work: http://technomancy.us/132

12:59 SirNick: technomancy: alright thanks

13:02 tomoj: SirNick: is clojure your first functional language?

13:02 SirNick: tomoj: no I've written a fair amount of Erlang and a bit of Haskell

13:03 tomoj: ok, so maybe try to think how you'd solve the problem in haskell

13:03 clojure wants you to do it more like that than like, say, ruby (which is what your paste reminded me of)

13:03 SirNick: tomoj: alright thanks, yea I think the problem I am having is just thinking that transients are something they're not. I think I see the error of my ways now though, hah

13:07 tomoj: what's prettier than #(assoc %1 %2 (inc (get %1 %2 0))) ?

13:08 hiredman: tomoj: update-in

13:11 tomoj: what, (fn [m k] (update-in m [k] #(inc (or % 0)))) ?

13:12 SirNick: Doing this the right way turned out much more elegant, but that's no surprise :)

13:12 tomoj: SirNick: how'd you do it?

13:13 I was trying to think of the most elegant way I could

13:13 (didn't work very well, as you can see)

13:13 SirNick: tomoj: Not to say this is the most elegant way possible, but: http://paste.pocoo.org/

13:15 tomoj: I like your idea with inc and or though... Might have to try that

13:15 tomoj: my best is (reduce (fn [m k] (update-in m [k] #(inc (or % 0)))) {} words)

13:15 your paste didn't come through

13:15 SirNick: ah, oops: http://paste.pocoo.org/show/fpaZK7c6mrZzQt1I58UT/

13:15 tomoj: hmm

13:16 how about: (def count-words frequencies)

13:16 :)

13:16 clojure.contrib.seq-utils/frequences

13:16 SirNick: hah, wow... I'll see how that works, thanks

13:17 tomoj: it uses (assoc counts x (inc (get counts x 0)))

13:17 :(

13:17 SirNick: hah well I'm sure they thought about it for a while

13:17 hiredman: (update-in counts [x] nil-safe-inc)

13:17 tomoj: man, I've written that function so many times

13:17 hiredman: right

13:18 tomoj: where's nil-safe-inc from?

13:18 hiredman: no where

13:18 :(

13:20 SirNick: tomoj: frequencies worked beautifully, thanks

14:00 thios: is there a handy clojure way to execute a system command, or does one need to use java.lang.Runtime directly?

14:00 hugod: clojure.contrib.shell-out

14:01 The-Kenny: hugod: http://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/shell.clj#L83

14:01 whoops. sorry

14:02 hugod: :)

14:03 thios: thanks

14:07 rlb: hugod: though that won't work if you're dealing with a *lot* of output.

14:08 hugod: I started a version that's intended to support lazy process output, i.e. "lazy line seq" from a sub-process, but I haven't finished it.

14:10 (Hmm, I should go find that code...)

14:10 But not today.

14:15 slyphon: so, what's the cool thing that the kiddies are playing with these days to deal with large tree-like data structures in clojure

14:15 ?

14:20 carkh: slyphon: what do you mean ? that's pretty a open-ended question

14:20 slyphon: "clojure.zip" i think is what i was looking for

14:23 Raynes: slyphon: Zippers.

14:23 slyphon: Oh, didn't see your last message.

14:23 :p

14:23 slyphon: heh

14:27 are zippers good for editing nested hashes?

14:27 carkh: i like to (update-in [:customers customer-id] update-pricelist pricelist-id update-pl-item item-id inc rate-increase)

14:28 slyphon: yes they are

14:28 tomoj: really? I thought I remembered a discussion here that they weren't

14:28 slyphon: so if i have {:foo {:bar {:blah "thing"} } }

14:28 carkh: huh

14:29 slyphon: how do i get to blah?

14:29 chouser: I don't know that anyone has written a genearic map-zipper. There's a vector-zipper.

14:29 and xml of course

14:29 * slyphon ndos

14:29 carkh: (assoc-in {:foo {:bar {:blah "thing"} } } [:foo :bar :blah] "other-thing")

14:29 ,(assoc-in {:foo {:bar {:blah "thing"} } } [:foo :bar :blah] "other-thing")

14:29 clojurebot: {:foo {:bar {:blah "other-thing"}}}

14:29 slyphon: ahh

14:29 ok, that's good

14:30 carkh: ,(update-in {:foo {:bar {:blah "thing"} } } [:foo :bar :blah] str 2)

14:30 clojurebot: {:foo {:bar {:blah "thing2"}}}

14:45 Borkdude: I am now in emacs and got elpa installed

14:45 now which package should I begin with?

14:46 swank-clojure ?

14:47 hugod: rlb: yes, I need to implement that for clj-ssh too

15:00 S11001001: is the bit where clojure.core/compile recursively compiles loaded files considered a bug or a feature?

15:04 Borkdude: I tried to install all the needed packages through elpa now

15:05 but.. it's not working

15:05 java.lang.ClassNotFoundException: swank.swank (NO_SOURCE_FILE:0)

15:05 The-Kenny: Borkdude: You have to load the java-part too (swank-clojure.jar)

15:06 slime consists of two parts: One for the emacs-side and one for the lisp/clojure side.

15:10 Borkdude: The-Kenny, I realize that

15:10 but I can't really find out how to start from a clean emacs to a working clojure setup. how do I start best from a clean emacs?

15:11 The-Kenny: Borkdude: Oh, and elpa is just for emacs-lisp files. It won't pull swank-clojure.jar. I'd recommend leiningen for this.

15:11 Borkdude: For a clean setup, I would use leiningen to set up a clojure project, pull dependencies etc. and use elpa to install slime and swank-clojure.el (the emacs stuff)

15:12 In fact, that's what I'm using now

15:14 mrSpec: Hello! I'm trying to use Clojure mode in emacs. But does the name completion work with Java Libraries? Or I have to use Eclipse/NetBeans? eg. .addAc[TAB] => addActionListener

15:15 The-Kenny: mrSpec: I think it won't work with java-libs in it's current state. But I think it's on someones todo-list

15:16 mrSpec: The-Kenny: but does it work in other IDE?

15:16 licoresse: mrSpec: M-/ will complete the symbol if it already exists

15:17 The-Kenny: mrSpec: I don't know. I'm only familiar with slime

15:17 mrSpec: licoresse: thanks, but it doesnt solve the problem :(

15:17 The-Kenny: ok, thx

15:18 The-Kenny: mrSpec: If you're familiar with emacs-lisp, you could try implememting it :)

15:18 (I'm not even sure if you have to know elisp for that)

15:18 mrSpec: The-Kenny: I'm not familiar enough ;)

15:18 carkh: wouldn't that be coming from the swank part ?

15:18 The-Kenny: Maybe the whole completion stuff is in clojure

15:19 carkh: Yeah, sorry for that. I realized that a few seconds after I pressed enter :)

15:19 carkh: well i don't know, just guessing =)

15:20 mrSpec: so, do you write under Emacs? And do you use all java libraries without name completion? :/

15:20 licoresse: mrSpec: I do

15:20 carkh: most of the time you'll hide the java stuff and do the call only once

15:20 licoresse: there was life before name completion

15:21 The-Kenny: mrSpec: I think most people write a thin wrapper around the java stuff.

15:21 In fact, it's rather easy to use a foreign library as you mostly have the reference opened already

15:22 mrSpec: thin wrapper? could you say something more?

15:22 The-Kenny: mrSpec: Just some clojure functions to call the java stuff. Nothing more

15:22 mrSpec: ah o

15:22 s/o/ok

15:22 carkh: mrSpec: your example with addactionlistener is a good one ... when i need this, i'll just use my own function (add-action-listener (fn [action] ????))

15:23 The-Kenny: I think there's something for action-listeners in contrib too

15:23 In swing-utils

15:23 carkh: ahwell i guess i should have looked in there first =P

15:23 mrSpec: hehe

15:24 The-Kenny: http://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/swing_utils.clj#L23 heh

15:24 carkh: anyways, the thing is that i don't have to do the whole "implementing an interface" thing

15:24 mrSpec: but most I will use JUNG, Action listener was only an example ;)

15:25 carkh: just build a library of functions that will help you with that, then you need to use each of these completable verbs only once

15:25 (when writing the library)

15:25 mrSpec: carkh: ok, I will think about it

15:26 in few days I have to decide Clojure or Java

15:26 carkh: what kind of application are you aiming for ?

15:27 mrSpec: It will be aplication to show the relationships between ppl in some blogosphere.

15:28 carkh: you'll find that clojure lets you write it with less lilnes of code, but you have to think harder to produce each one

15:28 mrSpec: I think so, moreover I love lisp and hate java ;)

15:28 so clojure sounds good for me

15:29 carkh: haha well then looks like you made a decision already =)

15:29 mrSpec: :)

15:29 * The-Kenny started hating almost every language which isn't based on ( and ) after some coding with common lisp and clojure

15:30 carkh: i see (defn potential-dot "Returns a list of potential dot method name completions...." ..) in swank-clojure

15:31 so it should be working =/

15:31 The-Kenny: carkh: Huh? Where?

15:31 Ah, found it

15:34 Borkdude: The-Kenny: it turned out I had a .clojure directory

15:34 that eliminated swank-clojure asking if I wanted to install

15:35 but now that's fixed :)

15:40 The-Kenny: I think one problem is, that slime-fuzzy (that's what I'm using, fuzzy-completion is great) seems to not-use this function

15:42 carkh: i'm using it too and yes not working

15:49 The-Kenny: Understanding swank_fuzzy.el is so *damn* hard :/

15:49 s/.el/.clj/

15:55 carkh: hum yes this isn't easy stuff

15:56 could take fuzzy-find-matching-vars as a base

15:57 The-Kenny: I'm doing this just now :)

15:57 carkh: and somehow insert the result in fuzzy-generate-matchings

15:57 nice =)

15:59 The-Kenny: But I have to admit: I already tried that some time ago, and I gave up

16:13 Every time I try this I start thinking "This isn't worth the effort"

16:14 carkh: that's a one time effort for a lifetime of bliss

16:14 ...so to speak

16:28 Borkdude: Cool, I finally have a working emacs + leiningen

16:37 qbomb: The-Kenny: What is it that motivates you to try again?

16:37 The-Kenny: qbomb: I would like to see this completion. It would be a good improvement

16:45 slyphon: so, in a gen-class impl function, 'this' is explicit

16:45 ?

16:45 but in proxy it's not?

16:46 StartsWithK: slyphon, yes

16:46 slyphon: ok

16:46 just making sure

16:46 makes sense

16:46 StartsWithK: in gen-class it has to be as methods are separate functions

17:02 slyphon: so, -init is always called with whatever the constructor arguments are? so if you have multiple constructors, you should make init variadic?

17:04 StartsWithK: slyphon, yes, same goes for methods too

17:05 slyphon: ok

17:05 StartsWithK: and do your own type checking for arg types if you need that

17:05 slyphon: thanks

17:05 * slyphon nods

17:09 slyphon: StartsWithK: could you take a look at something for me?

17:09 http://gist.github.com/361587

17:09 StartsWithK: sure

17:09 slyphon: oh, hm

17:10 StartsWithK: and what is the problem?

17:10 slyphon: i could probably do this by only having a default constructor and then using a setter

17:10 well

17:11 StartsWithK: that could be a easy way out :)

17:11 slyphon: elsewhere i call (XmlRpcRequestWrapper. req new-stream)

17:11 and the compiler throws: error: java.lang.IllegalArgumentException: No matching ctor found for class mbox.harpo.xmlrpc.XmlRpcRequestWrapper (xmlrpc.clj:224)

17:11 yeah, i think i'll just do that

17:11 StartsWithK: but you can also do

17:11 (defn init ([req] do1) ([req x] do2))

17:11 Borkdude: Any ideas when I get "All :namespaces already compiled. " in a leiningen project but no classes are generated?

17:11 slyphon: oh!

17:12 Borkdude: your namespaces aren't correctly specified? just a guess

17:12 i've had trouble with that too

17:12 Borkdude: slyphon, I have this:

17:13 (defproject swingprj "0.1" :dependencies [[org.clojure/clojure "1.1.0-master-SNAPSHOT"] [org.clojure/clojure-contrib "1.0-SNAPSHOT"]] :main swingprj)

17:13 in my project.clj

17:13 slyphon: yeah, you need to specify :namespaces explicitly

17:13 StartsWithK: thanks!

17:13 Borkdude: since when?

17:13 a lot of examples on the web don't have it

17:15 slyphon: i think it's recent

17:15 technomancy would know

17:15 StartsWithK: so, it's expected that what i have would produce that error?

17:15 Borkdude: do you know how I must specify it? :namespaces [swingprj] ?

17:15 slyphon: i think it's actually each class name

17:15 i *think*

17:16 Borkdude: ah if I put :namespaces [[swingprj]]

17:16 StartsWithK: slyphon, yes

17:16 Borkdude: it generates some promising errors ;)

17:16 slyphon: StartsWithK: so it's the signatures on -init that it's unhappy with

17:17 "There's no -init that takes 2 args, dummy!"

17:17 StartsWithK: i don't think so, as you would get a error saying function has a wrong type hints

17:17 this looks like something from ctor defs in gen-class

17:18 slyphon: ah

17:18 hrm

17:18 Borkdude: hmm I think this is wrong

17:18 StartsWithK: but then again.. with gen-class you never know for sure :)

17:18 slyphon: StartsWithK: ah, yeah, it all seems a little...hit-or-miss

17:19 StartsWithK: try constructiong a stub in java, its what i do

17:19 slyphon: yeah?

17:19 hrm

17:19 yeah, i guess i could do that

17:20 StartsWithK: public class MyStub { public Map<String, IFn> ifns = new HashMap<String, IFn>(); void someMethod(String arg) { ifns.get("someMethod").invoke(arg); }

17:21 length is almost the same, same compile problem.. no problems with differen clojure versions.. and i know how what to write

17:21 slyphon: clever

17:22 so

17:23 you assoc "methName" (fn [] (println "i am methName")) with MyStub/ifns ?

17:23 s/with/in/

17:23 or .add rather, i guess

17:24 i'm just a little confused as to what the ifns thing is doing

17:24 that lets you poke clojure into the java class?

17:24 StartsWithK: (.put MyStub/ifns "lalala" (fn []))

17:24 just make ifns static

17:24 slyphon: ah, gotcha

17:24 StartsWithK: it holds fn's from clojure side, this is more-or-less what gen-class will do too

17:24 slyphon: yeah, totally

17:25 ok, yeah, this makes sense

17:25 Borkdude: slyphon, what is the format in which to specify the namespaces

17:25 I get all kinds of weird error msgs

17:25 slyphon: um

17:25 i think it's :namespaces [my.full.namespace.ClassName]

17:25 again, i haven't had much luck with it

17:27 Borkdude: technomancy is the author, he'll most likely be able to give you more authoritative answers

17:27 Borkdude: technomancy ... can you answer this?

17:30 technomancy: :namespaces [my.full.namespace] should do it

17:30 it's not about the gen-class so much as it is the namespace that contains it

17:30 but I've never done AOT in any of my projects before, so take it with a grain of salt. =)

17:31 slyphon: technomancy: is there a leiningen plugin that handles building java classes?

17:33 technomancy: sure, lein-javac

17:33 Borkdude: technomancy, so I don't even need to compile in order to create an (uber)jar or what?

17:33 technomancy: haven't used that either

17:33 slyphon: technomancy: ah, cool

17:34 technomancy: Borkdude: in general: you never need to compile unless you want java interop or a main class for an executable jar

17:34 Borkdude: I have some java interop in the code

17:34 technomancy: (that may not be 100% accurate with new 1.2 features)

17:34 Borkdude: I am just trying something simple to see if I can get a project compiled to an uberjar

17:35 but I don't know what I'm doing wrong her

17:35 e

17:37 borkdude@Ubuntu-VM:~/temp/swingprj$ java -jar swingprj-standalone.jar Exception in thread "main" java.lang.NoClassDefFoundError: swingprj

17:38 slyphon: i hate you java

17:39 Borkdude: I have this structure: swingprj/project.clj

17:39 swingprj/src/swingprj.clj

17:41 zaphar_ps: Borkdude: does swingprj.clj have a gen-class in it's namespace declaration?

17:41 The-Kenny: uhm.. isn't the use of single-element namespaces discouraged?

17:42 zaphar_ps: The-Kenny: why. If it's not library code there is little need to have a deep namespace

17:43 The-Kenny: zaphar_ps: I know. But I saw some people here talk about problems with single-element-namespaces. Maybe that's the problem here.

17:43 zaphar_ps: hrmmm I've never had an issue it was usually because I didn't have the gen-class directive that this particular error would crop up

17:44 Borkdude: zaphar_ps, I have this in swingprj.clj

17:44 zaphar_ps: Borkdude: use a pastebin please

17:45 Borkdude: zaphar_ps: nevermind, I think I got it now

17:45 zaphar_ps: :-)

17:47 Borkdude: I used a dash in the namespace

17:47 probably that caused it

17:47 * technomancy suspects The-Kenny is on to something

17:48 The-Kenny: technomancy: huh, why? The fuzzy-completion-stuff?

17:48 technomancy: no, I mean the single-segment namespace problem

17:48 zaphar_ps: technomancy: what issues are arising with single element namespaces?

17:48 Borkdude: and it looks like the :namespacs is not really mandatory, can you confirm this technomancy?

17:48 :namespaces

17:48 technomancy: Borkdude: if you have :main set and your main requires your nses that need AOT then that might be enough

17:49 zaphar_ps: I'm fuzzy on the details; just have heard a proclamation to the effect of "don't do it"

17:49 something to do with Java packages

17:49 zaphar_ps: hrmmm interesting

17:50 is that only when doing AOT or is it for all clojure namespaces

17:50 technomancy: I think it's AOT-specific

17:51 jholloway7: Hi. How do you invoke constructor of static inner class? I tried: (Outer/Inner. args) throws IllegalArgumentException saying there is no matching method

17:55 slyphon: swank is failing me

17:56 Borkdude: jhollaway7, try this? http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Cookbook#Accessing_inner_classes

17:57 so with the dollar sign

17:57 never tried it myself though

17:58 bsteuber: cool, polyglot maven with leiningen-support - http://groups.google.com/group/clojure/browse_thread/thread/2949d054ca166da9

17:58 in case this wasn't posted already a hundret times :)

18:00 s/t/d/

18:02 Borkdude: cool, my stand alone app works in ubuntu, xp and win7

18:12 jholloway7: Borkdude, thanks will give it a shot

18:53 sattvik: Hmm... My CA has been received, and I am listed on the contributors page. However, I have not been approved for the clojure-dev mailing list. Also, should I be a 'team member' for Clojure on Assembla now? I can't seem to comment on tickets I have not opened.

18:53 TakeV: How do you install/use leiningen addons?

18:56 technomancy: TakeV: add them as dev-dependencies and do lein deps

18:56 TakeV: technomancy: Hmm, that didn't seem to work for autodoc.

18:58 technomancy: To the project.clj, right?

18:58 technomancy: that's the idea

19:14 defn: TakeV: did you run lein deps after you added it?

19:15 ndimiduk: TakeV: lein clean will delete the content of lib and thus uninstall your dev-dependencies

19:15 TakeV: defn: Yes. When I then try to run "lein autodoc", it tells me that autodoc is not a task.

19:16 defn: what does your lein version tell you

19:16 TakeV: Leiningen 1.1.0 on Java 1.6.0_0 OpenJDK Client VM

19:19 defn: TakeV: hm, weird

19:20 ndimiduk: TakeV: is the plugin compatible with 1.1.0?

19:20 defn: TakeV: what version of autodoc? 0.7.0?

19:20 ndimiduk: i don't know if the revbump broke internal APIs

19:20 TakeV: Yes, 0.7.0.

19:21 ndimiduk: TakeV: try just running `lein` after a `lein deps`- it should list the available tasks

19:22 TakeV: Odd, it randomly started working...

19:24 Err, thanks for the help, though. 0_o

19:24 slyphon: so, is there a convention to wrap the pattern (if (pred? thing) (xform thing) thing)

19:25 like (xxx pred obj & body)

19:27 * slyphon seems to remember that scala had a word for that pattern

19:33 lancepantz: is there a way i can define a string with a different delimiter than "?

19:33 like %{foo} in ruby

19:34 do then %{a"b} returns "a\"b"

19:34 *so

19:35 slyphon: i don't think so

19:35 that'd be a reader macro

19:36 you could probably do something sneaky like define a macro s

19:36 and just concat all the stuff inside

19:36 * slyphon wrote a %w-like func

19:37 lancepantz: yeah, thats probably my best bet

20:40 defn: you could make a map and {:a my-delim :b inner :b inner :b inner :c my-delim}

20:40 and then build from there?

20:40 rlb: Do I recall correctly that nested defs are not appropriate in clojure?

20:41 defn: rlb: better to use a let

20:43 rlb: thx

20:45 hiredman: def is not lexically scoped like schemes define

20:45 rlb: hiredman: ahh, that's what I (almost) remembered -- thx.

21:06 slyphon: is there an easy way to get clojure.xml/parse to parse a string as input?

21:08 or do you just have to wrap it in a ByteArrayInputStream

21:08 hiredman: bytearray is the easy way

21:08 slyphon: k

21:09 seems kinda...lame?

21:10 i mean, i very well could be missing something

21:17 defn: 2 quick questions on namespace stuff...

21:17 slyphon: "yes", and "only on thursdays"

21:17 was i right?

21:17 defn: 1. When I use defn- in a namespace, does that mean that I can have public defns which use those private defn-s?

21:17 slyphon: that works for me

21:17 carkh: yes

21:17 slyphon: just watch out for macros

21:18 that expand and call private dfns

21:18 defn: 2. Should I use in-ns to split up a large file into more logical pieces, or is this bad?

21:18 slyphon: oooh

21:18 defn: slyphon: ah yeah didnt think of that

21:18 * slyphon wants to hear the consensus on that

21:18 slyphon: defn: yeah, it's tripped me up a couple of times

21:18 it's pretty obvious when it happens though

21:18 carkh: i keep one file per ns

21:18 slyphon: i've found moving the private stuff into an "internal" namespace is good

21:19 carkh: if you need 2 files, then you can make sub-namespaces

21:19 defn: core.clj and utils.clj seem like they could reside in the same namespace

21:19 carkh: good point

21:19 slyphon: carkh: i don't understand

21:19 if you have two files, *then* you can make sub-namespaces, or it's just better to structure things that way with one-file-per-namespace

21:20 defn: i had absolute namespace hell -- still sort of do -- i let them get away from me

21:20 carkh: sometimes a single namespace grows a lot

21:20 technomancy: definitely don't use in-ns anywhere except the repl

21:20 slyphon: defn: circular references drove me insane for a good hour or two last week

21:20 defn: technomancy: reason! logic! i need none of this!

21:20 carkh: so when it's getting too big, i do a bit of refactoring

21:20 technomancy: if you break the one-ns-per-file, one-file-per-ns rules your code just gets a lot harder to follow

21:21 defn: technomancy: good point

21:21 technomancy: contrib sets a bad example here

21:21 slyphon: technomancy: what do you mean "rules your code"

21:21 ?

21:21 technomancy: should be a comma after "rules"

21:21 slyphon: ah

21:21 defn: if you break the .... rules, your code...

21:21 slyphon: ok

21:22 technomancy: gotta jet; see you cats later

21:22 slyphon: kk

21:22 what do you guys put in 'user.clj'

21:22 ?

21:22 carkh: nothing

21:22 well

21:22 nothing for the final application

21:22 * slyphon nods

21:23 slyphon: repl stuff?

21:23 carkh: i use it to play while developing

21:23 defn: could user.clj be useful for configuration vars?

21:23 carkh: yes i have a doc searching macro

21:23 defn: seems like a decent place for them

21:23 slyphon: defn: might as well make that stuff namespaced as well

21:23 no?

21:23 carkh: user is for interactive use

21:24 defn: slyphon: maybe... i guess i dont see why it couldnt go either way

21:24 carkh: (to me at least)

21:24 defn: carkh: even still, some users may use some code i wrote interactively

21:24 it might be nice to include some helper stuff

21:24 carkh: like you make a program that your user interacts with via the repl, you boot himm in there

21:25 then you can import the top level commands of your program

21:25 but that's very 1970 as user interfaces go

21:26 slyphon: what goes in 'core'?

21:27 carkh: you mean clojure.core ?

21:27 slyphon: no, like, my.ns.core

21:27 leiningen creates one by default

21:27 carkh: i don't use that convention

21:27 slyphon: ah, ok

21:27 defn: i like the core convention

21:28 question on namespaces again... when do you use com.blah net.blah, etc.?

21:28 it seems sort of loose

21:28 carkh: that's java convention, they do it like their real url

21:29 i just go cara.my-app-or-library

21:29 slyphon: i strip off the 'com'

21:29 so like, motionbox.prj-name.thing

21:30 carkh: the url thing makes sense as it's quite unique

21:30 there are no 2 com.google.blahblah

22:04 defn: I have a structure which looks like: (["some string", "another string"] ["some string 2", "another string 2"])

22:04 how can I remove duplicates based on the first of each []

22:05 slyphon: hrm

22:05 defn: i was thinking about a sorted-set maybe, but after i map first across, i lose the context

22:06 underdev: defn, what's the url of that clojure examples app you made?

22:06 defn: http://getclojure.org:8080/examples/concat

22:06 replace concat with whatever

22:06 slyphon: well, if i were gonna do this with ruby or something

22:06 defn: some examples don't work still underdev, but it's a WIP

22:06 slyphon: i'd make a collector that's a hash

22:06 underdev: rt on

22:06 all good

22:07 slyphon: and just check each item, see if the key is already in the hash, if not add it

22:07 i guess you lose ordering that way though

22:07 underdev: oooh, syntax highlighting, very nice

22:07 chouser: slyphon: you want to keep the first or the second?

22:07 underdev: how did you do that?

22:07 chouser: slyphon: and you want to keep order or not?

22:07 slyphon: chouser: defn's the one

22:07 chouser: oh, sorry

22:07 slyphon: chouser: i'm just trying to think it out :)

22:07 np

22:08 chouser: defn: same questions. :-)

22:08 tomoj: defn: did you get the include-js stuff working, then?

22:08 defn: chouser: i want to keep both the first and second, i just want uniques for the list of [] [] []

22:08 tomoj: i did yes :)

22:08 slyphon: it's funny, i was gonna say before "these are the kind of questions usually answered by chouser or hiredman"

22:08 tomoj: cool

22:09 chouser: defn: I still don't understand ([:a 1] [:a 2] [:b 3]} becomes what? ([:a 1] [:b 3])?

22:09 slyphon: so, after i have an xml-tree created by clojure.xml/parse, er, how do i emit that as xml?

22:09 defn: (["x", "y"] ["x", "y"] ["x1", "y2"]) => (["x", "y"], ["x1", "y2"])

22:10 slyphon: i see the reading but not the writing

22:10 defn: actually nevermind -- i can just called sorted-set on that structure, huh?

22:11 ,(sorted-set '(["x", "y"] ["x", "y"] ["x1", "y2"]))

22:11 clojurebot: #{(["x" "y"] ["x" "y"] ["x1" "y2"])}

22:11 slyphon: hmm

22:11 fail

22:11 defn: er maybe not

22:12 ,(apply sorted-set '(["x", "y"] ["x", "y"] ["x1", "y2"]))

22:12 clojurebot: #{["x" "y"] ["x1" "y2"]}

22:12 defn: there we go

22:12 slyphon: ah, there you go

22:13 lancepantz: ,(->> '(["x", "y"] ["x", "y"] ["x1", "y2"]) (into {}) (into ()))

22:13 clojurebot: (["x1" "y2"] ["x" "y"])

22:13 defn: ah, nice

22:15 slyphon: well, the zip example is pretty spiffy, i just mutated xml without really grokking what's going on

22:15 which i guess is both good and bad

22:15 carkh: ,(distinct [["x", "y"] ["x", "y"] ["x1", "y2"]])

22:15 clojurebot: (["x" "y"] ["x1" "y2"])

22:16 slyphon: if you call zip/root at any point in the walk of a tree, do you get the whole (possibly mutated) tree?

22:16 defn: (doc distinct)

22:16 clojurebot: "([coll]); Returns a lazy sequence of the elements of coll with duplicates removed"

22:16 defn: oo, cool

22:16 carkh: ~def distinct

22:17 lancepantz: i dont think thats what you want

22:17 ,(distinct [["x", "y"] ["x", "y1"] ["x1", "y2"]])

22:17 clojurebot: (["x" "y"] ["x" "y1"] ["x1" "y2"])

22:18 carkh: you can addapt the source to look inside the vectors

22:18 it's O(n) and preserves order

22:19 there should be a "key" parameter

22:19 i mean to the standard function

22:20 so you could (distinct first col)

22:20 could be added easy with no breaking change

22:20 lancepantz: ,(->> '(["x", "y1"] ["x", "y"] ["x1", "y2"]) reverse (into {}) (into []) reverse)

22:20 clojurebot: (["x" "y1"] ["x1" "y2"])

22:37 defn: carkh: very grateful for that tip

22:37 thanks

22:38 carkh: =)

23:41 quotemstr: How well does Clojure work on Android these days?

23:42 hiredman: not very, androids gc isn't very good, and it's jit is experimental and turned off by default

23:46 TakeV: Android doesn't use the JVM, right?

23:48 quotemstr: Right; it has its own JVM.

23:48 NIH.

Logging service provided by n01se.net