#clojure log - Dec 11 2009

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

0:00 KirinDave1: technomancy: Last time I tried to make a client for my katamari software… man that sucked. All the web libraries wanted to dump reqs into buffers, and it became very tedious.

0:00 technomancy: annoying from a coding perspective or from a UI perspective?

0:01 once you understand the APIs doing webby stuff is not bad: http://github.com/technomancy/relax.el

0:01 header/body separation could certainly be better

0:03 KirinHome: technomancy: So does paredit mode work with erc? :)

0:03 technomancy: KirinHome: heh; I'm not *that* hardcore. =)

0:04 jush show-paren-mode for blink-matching

0:04 clojurebot: for is not a loop

0:04 KirinHome: Man, paredit is the epic mode though.

0:04 defn: i havent gotten very good with it yet

0:04 KirinHome: M-r is like, the king of all commands.

0:04 defn: its kind of annoying to me tbh

0:04 but im probably just ignorant to its epic-ness

0:04 KirinHome: it's really essential

0:05 C-) and C-( are the most important commands, imho

0:05 technomancy: sluuuuuuuuurp

0:06 KirinHome: Wow, it's windowed.

0:06 defn: those give me "unbalanced parentheses" errors

0:06 but im clearly balanced

0:07 KirinHome: defn: Try going in front of a sexp, then type (. Then type C-).

0:07 defn: okay that's awesome.

0:07 KirinHome: Yeah dude

0:07 Now, you should have something like ( (sexp))

0:08 defn: ive been tabbing through my whole form to get my indentation fixed after doing something

0:08 yeah

0:08 chouser: %

0:08 KirinHome: Put the cursor at ( |(sexp))

0:08 And hit M-r (another of my faves)

0:08 technomancy: KirinHome: I find myself using M-s a lot more than M-r

0:09 defn: the just deletes everything in the scope of the paren you're in front of?

0:09 KirinHome: defn: it raises the sexp you're on to a level up, and kills all surrounding sexps at that level.

0:09 Paredit mode is basically hotkeys for tree editing.

0:09 devlinsf: Chouser

0:10 defn: ah gotcha, cool

0:10 <--young jedi

0:10 chouser: devlinsf

0:10 devlinsf: http://fulldisclojure.blogspot.com/2009/12/uses-for-takedrop-while.html

0:10 As promised

0:10 KirinHome: So, we can't let erlang get too far ahead

0:10 compojure needs websocket support. ;)

0:10 defn: haha

0:10 compojure is a lot bigger than i imagined it would be

0:11 i wish the documentation was better

0:11 KirinHome: The master version is quite small.

0:11 There is talk of more, it seems.

0:12 defn: i dunno, it's not "huge", but i thought it would be missing some of the stuff it has

0:12 chouser: devlinsf: nice.

0:12 devlinsf: Thanks :)

0:12 chouser: reminds me a bit of finger-tree applications.

0:12 ,(into (sorted-map) {3 :a 1 :c 2 :b})

0:12 clojurebot: {1 :c, 2 :b, 3 :a}

0:13 technomancy: some dude who does screencasts contacted me about recording my the paredit screencast I wrote a script for

0:13 * technomancy is hopeful

0:13 devlinsf: Hmmm

0:13 Interesting. Never heard the term before

0:13 The wiki article looks cool

0:14 chouser: oh, finger-tree? yeah, they're a hobby of mine. apparently. :-|

0:14 (doc subseq)

0:14 clojurebot: "([sc test key] [sc start-test start-key end-test end-key]); sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true"

0:14 defn: damn -- that's a bummer -- I thought I had this figured out with (append-spit (apply str (map #(print-doc %) (sort (keys (ns-publics 'compojure))))))

0:14 devlinsf: Huh

0:14 Cool

0:15 defn: too bad it only prints to the repl

0:15 devlinsf: Subsec returns a seq though, right?

0:15 sub-seq

0:15 chouser: yes

0:15 devlinsf: Okay

0:15 Still cool

0:15 technomancy: hiredman: I'll switch off bash right after 1.0.1

0:16 defn: is there any way to redirect (print-doc name) to append-spit?

0:16 the printed output i mean...

0:16 chouser: I think the double high-levelness of your functions is what's slowing down my comprehension. I just need to take the time to "get" it.

0:16 devlinsf: Yeah, I'm still not 100% sure if I get it

0:16 chouser: defn: (binding [*out* my-output-stream] ...)

0:16 devlinsf: :-)

0:18 devlinsf: Chouser: I'll try to have an intro doc ready by the end of the day tomorrow

0:18 chouser: great, thanks!

0:19 devlinsf: I'l post it on my github to start.

0:20 defn: chouser: im not sure how to use that. this was my first thought: (binding [*out* (map #(print-doc %) (sort-ns 'compojure))])

0:20 (append-spit (file-str "~/" "test.txt") *out*)

0:20 KirinHome: Hum, paredit mode seems to work fine..

0:20 Ahh, it doesn't if there are unmatched parens in thebuffer. that's too bad.

0:21 defn: sorry for all the questions -- i know they're a bit remedial compared to some of the other stuff going on in here

0:21 chouser: defn: sorry, I can see how my post could be misleading. my-output-stream needs to be a Java text-outputing stream.

0:21 the ... si where your code that does print-doc stuff would go.

0:24 ,(use '[clojure.contrib.map-utils :only [deep-merge-with]])

0:24 clojurebot: nil

0:24 chouser: ,(let [m {:a {:b [1, 2, 3, 4]}, :b {:c [5, 6, 7]}}] (deep-merge-with #(apply + %2) m m))

0:24 clojurebot: {:a {:b 10}, :b {:c 18}}

0:24 chouser: clearly an abuse of deep-merge-with.

0:26 defn: chouser: what's an example of a text outputting stream? I tried doing (let [stream (FileOutputStream)])

0:27 errr FileOutputStream.

0:28 chouser: (with-open [tmp-txt (java.io.OutputStreamWriter. (java.io.FileOutputStream. "tmp.txt"))] (binding [*out* tmp-txt] (print "hi")))

0:29 or use duck-streams from contrib

0:30 defn: chouser: ah-ha! with-out-writer im guessing

0:30 chouser: yeah, that looks good. just give it a filename.

0:31 defn: (with-out-writer "myfile.txt" (apply str (map #(print-doc %) (sort-ns 'compojure))))

0:31 something like that maybe

0:32 chouser: hm, I think you're still misunderstanding what's going on.

0:32 defn: gah

0:32 i dont need the apply str

0:32 chouser: print-doc will print out to whatever

0:32 right.

0:33 but you shouldn't use 'map' because you're using print-doc for its side-effect of printing to *out*

0:34 either wrap 'map' with 'dorun' or just use 'doseq' instead of 'map in the first place.

0:38 defn: chouser: thanks for all the patience again, finally got this working: (with-out-write (file-str "~/" "test1000.txt") (doseq [s (sort-ns 'compojure)] (print-doc s)))

0:38 chouser: defn: looks great!

1:03 defn: http://gist.github.com/254019 <---I'm interested in turning this into an executable jar: java -jar doc-ns.jar "compojure" "~/path/" "filename.txt"

1:04 I've placed that code in a new lein project with the proper deps setup in project.clj

1:04 i `lein compile`, and finally `lein uberjar`, running the jar doesn't do anything though, what am i doing wrong there?

1:08 technomancy: defn: did you set a :main key in your project.clj to match your main ns?

1:09 defn: i didnt

1:11 Exception in thread "main" java.lang.NoClassDefFoundError: doc-ns

1:11 says it can't find my class doc-ns, but that's what the ns is named

1:13 technomancy: which step causes the exception?

1:15 defn: running the jar

1:17 technomancy: oh, you can't AOT namespaces that don't have a dot in them

1:17 nothing to do with leiningen

1:17 defn: i did that actually -- (ns doc-ns.core

1:18 technomancy: but the exception says it's still looking for doc-ns without core

1:19 defn: the earlier one yes, but while we were talking i edited the :main to be doc-ns.core

1:19 and changed my doc-ns.clj to (ns doc-ns.core...

1:19 then lein clean, lein compile, lein uberjar

1:20 Exception in thread "main" java.lang.NoClassDefFoundError: doc-ns/core

1:21 technomancy: did you move it to src/doc-ns/core.clj?

1:23 defn: i did not, but now that i have it still gives me the same exception, i have a feeling im doing something stupid here

1:23 src/doc-ns/core.clj => (ns doc-ns.core...., project.clj => :main doc-ns.core

1:26 technomancy: is core getting :gen-classed?

1:26 defn: yes

1:27 http://gist.github.com/254026, http://gist.github.com/254027

1:27 technomancy: defn: trying a sample project uberjar righ tnow

1:28 are you running the standalone jar?

1:28 defn: not every time

1:28 i had exceptions on both, but let me try now

1:29 technomancy: could it be the '-'?

1:29 technomancy: the non-standalone jar doesn't contain clojure, so you can't run it with java -jar

1:29 defn: oh, the files on disk need - replaced with _

1:29 JVM limitation

1:29 defn: like folder names?

1:29 project names? everything?

1:30 technomancy: I'm not sure if it's directories or just .clj files

1:30 it might be everything that is inside a directory/jar that's on the classpath

1:30 defn: 'cause currently i have core.clj, no '-'s, ill try to switch the dir name

1:31 doc-ns/src/doc-ns/core.clj

1:31 so that should be doc-ns/src/doc_ns/core.clj?

1:31 technomancy: I think so

1:31 defn: i think that fixed it

1:31 uberjarring...

1:32 bah

1:32 need to change my main to doc_ns.core maybe?

1:32 technomancy: no, it only affects filenames IIUC

1:33 defn: i think that i actually needed to do that

1:33 Exception in thread "main" java.lang.NoClassDefFoundError: doc-ns/core

1:33 technomancy: just try docns =)

1:34 defn: ^^that's a good error, looks like it at least found the class, probably just my inept clojure mucking things up now :)

1:35 technomancy: thanks for the tech support, i would have never figured that out on my own

1:36 technomancy: do you know how id pass a cmdline arg like "compojure", and have it interpreted as 'compojure ? I was thinking (quote (symbol "abc"))

1:38 technomancy: defn: I think you just want symbol

1:40 defn: awesome, finally got this *beast* of an application running -- kind of sad to think of how long i spent writing an application to do this... lol

1:43 technomancy: thanks again for everything, cheers

1:43 technomancy: np

1:50 pelotom: does clojure have static type-checking?

2:35 rlb: pelotom: depending on what you're asking, probably not.

2:37 pelotom: rlb: is my question ambiguous?

2:38 rlb: clojure is dynamically typed, though you can provide type annotations that can help with performance.

2:39 pelotom: rlb: performance isn't my concern so much as deferring till runtime problems that could've been discovered at compile time

2:40 rlb: pelotom: then the answer to your question is a definitive no.

2:40 pelotom: rlb: ok, thanks

2:41 rlb: clojure is a lisp dialect.

2:45 pelotom: rlb: right, I wasn't sure if that precluded a static type system

2:48 ajray2: is there a decompiler for clojure?

2:52 replaca: ajray2: not that I've heard of

2:56 ajray2: replaca: thanks

3:09 LauJensen: Goooood morning :)

3:51 Fossi: LauJensen: vietnam?

3:51 LauJensen: Yea I almost wrote that Fossi, but then remembered that is was 'spoken' in one of the most disgusting wars yet to be started by the US, so I just stuck with 'good morning' :)

3:52 cark: you sure look like in a good mood =) good morning !

3:53 LauJensen: Thanks

3:53 Anybody here know of a good free mailing list service, ale Googles but without the suck ?

3:54 Fossi: LauJensen: well, a collegue of mine saw a few shops in vietnam selling it on t-shirts as merchandise

3:54 so it can't be that bad ;)

3:54 LauJensen: Fossi: If you labeled anything that men are willing to make money on as being 'not that bad' then......

4:07 somnium: anyone have any recommendations on nio/netty/nio for tcp/ip with clojure?

4:09 er mina, that was the third one

4:09 vy: netty is cool, imho.

4:11 somnium: vy does it offer a better api than nio?

4:11 vy: somnium: Easy to use I'd say.

4:11 somnium: vy: good enough for me then :)

4:12 coffee and javadocs for breakfast

4:22 piccolino: I thought it was hard to use Netty from Clojure, since it requires the use of annotations.

4:30 somnium: hmm, I just need a ByteBuffer and a socket really

4:30 cark: so why don't you use regular sockets ?

4:31 my understanding was that nio is only usefull with lots of connections

4:32 somnium: cark: what java package?

4:33 cark: java.net

4:39 eevar2: cark: nio is supposed to let you offload a lot of the work directly to the os itself, meaning lower overhead. which probably won't matter a lot unless you have a ton of transfers going, as you say

4:42 cark: what's a java decompiler that will work on clojure AOT jars ?

4:43 hiredman: clojure compiles to class files

4:43 cark: right

4:43 hiredman: as does java, I doubt any decompiler will "work on" jars

4:44 cark: you're nitpicking

4:44 hiredman: ~google cljdb decompile

4:44 clojurebot: First, out of 2 results is:

4:44 CLJDB 0.3

4:44 http://georgejahad.com/clojure/cljdb.html

4:44 hiredman: I think that is the one, no web browser open

4:44 cark: it says that's a debuger

4:45 but thanks !

4:46 hiredman: hmmm

4:47 ah

4:47 ~google clojure decompiled

4:47 clojurebot: First, out of 1110 results is:

4:47 Clojure Decompiled

4:47 http://georgejahad.com/clojure/clojureDecompiled.html

4:48 hiredman: so close

4:48 cark: ah i tried this one already

4:48 i wouldn't go inside some of my nested namespaces

4:49 hiredman: nested?

4:49 cark: i mean : it shows there is a cara.webtl but doesn't show what's under it

4:49 like cara.webtl.bleh

4:50 hiredman: namespace, like java packages are not a hierarchy

4:50 cara.webtl is a name, and cara.webtl.bleh is a name

4:50 cark: well it's presented like that in the gui of the program =)

4:50 hiredman: they have no connection except for the string representation

4:50 cark: works for other namespaces

4:51 hiredman: perhaps I misunderstand what you want

4:51 cark: i want to see my class cara.webtl.bleh but that wont work, while i can see cara.data.trie

4:52 that's a bug in the decompiler as i know for sure the program works

4:53 hiredman: cara.webtl.bleh is a class or a namespace?

4:53 cark: well it's a clojure namespace

4:53 hiredman:

4:53 and the decompiler works on classes...

4:54 cark: well believe me it's not working ... each decompiler i'm trying is showing different stuff, sometimes exactly what i want, except for the one clojure namespace i'm trying to check

4:59 tomoj: doesn't clojure generate bytecode that java can't?

4:59 cark: ah could be

5:00 well the whole point was to make sure the deocmpiled code wasn't too obvious, i can't even get to it so i guess it's ok

5:01 hiredman: jvm bytecode is fairly high level

5:01 cark: right

5:02 the customer wants wome kind of licence key system

5:02 tomoj: man I'm glad I don't have to deal with that shi

5:02 * hiredman just got clojure.asm.* to generate a ClassLoader with no dependency on the clojure runtime and a .add method for adding urls to be searched for classes

5:03 cark: i warned him that it wouldn't be very secure

5:03 hiredman : you mean to sidestep the classpath issues ?

5:03 Licenser_: licenser key systems are nonsense -.- the best I've seen use public/private key combos so to say 'signing' a license

5:03 hiredman: I am not sure

5:04 cark: I am looking in that direction, but I don't know enough about the issues to be sure if thise solution effectively sidesteps them

5:04 cark: Licenser: i think the customer just wants to make it non-obvious to copy the program

5:04 it doesn't need to be rock solid

5:05 hiredman: there are obfuscators

5:05 cark: still the cryptography stuff is a real pain

5:05 hiredman: I don't think java even has support for say, signed jars

5:05 (like on the clr)

5:05 cark: right, i couldn't get proguard to obfuscate my jar

5:05 hiredman: :|

5:06 cark: looks like i should be using a more recent version of clojure

5:12 qed: Is it possible to nest variables in a string for shell-out?

5:13 like (sh (concat "ps aux | grep " var))

5:13 hiredman: why would it be concat?

5:14 is var a seq?

5:14 tomoj: maybe you want format?

5:14 ,(format "ps aux | grep '%s'" "foo")

5:14 clojurebot: "ps aux | grep 'foo'"

5:16 qed: yeah, (format), for some reason I thought that was Java only

5:16 tomoj: str works for your above though

5:16 better than (apply str (concat ...)

5:17 qed: yeah

5:18 octe: http://paste.lisp.org/display/91938 <- shouldn't that create a set containing each line fromt he file?

5:19 hiredman: nope

5:20 that creates a hash-set that contains a lazy-seq

5:20 octe: oh

5:20 well, what would be a good way to do what i want?

5:20 hiredman: hmmm

5:21 ,(apply conj #{} [:a :b :c])

5:21 clojurebot: #{:a :c :b}

5:21 hiredman: ,(into #{} [:a :b :c])

5:21 clojurebot: #{:a :c :b}

5:22 hiredman: ,(reduce conj #{} [:a :b :c])

5:22 clojurebot: #{:a :c :b}

5:22 hiredman: into is clearly to be prefered to reduce here

5:22 but into vs. apply conj

5:22 hmmm

5:24 into over conj

5:24 ,(into #{} [:a :b :c])

5:24 clojurebot: #{:a :c :b}

5:26 octe: hmm

5:26 ,(first (into #{} [:a :b :c]))

5:26 clojurebot: :a

5:27 hiredman: ,(type #{})

5:27 clojurebot: clojure.lang.PersistentHashSet

5:27 hiredman: not sorted

5:27 octe: yeah

5:27 doh, needs to trim every line in the file too

5:27 hiredman: (but you specified hash-set, which #{} is)

5:28 octe: yeah

5:28 do not need sorted

5:34 does this look correct? http://paste.lisp.org/display/91939

5:34 i want to count number of unique entries lines in "in.txt" that do not exist in "before.txt"

5:36 hiredman: looks fine

5:41 octe: yup, seems to work, wrote a java version to verify

5:41 don't trust my clojure skills yet :)

5:46 Chousuke: octe: you can use sets as predicates

5:47 octe: the (filter #(not (contains? old %)) ...) can be simplified to (remove? old current)

5:47 oops

5:47 -?

6:00 octe: Chousuke: cool

6:13 Chousuke: Unable to resolve symbol: remove? in this context

6:13 is that a new function?

6:13 running clojure 1.0

6:13 LauJensen: remove the ? :)

6:13 ,(remove even? (range 10))

6:13 clojurebot: (1 3 5 7 9)

6:14 Chousuke: octe: yeah, I made a typo

6:15 sids: how do I create a nil of a certain type? I'm trying to use this constructor from clojure: http://weka.sourceforge.net/doc/weka/core/Attribute.html#Attribute(java.lang.String, weka.core.FastVector)

6:18 Chousuke: you don't need to :/

6:18 oh but hm

6:18 use a type hint

6:18 qed: What's a good way to get directory listings in clojure? Specifically I'd like to recursively filter filenames that math #"foo"

6:18 octe: Chousuke: thanks, worked

6:18 Chousuke: sids: #^FastVector nil

6:19 I wonder if that works...

6:19 sids: Chousuke: tried that, but it isn't working

6:20 Chousuke: Hm. might not be possible.

6:21 this could be considered a defect.

6:21 Can you work around it? pass some non-nil value?

6:22 or maybe make a function that is type-hinted as returning a FastVector and then return nil?

6:22 sids: Chousuke: unfortunately, no. the constructor's behavior changes depending on whether null is passed or not

6:22 Chousuke: #^FastVector ((constantly nil))?

6:23 or (let [x nil] (... #^FastVector x))

6:23 qed: is there a function in closure to get a directory listing, or is that (sh) material?

6:23 Chousuke: qed: you should be able to use java for that.

6:23 qed: might be something in contrib for it too

6:23 sids: Chousuke: thanks, but none of those work :(

6:23 qed: shell-out works

6:24 Chousuke: file-seq or something :/

6:24 qed: see the File class anyway

6:24 ordnungswidrig: hi all

6:26 sids: Chousuke: figured it out! type-hinting the first as well as the second arguments works

6:30 qed: Chousuke: like (def mydir (java.io.File. "~/"))?

6:30 How do I get the listing on that mydir object?

6:31 Chousuke: qed: read the docs :)

6:31 qed: ahh, nvm, (apply vec (.list directory))

6:32 sorry, something of a java newb

6:32 Chousuke: the javadocs are pretty good.

6:32 don't need to know much java to understand them, either.

6:34 qed: one question i have is: once I do something like (map #(str %) (.list directory)), ive basically lost my ability to use .isDirectory on those elements, yes?

6:34 esj: probably out of place, but file-seq might be helpful ?

6:34 Chousuke: yes.

6:35 also #(str %) == str

6:39 qed: esj: thanks a lot for that, i didnt know that was in core

6:40 esj: qed: np.

6:43 tomoj: when you use file-seq, do you just get the file and all its descendents with no way to, say, just get 1 level of the tree?

6:44 esj: dunno, never actually used it.

6:44 tomoj: seems a tree-seq is just a lazy seq

6:44 so I think what I said is true :/

6:46 (seq (.listFiles ...)) seems to work for just 1 level

7:06 qed: tomoj: yeah file-seq does the recursive thing for you

7:07 and (.. directory list) did exactly as you say, the top level

7:07 it wouldnt be too hard to do the whole thing, but id rather use clojure where I can

7:07 whole thing in java*

7:07 im determined to be good at clojure

7:08 because im secretly avoiding java

7:10 octe: java, or at least the library, is an asset to clojure

7:11 qed: octe: i know i know, im just being petty and biased

7:11 :)

8:41 weird, for some reason I get a nullpointer exception on (doseq [s (sort (keys (ns-publics 'clojure.contrib.duck-streams)))] (print-doc s))

8:41 but not for the same statement with 'compojure

8:41 both are have been (use'd)

8:44 ,(sort (keys (ns-publics 'clojure.contrib.duck-streams)))

8:44 clojurebot: (*append-to-writer* *buffer-size* *byte-array-type* *default-encoding* append-spit append-writer copy file-str make-parents pwd read-lines reader slurp* spit to-byte-array with-in-reader with-out-append-writer with-out-writer write-lines writer)

8:45 qed: ,(doseq [s (sort (keys (ns-publics 'clojure.contrib.duck-streams)))] (print-doc s))

8:45 clojurebot: java.lang.NullPointerException

8:45 qed: ,(doseq [s (sort (keys (ns-publics 'clojure.contrib.duck-streams)))] print-doc s)

8:45 clojurebot: nil

8:45 qed: ,(doseq [s (sort (keys (ns-publics 'clojure.contrib.duck-streams)))] s)

8:45 clojurebot: nil

8:46 qed: ,(doseq [s (sort (keys (ns-publics 'clojure.contrib.duck-streams)))] (str s))

8:46 clojurebot: nil

8:47 qed: weird stuff -- i wonder why

8:48 ,(doseq [s (sort (keys (ns-publics 'clojure.contrib.str-utils)))] (str s))

8:48 clojurebot: java.lang.Exception: No namespace: clojure.contrib.str-utils found

8:48 qed: ,(doseq [s (sort (keys (ns-publics 'clojure.contrib.seq-utils)))] (str s))

8:48 clojurebot: nil

8:49 qed: ,(doseq [s (sort (keys (ns-publics 'clojure.contrib.seq-utils)))] (print-doc s))

8:49 clojurebot: java.lang.NullPointerException

8:49 qed: grr

8:51 hoeck1: qed: try (vals (ns-publics ..))

8:52 qed: print-doc wants a var, not a symbol

8:52 qed: why would it work on compojure, but not duck-streams?

8:53 chouser: ,(meta (first (keys (ns-publics 'clojure.contrib.duck-streams))))

8:53 clojurebot: nil

8:54 hoeck1: qed: maybe compojure adds some extra metadata somewhere?

8:54 cark: compojure has some magic

8:54 chouser: I think it's the lack of metadata that's the problem.

8:54 cark: it uses a macro to bring symbols from other name spaces

8:56 qed: that works great hoeck1 && chouser

8:56 thanks

8:56 clojure.contrib.duck-streams/*byte-array-type*

8:56 nil

8:56 that's probably why it blew up

9:14 tomoj: what is syntax-symbol-anchor for?

9:14 I can't get it to return anything but nil

9:15 oh, I see

9:15 ordnungswidrig: re

9:25 hello: oh dear. ejabberd's mod_irc is strange....

9:32 danishkirel: Hi. I have a recursive function. I want it to use a memoized version of itself for recursion. I know how to du it with vars (declare ...) but can I do this with a function created inside a letfn?

9:34 Here is the code. It's something like the Levenshtein distance: http://gist.github.com/254237

9:34 esj: (def x (momoize x)) ?

9:34 LauJensen: hehe

9:35 esj: s/momoize/memoize

9:35 LauJensen: thats a fun read :)

9:35 (filter even? (map inc (range 10

9:35 )

9:35 )

9:35 )

9:35 danishkirel: The memoization of measure works great but match won't use it's memoized version internally.

9:36 esj: yeah, i see you tried that *blush*.

9:36 chouser: danishkirel: that's a good question

9:36 danishkirel: And I just don't know how to accomplish that while still using letfn

9:37 tomoj: would using a binding instead of a let work?

9:37 chouser: bindings work on vars, not locals like let and letfn.

9:38 danishkirel: tomoj: That was my first thought but then clo...

9:38 Yeah. What chouser says.

9:38 Dynamic binding was my first thought.

9:38 clojurebot: :|

9:38 chouser: huh. really a good question.

9:39 I think a full-on letrec might do it, but we don't have that.

9:39 tomoj: well if you think it's a good question, that's my signal to give up and go back to doing what I was doing :)

9:40 danishkirel: Maybe it just isn't possible?

9:41 Well I already know how to get it done but that will break the beauty of my code :(

9:43 chouser: actually, even letrec wouldn't do it, I think.

9:44 scgilardi: I think mutation is necessary which locals can't do.

9:44 chouser: in order to use the existing memoize function, you need ... right, mutation.

9:44 you could have a memoizing macro that might do in this case.

9:45 scgilardi: you can use an atom. let it to (atom nil), define the function in terms of calling the value of the atom, then swap the memoized version into the macro.

9:45 s/macro/atom

9:46 chouser: ,(macroexpand-1 '(letfn [(foo [x y] foobody)]))

9:46 clojurebot: (letfn* [foo (clojure.core/fn foo [x y] foobody)])

9:46 scgilardi: how do I find out where we paste?

9:46 danishkirel: Then I'll simple (declare memoized) (defn unmemoused [] ... (memoized ...)) (def memoized (memoize unmemoized)

9:46 chouser: lisppaste8: url?

9:46 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

9:46 scgilardi: thanks

9:49 LauJensen: I haven't followed the discussion, but it looks like a case for transients ?

9:50 lisppaste8: scgilardi pasted "use memoize func with locals (atom)" at http://paste.lisp.org/display/91944

9:53 danishkirel: scgilardi: That looks interesting. Especially it looks like it will work.

9:53 scgilardi: chouser: thanks for updating my ticket with the commit id. I'll do that next time.

9:54 chouser: scgilardi: I don't think it's a big deal either way, but I happened to have the ticket open when I dug up the commit id, so I thought I might as well add it.

9:54 scgilardi: if you put "ref #<ticket>" in the commit comment, assembla will do it for you.

9:55 scgilardi: or you put "fixes #<ticket>" and it'll put a github link *and* close the ticket for you.

9:55 scgilardi: ok cool, thanks

9:55 even better

9:57 danishkirel: Awesome! sigilardi - You are my hero for the day!

9:57 Works great.

9:58 scgilardi: Excellent! Enjoy.

9:59 danishkirel: From 35 sec to 1 msec for my testcase :D

10:02 scgilardi: wow, cool. and (depending on the application) it can be really important that the cache used by the memoized function starts fresh with each call to the function that contains the let rather than being kept around forever.

10:18 cemerick: dysinger: what's the issue with using AOT'ed libs?

10:18 dysinger: makes it a PITA to try different branches of clojure

10:18 (new)

10:18 everything breaks

10:18 works fine if you don't AOT though

10:19 I had to rebuild our whole chain

10:19 with AOT off

10:19 cemerick: oh, OK, figured there was a real problem :-) That's just a side-effect of the churn when living on the edge

10:19 dysinger: so I could flip back and forth

10:19 heh

10:19 Well it is kind of a problem IMO

10:19 code that could work perfectly fine with a newer clojure doesn't

10:19 chouser: pprint is the main one that currently really requires AOT

10:20 dysinger: y

10:20 chouser: I never used to build contrib at all

10:20 cemerick: I don't think it's reasonable to say that AOT'ed libs should be portable across significant clojure revs. Maybe once core has really settled in, but not now.

10:21 dysinger: true

10:21 chouser: oh, goodness, no.

10:21 dysinger: The issue I am having is that if you are using a repository (and you should) like clojars or build.clojure.org or etc, that all those AOTed and uploaded jars break

10:22 chouser: binary compatibility of class files isn't a problem I'd want anyone spending much time on.

10:22 dysinger: Yeah - it's boring work

10:23 cemerick: stuff like this is why we continue to use an internal build, despite the strong pull from build.clojure.org. Maven can probably be coerced into locking into a particular snapshot, but I haven't touched that particular knob yet.

10:24 dysinger: cemerick: you can use the slim jar

10:24 that's what I am doing now for clojure (new) & contrib

10:24 chouser: cemerick: what would be the benefit of using build.clojure.org?

10:24 dysinger: snapshots

10:24 anytime github changes

10:24 cemerick: yeah, staying closer to the edge, not having to maintain our own repo, etc.

10:24 chouser: I just use a sha1

10:25 for my cmake build files. :-|

10:25 cemerick: dysinger: many, many moons ago, I discovered that using the slim jar is a no-go in certain environments, because of dynamic classloading buggaboos. I should revisit that, as I'll bet the situation has improved.

10:26 lisppaste8: cgrand-i'm-not-there annotated #91944 "old-school explicit self" at http://paste.lisp.org/display/91944#1

10:26 dysinger: hrm

10:26 ordnungswidrig: re

10:26 dysinger: cemerick: I'll watch out for that. All tests are passing with slim and (new) branch

10:27 chouser: heh. cgrand reading via bot and posting via paste.lisp.org.

10:27 cemerick: dysinger: AOT'ing everything is a habit I gained in the very early days that I might just need to get over.

10:28 I'd still insist on AOT for anything being shipped out though --- someone with a super-locked-down java security policy wouldn't be able to load any .clj files.

10:28 dysinger: I am not saying I have the answer - I just found that trying new branches of clojure breaks the entire build chain if that chain is AOTed

10:31 cemerick: actually, that whole issue should probably simply go away once c-in-c is a reality

10:31 hrm. Too many qualifiers in there. :-P

10:32 ordnungswidrig: is java.lang.string#split the idiomatic way to split

10:35 devlinsf: ordungswindrig: Check out str-utils2 in contrib

10:35 chouser: ordnungswidrig: I prefer Pattern split, or str-utils2

10:35 ,(.split #"/" "one/two/three")

10:35 clojurebot: #<String[] [Ljava.lang.String;@15e64c7>

10:35 chouser: ,(seq (.split #"/" "one/two/three"))

10:35 clojurebot: ("one" "two" "three")

10:36 ordnungswidrig: chouser: oh, I flipped the arguments to split, no wonder I get strange results

10:37 chouser: well, string has a split too, but it takes a string instead of a regex.

10:37 ordnungswidrig: chouser: now, String#split takes a regex

10:37 _fogus_: ,(re-seq #"\d" "1/2/3")

10:37 clojurebot: ("1" "2" "3")

10:37 _fogus_: Another approach from a different angle

10:38 ordnungswidrig: re-seq is on contrib?

10:39 chouser: clojure.core

10:41 ordnungswidrig: ,(re-seq #"\s" " 1 2 3")

10:41 clojurebot: (" " " " " " " " " ")

10:41 ordnungswidrig: huh?

10:41 chouser: re-seq is returning what matches, so a sort of inverse of split.

10:42 ordnungswidrig: chouser: i see

10:42 chouser: ,(re-seq #"\d+" " 1 2 345 6")

10:42 clojurebot: ("1" "2" "345" "6")

10:42 ordnungswidrig: ,(re-seq #"[^\s]+" " 1 2 3")

10:42 clojurebot: ("1" "2" "3")

10:47 drewr: ,(re-seq #"\S+" " 1 2 3")

10:47 clojurebot: ("1" "2" "3")

10:50 ohpauleez: what is reverse filter called again?

10:50 I want to filter a vector, but get all the items that fit a condition

10:51 chouser: remove

10:51 _fogus_: ohpauleez: some

10:51 ohpauleez: thanks guys

10:51 chouser: ohpauleez: actually, that sounds like you want 'filter'

10:51 _fogus_: ignore me

10:51 ohpauleez: let me hit the repl and double check

10:51 it might be that I did somethign wrong elsewhere

10:52 chouser: ,(filter odd? (range 7))

10:52 clojurebot: (1 3 5)

10:53 ohpauleez: yes, I just spotted the other bug I introduced

10:53 thanks chouser

10:55 rullie: ,(range 7)

10:55 clojurebot: (0 1 2 3 4 5 6)

11:17 ordnungswidrig: hmm, how do I join a lazyseq of strings to a string?

11:20 stuartsierra: ,(apply str '("a" "b" "c"))

11:20 clojurebot: "abc"

11:21 rhickey: everyone ok on latest new branch?

11:22 stuartsierra: Haven't had time to really look at it, sorry.

11:22 Stuck in C-land right now.

11:22 ordnungswidrig: stuartsierra: "clojure.lang.LazySeq@467bcfd"...

11:23 stuartsierra: ordnungswidrig: The lazy sequence has to be the last argument to apply.

11:23 ordnungswidrig: stuartsierra: yes, and I better actually type "apply" :-)

11:23 stuartsierra: and do not omit it

11:25 hoeck1: rhickey: yes, everything ok, one question, should it be allowed to overwrite the default implementation of ILookup in deftype?

11:26 rhickey: hoeck1: yes it should, because how else could you use deftype to implement PersistentHashMap?

11:26 ohpauleez: rhickey: I haven't had time to play with it, but I'm going to dig in over the weekend

11:27 is there any desire for setting up continuous integration

11:27 rhickey: ohpauleez: like: http://build.clojure.org/

11:27 ?

11:28 ohpauleez: I have two machines I'd be more than happy to put up (MBP Dual Core, Linux single core)

11:28 yeah like that, but across multiple machines and architectures

11:29 I'd be happy to set one up over the weekend and host it myself just for your own feedback

11:29 rhickey: ohpauleez: differences on platforms/architectures are very rare for Clojure itself

11:29 ohpauleez: because of the JVm

11:29 right, nvm :)

11:31 * hoeck1 forgot removing the leading dot of valAt while trying the new deftype

11:32 hoeck1: rhickey: now it works as expected, thanks

11:33 drewr: rhickey: do you feel like the syntax of defproto/deftype/extend-* has stabilized?

11:33 rhickey: hoeck1: of course, once you've done that you lose keyword-based field lookup. You can still get at the fields externally using the interface clojure.lang.IDynamicType for now

11:33 drewr: ues

11:33 yes

11:34 drewr: why, wanna write some tests? :)

11:34 tests for letfn and case also desired

11:35 drewr: rhickey: love to! first I want to build on it in something non-trivial :-)

11:36 leafw: would be nice also to see non-trivial examples of defprotocol, deftype and reify. IS there any project repository with some, somewherE?

11:38 hoeck1: rhickey: what about direct access to the deftypes fields using (.field mytype)?

11:38 drewr: hoeck1: how is that better than (:field mytype)?

11:39 rhickey: hoeck1: yes, that too, in code that knows the type by name

11:39 otherwise beware of reflection

11:40 drewr: we are talking about the case where a deftype takes control over ILookup itself, thus turning off (:field x)

11:41 * drewr scrolls up...

11:44 cemerick: <rant>So J2EE 6 removes the web.xml requirement (yay!) and offers as a replacement....annotations! *facepalm*</rant>

11:46 ordnungswidrig: cemerick: yeah! annotations is the new xml.

11:46 cp2: cemerick: next stop... annotation in xml format ^_^

11:51 devlinsf: cp2: No no no no... It'll just be a bunch of POJOs & EJB4!

11:51 cp2: hah

11:54 ordnungswidrig: pfft, (let [x (fn [bah] (form)] ...) or (let-fn ...) ?

11:55 doublindirection: is it possible to run some initialization code when a namespace is first loaded?

11:56 ordnungswidrig: ,{1 2 3}

11:56 clojurebot: java.lang.ArrayIndexOutOfBoundsException: 3

11:56 ordnungswidrig: Any chance that the error cause will be more precisely reported in future clojure?

11:57 drewr: doublindirection: you could do something like (defonce foo (do (init) (init-more)))

11:57 rullie: .{1 2 3 4}

11:57 ,{1 2 3 4}

11:57 clojurebot: {1 2, 3 4}

11:57 rullie: ordnungswidrig: a map needs even number of elements

11:58 the error is precise, it is getting the [3] of the array, which is the 4th element, or the value of the key 3

11:58 doublindirection: drewr, thats what i'm doing, i was thinking that maybe there is something "idiomatic"

11:58 ordnungswidrig: rullie: I now, but the error is misleading

11:58 arohner: if I use clojure.contrb.ns-utils/immigrate, that creates a second var, right?

11:58 a second var in the destination namespace

11:58 doublindirection: drewr, it works anyway

11:58 rullie: ordnungswidrig: i think the error makes sense :)

11:58 ordnungswidrig: rullie: I'd expected a OddNumberOfMapElementsException :-)

11:59 rullie: if the error is burried deep in your code than it's more complicate to see the cause

12:00 rullie: i suppose

12:02 arohner: ns-utils/immigrate looks like it's not a clean solution. I think it's causing screwyness with slime

12:04 is there a way to intern a var in two different namespaces?

12:04 replaca: hiredman: are you here?

12:05 hiredman: barely

12:06 * esj is reaching a fragile truce with paredit

12:06 stuartsierra: arhoner: no

12:06 replaca: hiredman: are you still using the JSON doc for clojure-contrib in clojurebot?

12:07 hiredman: yes

12:07 replaca: cool, ok, I was just curious :-)

12:07 hiredman: ahem

12:07 stuartsierra: arohner: immigrate is a bad idea

12:07 arohner: stuartsierra: yeah, I'm finding that out the hard way

12:07 hiredman: yes, and thankyousomuch

12:08 arohner: stuartsierra: is there a better approach?

12:08 stuartsierra: arohner: Yes. Don't try it. :)

12:10 arohner: well, my final goal is to have a namespace that contains the contents of two sub-namespaces. I don't really want to use load, because I don't like that the loaded file doesn't have a namespace declaration, so you don't know what is required, etc

12:10 stuartsierra: There's no such thing as a sub-namespace.

12:11 If you're used to languages with first-class modules like Python/Ruby, this may be difficult.

12:11 arohner: I want to end up with arohner.foo, that has the contents of arohner.foo.bar and arohner.foo.baz

12:11 stuartsierra: arohner: Can't be done in any reasonable way.

12:14 hoeck: stuartsierra: what about defalias, does it face the same problems as immigrate?

12:15 stuartsierra: What's defalias? Is that in contrib?

12:17 hoeck: stuartsierra: clojure.contrib.def/defalias

12:17 stuartsierra: Yes, it has the same problems, because it creates a new Var.

12:17 hoeck: basically expands to (def myname otherns/myname)

12:18 stuartsierra: That's not an alias, it's a NEW global Var initialized to the other Var's value.

12:18 Rebinding one will not affect the other. This is the problem with immigrate.

12:20 hoeck: stuartsierra: I see

12:20 stuartsierra: If you REALLY want to refer multiple namespaces with a single line, write a function that calls 'use' or 'refer' for each namespace.

12:20 arohner: that, and reloading the source namespace will not affect the target namespace, because you have two vars

12:20 stuartsierra: arohner: Exactly.

12:20 arohner: but use and refer aren't exported to other users of the namespace

12:21 stuartsierra: Correct. What you want -- to 'use' my-ns and automatically get my-ns.foo and my-ns.bar -- is simply not possible.

12:22 The closest you can get is to define my-ns/refer-others and call it after you 'use' my-ns.

12:22 arohner: I think there's room for improvement there. as a library implementor, I want to split the implementation into multiple files, and load is sub-optimal

12:23 stuartsierra: The problem is that namespaces mirror the structure of Java packages, which are not first-class objects.

12:24 arohner: how does that cause a problem?

12:24 stuartsierra: All Java packages exist in one flat, global namespace. There is no hierarchy.

12:25 arohner: for this to work, I don't need the namespaces to form a hierarchy, I just need to be able to stick one var in multiple namespaces

12:26 drewr: that sounds like a nightmare

12:26 arohner: though, that might cause problems

12:26 I don't understand the big picture yet

12:26 drewr: as a user, I would prefer the consolidation be explicit

12:27 stuartsierra: arohner: Look at it this way: The namespace is a property of the Var. A Var cannot, by definition, exist in more than one namespace.

12:28 arohner: so it is

12:35 fliebel: how can i do slices(like python) with clojure?

12:36 arohner: fliebel: you can use subvec, if you have a vector

12:37 what are you trying to do?

12:37 slices cover a lot of functionality in python

12:37 fliebel: well, just the start, stop

12:37 length

12:37 I'd like to retreive parts of a lazy seq

12:38 especially the third step is important for me...

12:39 drewr: you could use partition if you want to pull chunks at a time

12:39 arohner: or take

12:40 fliebel: (slice [:a :b :c :d] 0 −1 2) => [:a :c]

12:40 drewr: ,(get [:a :b :c :d] 2)

12:40 clojurebot: :c

12:41 fliebel: drewr: partition might work fine...

12:41 arohner: it's been a while since I've done python, but that's go from the end of the list to the beginning, taking every other item, right?

12:41 fliebel: arohner: how do you mean?

12:42 arohner: I was trying to remember how to interpret the python slicing

12:42 fliebel: arohner: this was probalby a wrong one...

12:42 hiredman: ,(take-nth 2 [:a :b :c :d])

12:42 clojurebot: (:a :c)

12:42 arohner: sorry, I have to run

12:42 fliebel: the syntax is start:length:interval

12:43 hiredman: ,(take-nth 2 (range 10))

12:43 clojurebot: (0 2 4 6 8)

12:43 hiredman: ,(take 2 (take-nth 2 (range 10)))

12:43 clojurebot: (0 2)

12:43 fliebel: hiredman: that is exactly what I need!

12:44 drewr: ah, take-nth

12:45 aluink: i'm looking for a good tutorial to working with Clojure...where can I find one? searching google for clojure is ... painful

12:45 chouser_: thicket: I know it's early to be asking but do you have any sense of a timeline for 1.2?

12:45 fliebel: aluink: I agree on the searching thing....

12:45 aluink: i've worked with Haskell so I'm not new to functional programming, and have worked a lot with Java so i'm not new there either

12:46 hiredman: ~blip.tv

12:46 clojurebot: blip.tv is http://clojure.blip.tv/

12:46 fliebel: aluink: I envy you…

12:46 chouser_: rhickey: that was for you. iPhone speli

12:46 aluink: fliebel: how so?

12:46 chouser_: spelling corrector fail

12:47 aluink: searching "clojure lisp java" on google was kinda productive

12:47 fliebel: aluink: I'm trying to learn clojure without any knowledge of functional programming and a little Java.

12:47 hiredman: ircPhone

12:48 aluink: unfortunately corporate policies here have blocked blip.tv, FAIL!

12:48 we won't discuss how i'm in an IRC channel ;)

12:48 chouser_: hiredman was that a tip or a pun? :)

12:49 hiredman: pun :(

12:49 esj: what is the inverse of (keyword x) ? I'm using (apply str (rest (str (keyword "index")))) which is just silly.

12:49 drewr: ,(name :foo)

12:49 clojurebot: "foo"

12:49 esj: drawr: thanks

12:49 drewr, even.

12:49 rullie: `(a b c)

12:50 ,`(a b c)

12:50 clojurebot: (sandbox/a sandbox/b sandbox/c)

12:50 replaca: Q: when I execute this line: `(defn ~name [] (snippet ~name (template-for ~template-file) [:body :> any-node] ~args ~@body))

12:50 somnium: esj: name

12:50 ,(name :x)

12:50 clojurebot: "x"

12:50 rullie: ,`(,gensym)

12:50 clojurebot: (clojure.core/gensym)

12:50 replaca: I get "can't use qualified name as parameter: net.cgrand.enlive-html/any-node"

12:50 rullie: ,`(+ 1 2)

12:51 clojurebot: (clojure.core/+ 1 2)

12:51 esj: somnium: thanks too :) Clojure is great for distilling long questions into short answers.

12:51 replaca: why can't I?

12:51 rullie: good stuff

12:51 chouser_: hygiene

12:51 replaca: (I understand the part about how ` namespace qualifies symbols, but I don't see why that would be a problem

12:51 fliebel: What the heck is the function name for scrambling/shuffling a sequence?

12:52 cemerick: seq-util/shuffle

12:52 hiredman: Collections/shuffle ?

12:52 replaca: chouser_: ? I don't understand the hygenic implication here? Isn't namespace qualification *good* for hygiene

12:52 fliebel: cemeric & hiredman: Is that in contrib?

12:52 aluink: fliebel: http://mitpress.mit.edu/sicp/ This is an EXCELLENT book on functional programming...it uses scheme ;)

12:52 chouser_: replaca: you need to gensym local names to avoid unintended capture

12:53 hiredman: Collections/shuffle is part of the java Collections api

12:53 aluink: fliebel: it's up there with K&R :)

12:53 fliebel: aluink: thanks, but I'm not learning scheme ;)

12:53 replaca: chouser_: but it's not a local name! it's a func in enlive

12:54 so that's what I want, isn't it?

12:54 chouser_: hm would seem so

12:54 cp2: is there a way to pass arguments to javac in a leiningen project file? ex -Djava.library.path=foo

12:54 chouser_: you're sure that fn is refered in like with use?

12:54 replaca: chouser_: that's why I'm confused :-)

12:56 the macro's used in the same ns as where it's defined. It seems like if it can do the ns qualification in ` it must be able to find the var

12:56 chouser_: actually it seems more likely you're misusing enlive somehow

12:57 i don't know how snippet works

12:57 if that macro is not defined in enlive it must be finding the anynode fn ok

12:58 drewr: cp2: I believe JAVA_OPTS support has just been added

12:58 chouser_: but then trying to use it as a formal arg or something?

12:58 drewr: cp2: might want to ask in #leiningen

12:58 cp2: drewr: aye, thanks

13:00 replaca: Aha! snippet is a macro itself! I thought it was a function and that that was simply a vector arg, not an arg list. Now it makes complete sense. Thanks, chouser_!

13:02 aluink: fliebel: this book uses scheme as it's vehicle, but the book is not a tutorial/guide whatever you wanna call it on scheme

13:02 fliebel: this book is about functional programming concepts

13:03 fliebel: it could have just as easily been written using clojure as it's language of choice...they chose scheme..prolly cause clojure wasn't around when it was written ;)

13:03 esj: fliebel: a support aluink whole heartedly, you should read this first. I'm working through it at the moment, great stuff.

13:05 aluink: fliebel: this book no doubt has the obvious side-effect of teaching scheme

13:18 lghtng: good morning

13:30 _fogus_: ,(sorted-set :a 1 :b :c :d)

13:30 clojurebot: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.Number

13:30 _fogus_: Is this intended?

13:31 I assume that if you're building a sorted-set then Clojure assumes that all items are mutually comparable

13:33 Ahh, now I see sorted-set-by

13:34 mabes: what is the recommended/idomatic way of serializing clojure data to a file and reading it back in? I've seen pr-str and read-string but having an ASCII representation seems wasteful

13:35 drewr: but it's homoiconic

13:35 mabes: drewr: what that comment for me?

13:36 drewr: mabes: yes

13:36 you benefit by writing in the same format the reader can read

13:36 I usually compress though to save bandwidth/disk space

13:37 mabes: drewr: ah, I see. Ok, I guess I can see that.

13:44 Licenser: aloah

13:55 Drakeson: how can I find the maximum number of arguments for a function?

13:55 jasapp: Drakeson: what do you mean?

13:55 Drakeson: do I have to parse (:arglists (meta f)) looking for `&' or there is an easier way?

13:56 (reduce max (map count (:arglists (meta f)))) is a naive way that does not account for `&'s

13:56 dakrone: Drakeson: might be some stuff here: http://stackoverflow.com/questions/1696693/clojure-how-to-find-out-the-arity-of-function-at-runtime

13:59 alexyk: anybody using IDEA's La Clojure plugin?

13:59 Drakeson: dakrone: thanks

14:26 alexyk: technomancy: would it make sense to optionally add rlwrap to lein repl launch line?

14:28 the-kenny: alexyk: Isn't jreadline integrated in the last commit

14:28 alexyk: the-kenny: I hate readline, you can't search with C-r backwards in it

14:28 I always end up trying to disable jline from JVM repls to call under rlwrap

14:29 I mean I hate jline and love readline

14:29 {:jline hate, :readline love}

14:29 the-kenny: unknown symbol "hate"

14:29 ;)

14:29 hiredman: jline also has unicode issues

14:30 lghtng: one man's meta...

14:30 technomancy: jline is definitely not as good as readline, but it's impossible to make rlwrap a dependency of leiningen, while jline can be defined as a dependency and included in the standalone jar.

14:30 alexyk: this is the most bizarre thing of all: with all the REPLs now in JVM, stupid, broken jline for all.

14:30 Not a single GNU-readline compatible thing, with search through history.

14:31 opqdonut: rlwrap

14:31 hiredman: alexyk: I think headius had a fork of jline at one time that fixed some issues

14:32 headius: and somehow I ended up admin for jline proper

14:32 alexyk: technomancy: right. I now call repl as: rlwrap lein repl, and am sticking rlwrap into the lein as: rlwrap java ... -- but that's just me.

14:32 headius: though I really haven't had time to admin it

14:32 hiredman: http://blog.headius.com/2009/05/jruby-nailgun-support-in-130.html?showComment=1242249900000#c4023221249455202623

14:32 alexyk: technomancy: if you add jline, please also add a standard way to disable it!

14:33 technomancy: alexyk: patches welcome. I don't use either of them myself.

14:34 hiredman: maybe I should take another look at jline

14:35 alexyk: technomancy: sure, I'll send you some charred sh-shards :)

14:35 hiredman: (if headius is calling the shots)

14:35 alexyk: hiredman: that post is about nailgun, not jline?

14:36 ah, comments

14:36 hiredman: alexyk: the url is for a comment

14:37 alexyk: is there a same thing for clojure to run with a nailgun, btw?

14:37 I know one in maven plugin mentions clojure:nailgun

14:38 hiredman: you just install nailgun and ng clojure.main

14:38 alexyk: hiredman: say I have a clojure script, will the above run it in a pre-existing JVM?

14:38 hiredman: yep

14:39 alexyk: so, ng clojure.main myscript.clj?

14:39 or #!...ng clojure.main ; on top of script?

14:41 hiredman: never tried to use ng in a shebang line

14:50 arohner: I'm using a macro to generate a defn. Is there a way to write the macro so I get "pretty" function names as opposed to gensyms? I tried using ~' on the fn arguments, but clojure wasn't happy with that

14:50 sorry, not function names, function arguments

14:51 the-kenny: arohner: I don't really get the problem.. cann you show me an example?

14:52 arohner: `(defn foo [x#] (println "hello world"))

14:52 hiredman: :|

14:52 arohner: the docstring for foo will show that it takes [x_1123q4]

14:52 as opposed to just x

14:52 hiredman: you can always reach in and tweak the docstring

14:53 ,(doc alter-meta!)

14:53 clojurebot: "([iref f & args]); Atomically sets the metadata for a namespace/var/ref/agent/atom to be: (apply f its-current-meta args) f must be free of side-effects"

14:53 arohner: yeah, I guess that will work

14:53 the-kenny: arohner: hm... If variable-capture isn't a problem, why use gensyms at all?

14:54 arohner: because the compiler doesn't appear to be happy with a non-gensym as an argument to the fn. I get: Can't use qualified name as parameter: my-ns/x

14:54 oh, nm

14:54 I should be using ', not ~'

14:54 the-kenny: arohner: Heh, I had this problem after using common lisp a long time too

14:55 stuartsierra: arohner: 'intern' is often a better way to create functions

15:01 tolstoy: Is it possible to implement an "abstract method" using (proxy ... )?

15:02 stuartsierra: tolstoy: yes, shouldn't be a problem

15:02 tolstoy: stuartsierra: Okay, thanks. I must have some other issue, then. Phew! :)

15:03 * the-kenny had to use wall-hack-method for the first time a few days ago :(

15:03 the-kenny: I felt bad

15:04 tolstoy: Hm. I still get AbstractMethodError.

15:05 I wonder if you have to type hint?

15:05 Maybe it's the "protected" thing.

15:06 Or void.

15:06 hiredman: the-kenny: even with a name like that?

15:07 the-kenny: hiredman: "wall-hack-method"?

15:07 hiredman: yes

15:07 the-kenny: It sounds so.. nasty

15:07 hiredman: http://github.com/richhickey/clojure-contrib/commit/cc4e2ec2bf558f059330ebc97a031d7806a1e364

15:08 the-kenny: hiredman: No offense against you ;) I just don't like the idea of "breaking walls" just to call a protected method in a proxy.

15:08 ...but if that's the only way

15:09 tolstoy: the-kenny: Can the superclass of the class your proxying call a protect method you've implemented in the proxy?

15:10 hiredman: the-kenny: I am not offended, just tickled pink to have (5 or 6 lines of) code in contrib

15:10 the-kenny: tolstoy: I don't know.

15:11 tolstoy: the-kenny: Ah, I was thinking that's what you were talking about.

15:11 the-kenny: tolstoy: No, I talked about calling a protected method from a proxy, not implement it.

15:11 tolstoy: Yeah, that's what I thought, but I was hoping.... ;)

15:35 leafw: hum, any body knows how to get the type for a double[]?

15:35 chouser: "get the type"?

15:35 leafw: for example, a double is Double/TYPE, but what is a double[] ?

15:36 chouser: (class (double-array []))

15:36 ,(class (double-array []))

15:36 clojurebot: [D

15:36 chouser: there ya go. ain't it beautiful?

15:36 defn: hehe

15:36 leafw: chouser: yes, sure ... but I'm stuck in java land. I guess I can call RT.invoke, but there must be an internal way

15:36 chouser: for type hints you should be able to use #^doubles

15:37 ,(Class/forName "[D")

15:37 clojurebot: [D

15:37 leafw: (. Class (forName "[D"))

15:37 yeah. works

15:37 weird

15:38 chouser: ,(Class/forName "[X")

15:38 clojurebot: java.lang.ClassNotFoundException: [X

15:38 rhickey: double[].class

15:38 stuartsierra: "[D" is Java bytecode syntax.

15:38 * hiredman was just going to say that

15:38 chouser: I could be the measure of how little one can know about Java and still use Clojure.

15:38 leafw: double[].class ... trying that

15:39 * the-kenny has learned to use the classpath correctly because of clojure

15:39 * hiredman has been playing with clojure.asm.* all week

15:39 stuartsierra: The ASM library is kind of fun. I toyed with the idea of writing a Forth-like interpreter with it.

15:39 rhickey: hiredman: speaking of which, one short term objective (1.2?) I have is to pull ASM out of clojure's jar

15:39 hiredman: :(

15:39 stuartsierra: Why?

15:40 hiredman: taking away my shiny new toy

15:40 rhickey: Will still come with Clojure, but as an external dep

15:40 cp2: hiredman: asm in clojure is not the full library anyway =P

15:40 rhickey: so we can move to later version, avoid duplication when combined with code also using ASM

15:40 stuartsierra: ah, that's fine

15:40 hiredman: cp2: I got my classloader working

15:40 cp2: good

15:40 stuartsierra: good, in fact

15:40 rhickey: have access to parts of ASM I left out for size reasons

15:40 chouser: only needed for compiling, not for running AOT-compiled things, right?

15:41 rhickey: including those that would let you get ASM output during Clojure compilation

15:41 hiredman: now I just want to have the code generate a jar file when run

15:41 rhickey: chouser: right, although pulling out all references not in compiling code is another project

15:42 hiredman: so you can put classloader.jar on your classpath, and add -Djava.system.class.loader=foo.classloader to your java options

15:42 chouser: ok,I can see that.

15:49 rhickey: So, I'd like some input on how best to handle that (separate ASM) from the perspective of git, Ant, Maven et al

15:49 hiredman: :|

15:52 piccolino: I notice that Servlet 3.0 seems to require the use of annotations to enable the asynchronous processing stuff... how would one use that from Clojure? Is it possible?

15:59 defn: good god the splits today

16:00 dakrone: hey defn, what's up with your git commits?

16:01 defn: ?

16:01 dakrone: they're all hostnames and timestamps

16:01 no actual commit messages?

16:01 defn: yeah i just wrote a little script to push it because i mess with it at work and at home

16:01 dakrone: ahh

16:01 defn: and want it to be consistent at both places, but i realize that's probably annoying

16:02 ill change the script to force me to add a message :)

16:02 dakrone: it's really hard to tell what's changed, have to look at the diff each time

16:02 defn: yeah sorry about that

16:02 dakrone: p.s. please add an RSS feed to your blog

16:02 defn: haha, feature requests aplenty! :)

16:02 ohpauleez: defn: where's your blog?

16:02 defn: http://devinwalters.com

16:02 ohpauleez: thanks

16:04 defn: dakrone: as far as what's changed, not a whole lot yet, it took me awhile (not knowing much java) to get the hang of building the jar and such

16:04 ohpauleez: defn: Awesome, I actually did an optimization of your Problem 14 a little while back

16:04 defn: oo! I'd love to see it

16:05 that code takes about 30seconds :\

16:05 ohpauleez: let me dig it up for you

16:07 defn: if you make the second line of count-and-track: (let [cnt (int n)

16:07 you'll notice an improvement

16:07 I also prime the JVM before I do the large set

16:07 jasapp: prime the JVM?

16:08 ohpauleez: give the same calls you want to make a few times, so the JIT will kick in when you're running a larger set

16:08 jasapp: Ahh, ok

16:11 defn: ohpauleez: yeah that makes big difference in some cases

16:11 i've seen (time ...) after priming the JVM go from 3.5s to 1.8s

16:12 im not sure if that is a huge deal once the JVM is up and running, in other words, we're not getting 3.5s for every 1.8s in an un-primed JVM

16:12 but it's still nearly 2s

16:13 ohpauleez: for sure

16:13 defn: ohpauleez: @ your (int n) stuff, that's a great idea -- i haven't looked at this code since i finished reading the optimization section in Programming Clojure

16:14 polypus: anyone had any luck installing compojure via lein?

16:14 defn: sure

16:14 err, you mean with clojars?

16:14 chouser: defn: my solution to problem 12 is startlingly similar to yours.

16:15 polypus: yeah

16:15 defn: i believe i got that divs fn from hiredman

16:15 ohpauleez: after the comment about Rosetta Code, when I get stuck on current projects, I'm going to start to try to fill some of that in

16:16 chouser: our divs are identical except for the name (mine is "divisors") and spacing. otherwise the forms are =

16:17 hiredman: think I got mine from reading a wikipedia article on something or other

16:17 defn: chouser: heh, im not sure how else you'd approach that problem

16:17 the brunt of it is, triangles as a lazy-seq, a good divs fn, a filter

16:17 liebke: polypus: are you seeing a Maven missing artifact error for org.clojure:clojure-lang:jar:1.1.0-alpha-SNAPSHOT?

16:18 polypus: yeah

16:18 chouser: defn: you could use :let for c in problem 9

16:18 liebke: clojure-alpha was renamed clojure-master, and this broke most of the projects on Clojars

16:19 polypus: ahh, when did that happen?

16:19 defn: chouser: nice, thanks!

16:19 liebke: yesterday or so

16:19 chouser: polypus: a couple days ago. I did it because I was asked to.

16:20 polypus: chouser: do you always follow orders w/o regard for the consequences :)

16:20 chouser: yes

16:20 defn: i havent had trouble with building compojure with lein via clojars

16:20 chouser: wait, no!

16:20 polypus: I dunno, what would you like me to say??

16:21 liebke: chouser: I think the new naming scheme is good, but can the old name hang around for a while

16:21 polypus: chouser: i dunno let me consult my superiors

16:21 chouser: polypus: :-)

16:21 defn: polypus: :D

16:21 hiredman: polypus: yes

16:22 defn: polypus: you're getting the problem with lein deps?

16:22 chouser: liebke: this is all beyond me. All I think I have the authority to do is back out the change, and I haven't gotten the impression that's what people want.

16:23 liebke: chouser: I agree, it shouldn't be backed out. I just wish there was a way to have clojure-alpha point to clojure-master.

16:23 arohner: symlink on the server?

16:24 defn: polypus: just for fun i created a new lein project and added [org.clojars.ato/compojure "0.3.1"] to my project.clj, lein deps, lein compile, lein uberjar, no errors

16:25 polypus: I think technomancy may have pushed out a new vers. of lein last night which may have fixed the issue you're having

16:25 hiredman: does lein do any caching?

16:25 liebke: defn: do you have clojure-alph in your .m2/repository?

16:26 defn: i dont

16:26 liebke: hmm

16:26 polypus: defn: you just did that and i worked?

16:26 s/i/it

16:27 defn: yeah, but maybe its because i have it downloaded already

16:27 in my .m2

16:27 polypus: yeah probs

16:27 defn: i can send you it! :)

16:27 polypus: maybe i can just change the name in my .m2

16:45 * the-kenny needs a function like nonlazy-map

16:46 chouser: (doall (map ...))

16:46 or (vec (map ...))

16:47 ordnungswidrig: cu all!

16:47 the-kenny: chouser: I know, I know. But I think it would be good in core. I had too much bad problems with lazyness

16:47 chouser: the-kenny: :-( really? like what?

16:47 alexyk: liebke: did you take down incanter off clojars?

16:48 search for incanter only finds dependencies

16:48 the-kenny: chouser: Some io- and storing-related things

16:48 alexyk: chouser: let me guess: being fired?

16:48 :)

16:48 the-kenny: (Weird exceptions when something lazy was stored for 5mins in a agent-wrapped list)

16:48 chouser: heh

16:49 the-kenny: hm... it's hard to know how to mitigate that without making everything non-lazy by default, which seems like an awefully big hammer.

17:01 alexyk: these freenode explosions are getting old

17:01 the-kenny: ..very annoying

17:01 arohner: why does IRC still do this? Haven't they had decades to sort this out?

17:01 the-kenny: arohner: It's a problem of the architecture..

17:01 alexyk: liebke: depending on 1.0-SNAPSHOT works, downloads incanter-1.0-20091121.091400-1.jar

17:01 the-kenny: ...but it shouldn't be hard to modify a server to serve the missed messages to the respective people

17:01 alexyk: arohner: RMS gets bored and flips the switch

17:02 hiredman: could move to a xmpp muc

17:02 the-kenny: hiredman: Yeah.. but I think Adium isn't suited for so much users

17:02 * the-kenny needs a xmpp-client like irssi or weechat :)

17:02 hiredman: as it happens, clojurebot hangs out it a muc (when the xmpp stuff is working)

17:02 http://cybione.org/~irssi-xmpp/

17:02 mmullins: Is it possible to use "&" variable arity with defprotocol?

17:02 I've been trying but keep getting errors.

17:02 the-kenny: hiredman: I switched to weechat some weeks ago. I like it way more than irssi

17:02 liebke: alexyk: good

17:02 the-kenny: clojurebot: xmpp

17:02 clojurebot: I don't understand.

17:02 alexyk: ,relax-and-enjoy

17:02 clojurebot: java.lang.Exception: Unable to resolve symbol: relax-and-enjoy in this context

17:02 the-kenny: hiredman: Where does clojurebot hand out?

17:02 polypus: http://metajack.im/2009/01/07/emacs-and-jabber-happy-together/

17:02 * hiredman tries to remember

17:02 alexyk: teXnomancy: here's a simple idea to enable rlwrap in lein: $RLWRAP java ...

17:02 you define RLWRAP in your shell if you want it

17:02 polypus: oops i forget not everybody's on emacs

17:02 hiredman: clojure@conference.thelastcitadel.com

17:02 * the-kenny never used xmpp muc much

17:03 hiredman: me neither

17:03 chouser: mmullins: I think varargs for protocols is not yet supported.

17:03 hiredman: I'm getting a sneaky suspiscion my xmpp server might not be working

17:03 mmullins: chouser: ok, thanks

17:04 the-kenny: Oh, looks like weechat has a xmpp-plugin, I just haven't compiled it

17:05 hiredman: huh, this says clojurebot is online

17:05 tomoj: so I'm trying to set lein up finally. seems to be working ok, I think, but lein-swank won't. I added [leiningen/lein-swank "1.0.0"] to my :dev-dependencies, but then running 'lein deps' causes an error: https://gist.github.com/55a7a1d61e98c909a7e0

17:05 the-kenny: hiredman: I just joined the muc and you and clojurebot are there

17:07 hiredman: yep

17:07 polypus: tomoj: lein is pretty screwed up right now cuz most clojars are broken

17:07 tomoj: oh, I see

17:09 polypus: maybe wait a few days till things clear up and save yourself some headaches

17:09 tomoj: thanks

17:09 polypus: np

17:10 alexyk: is there a maven naming scheme for jars compiled under clojure "new" branch vs regular?

17:16 should I depend on clojure-1.1.0-alpha or 1.1.0-master form maven?

17:17 are they the same?

17:17 tomoj: earlier today leiningen switched to -master

17:17 dunno why though

17:18 alexyk: yeah, and alpha has no jar

17:18 in my repo

17:19 so we really need a naming convention for branches. Scala does this: -language-branch is tacked after artifactId, this leaves version the same across language branches.

17:19 so x/y-v would be x/y-new/v for a non-master branch

17:21 hiredman: have you checked the google group?

17:22 alexyk: hiredman: not for this yet

17:22 hiredman: I am pretty sure this has all been discussed and more or less acted upon

17:22 alexyk: hiredman: what's the summary? :)

17:22 hiredman: alexyk: nothing I cared enough about to rememeber

17:23 alexyk: a good summary :)

17:31 how do you do iteration count to doseq?

17:31 I want to print progress every N iterations

17:32 tomoj: seq-utils has indexed

17:33 alexyk: thx

17:34 tomoj: ,(doseq [[i e] (map vector (iterate inc 0) '[foo bar baz])] (println i e))

17:34 clojurebot: 0 foo 1 bar 2 baz

17:34 tolstoy: Do messages take a while to show up on google groups?

17:35 chouser: tolstoy: they can.

17:35 tolstoy: Ah, I'm a "new" member. I see.

17:35 alexyk: tomoj: nice

17:37 tomoj: looks like indexed really is just (map vector (iterate inc 0) s)

17:37 alexyk: save me some pusszling over (require '...) :)

17:38 defn: anyone here a groovy fan?

17:38 i dont know much about it, was wondering what the consensus was

17:40 hiredman: clojureql has gone gradle

17:40 lisppaste8: Tolstoy pasted "Abstract Method Error" at http://paste.lisp.org/display/91963

17:41 tolstoy: defn: I use Groovy quite a lot. It's nice enough.

17:41 defn: tolstoy: what's the draw for you over Ruby?

17:42 tolstoy: I work in a Java shop and MUST use something that can make use of the giant wads of cruft lying around.

17:42 hiredman: tolstoy: I think he meant jruby

17:42 defn: ty

17:42 tolstoy: Oh.

17:42 defn: Groovy looks more java-ish

17:42 tolstoy: Sorry, never tried Jruby.

17:42 defn: probably makes more sense to use something more familiar

17:42 tolstoy: Yes, it gets you better buy-in from nervous managers.

17:43 defn: haha, oh god, please don't get me started on that

17:43 hiredman: tolstoy: might be an issue with protected

17:43 defn: that's the only reason i got them to let me try out clojure on a project at work

17:43 "JVM" -- Just like Java... *cough cough*

17:43 tolstoy: hiredman: I tried making the method public, no go. Same error.

17:44 defn: Yeah. I've tried so hard to make a "installable running process" be the medium of exchange. Linux as appserver. But no go.

17:45 defn: For them, it's imagining they can replace devs. Of course, our code is so spaghetti due to Java itself that each project might as well be a brand new language.

17:45 defn: haha, exactly

17:45 hiredman: the addStuff method isn't being called for some reason

17:46 defn: it's like ... i understand why you think this is a good decision, but umm, you know that John doesn't use a testing harness, right? You know that Ted doesn't indent his code properly right? You know that Bob doesn't write comments as a rule, right?

17:46 tolstoy: you know we re-invented half of J2EE less the documentation, right?

17:46 hiredman: tolstoy: what if initStuff is public?

17:47 tolstoy: hiredman: I'll try that.

17:47 defn: haha tolstoy

17:47 "It's Java, but...not Java at all. Think: Java, without Java. It's brilliant, and maintainable!"

17:47 tolstoy: hiredman: Same problem.

17:47 hiredman: hmmm

17:48 Oh!

17:48 Oh!

17:48 $5

17:48 it's because you don't have the class in a package

17:48 tolstoy: defn: Yeah. Any Java app is a bug-ridden, half-implementation of J2ee.

17:48 hiredman: Which class. Foo? This is just an example. The real one DOES have a package and I get the same error.

17:49 defn: You know, after watching Rich's "Are We There Yet?" presentation, I was thinking a bit about things that are annoying about programming in this day in age

17:49 hiredman: bah!

17:49 wtetzner|laptop: how do i get the version of clojure that has new features, like deftype and reify?

17:49 tolstoy: hiredman: Yeah, this is a puzzler!

17:49 defn: and one of the biggest pain points for me is always the GUI stuff for multiple platforms -- someone needs to solve that problem for God's sake

17:49 tolstoy: defn: They did. It's called The Web.

17:49 defn: bah!

17:50 heresy

17:50 tolstoy: heh heh

17:50 emacs?

17:50 defn: emacs is close I guess, but well -- let's be honest

17:50 it ain't for everyone

17:50 tolstoy: hiredman: I wonder if it's the fact that Clojure is running as a script?

17:51 hiredman: tolstoy: nope

17:51 teXnomancy: coding UIs in Emacs is so much less painful than any other system I've tried; HTML/CSS included

17:51 tolstoy: hiredman: Using java -server -cp $CLOJURE clojure.lang.Script $scriptname -- $*

17:51 hiredman: clojure is always compiled regardless

17:51 tolstoy: hiredman: Well, that's what I woulda thought.

17:51 hiredman: Okay, I'll try adding a package to Foo and see how it goes.

17:52 hiredman: and use clojure.main

17:53 clojure.lang.Script is deprecated

17:55 alexyk: tomoj: so in (map vector (iterate inc 0) '(1 2 3)) how does map finds out what's fn and what's seq?

17:56 i.e. what does vector do here?

17:56 tolstoy: Exception in thread "main" java.lang.AbstractMethodError: app.Foo.addStuff(Ljava/util/Map;)V (foo-bar.clj:0)

17:56 tomoj: ,(vector 1 2)

17:56 clojurebot: [1 2]

17:56 tolstoy: hiredman: I'll try clojure.main

17:57 defn: teXnomancy: Does the teX mean you're doing maths? :)

17:57 tomoj: you've got two seqs, (iterate inc 0) and '(1 2 3), map goes over them in parallel and passes an element of each to vector

17:57 alexyk: right but why don't we have parens around (vector ...)? or does map only create vector from iterate seq, and then doseq consumes two sequences into one [i e] each time?

17:57 ah, so map goes over both

17:57 tolstoy: hiredman: Same deal.

17:57 tomoj: ,(map vector (iterate inc 0) '(foo bar baz))

17:57 clojurebot: ([0 foo] [1 bar] [2 baz])

17:58 alexyk: nice

17:58 hiredman: :(

17:58 tomoj: doseq destructures

18:01 tolstoy: hiredman: I have the contructor call a regular method, which I've overridden in the clojure proxy, and it works just as I'd hoped.

18:01 alexyk: tomoj: so if map has more than one seq, the fn must have arity to accomodate all?

18:02 tolstoy: hiredman: So, yeah, something weird about implementing an abstract classes' abstract method.

18:04 tomoj: alexyk: yup

18:18 qed: hm, i cant get this shell-out stuff to work

18:18 (sh (format "/usr/local/bin/markdown %s -f %s -x codehilite" md-file write-to))

18:19 Cannot run program ...

18:19 error=2, No such file or directory

18:20 hiredman: ,(doc sh)

18:20 clojurebot: "clojure.contrib.shell-out/sh;[[& args]]; Passes the given strings to Runtime.exec() to launch a sub-process. Options are :in may be given followed by a String specifying text to be fed to the sub-process's stdin. :out option may be given followed by :bytes or a String. If a String is given, it will be used as a character encoding name (for example \"UTF-8\" or \"ISO-8859-1\") to convert the sub-process's stdout to a Stri

18:22 qed: hiredman: im not sure what im missing there

18:24 hiredman: qed: have you looked at the arguments exec() takes?

18:24 alexyk: teXnomancy: so are you planning to let folks specify JAVA_OPTS in project.clj?

18:24 qed: hiredman: no, what's exec?

18:25 exec()

18:25 hiredman: did you read the docstring for sh?

18:25 I mention exec() in the context of the docstring

18:26 if you read the docstring (which you should do) the exec() I mean in that context should be very apparent

18:26 qed: yeah i see it, im just terrible at understanding the java docs, its slowly coming

18:26 teXnomancy: alexyk: I think that would mean you'd have to fork to run tests/compile/do anything. depends on how bad of a speed hit that requires I guess.

18:27 hiredman: qed: basically by handing a single string to sh you are getting http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#exec%28java.lang.String%29

18:27 alexyk: teXnomancy: my current approach is to actually store ./lein next to project.clj to add things anyways

18:28 I'm just thinking there will be situations where you want to use say compressed references or some other JVM flags per project, and storing them in project.clj seems right

18:29 then shell will have to easily grep them out and feed to java command line

18:29 teXnomancy: alexyk: alternate approach would be to source a my-project/.leinrc from the bin script. haven't given it much thought as I don't need it myself. why don't you bring it up on the mailing list and see what other users think?

18:29 hiredman: qed: what you want is http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#exec%28java.lang.String[]%29

18:29 alexyk: teXnomancy: is there a list for lein, or you mean clojure google group?

18:30 teXnomancy: alexyk: there's http://groups.google.com/group/leiningen

18:30 you seem to have a lot of ideas; you should join. =)

18:31 alexyk: cool, will post there then

18:31 hiredman: I don't mean to offer criticism without offering a solution, but sheel-out/sh seems like brittle junk, I would just use .exec directly

18:31 qed: hiredman: im still not sure how to say "-f xyz"

18:32 (sh "cmd" arg1 arg2) works, just not sure how to say arg1 is "-f arg1"

18:32 hiredman: qed: things that would be sperated by spaces on the commandline need to be in seperate array elements

18:32 so for sh it would be something like (sh "cmd" "-flag" "arg1" "arg2")

18:32 qed: hiredman: awesome thank you

18:33 but good point on calling exec directly

18:34 hiredman: qed: have you tried looking for java markdown processors?

18:34 qed: i havent

18:34 i found this particular markdown processor to be nice because it had a pygments extension already

18:34 which was something that was important

18:38 i own that nick :)

18:40 teXnomancy: qed: you're te? aha.

18:40 * teXnomancy was trying to do /nick teχnomancy, but it didn't work

18:40 qed: haha, no UTF-8 for you!

18:40 i got all wrapped up in eastern philosophy for awhile, plus im a sucker for short nicks

18:52 skybound: i am trying to understand type hints, or more precisely when the type is inferred from the return value of a fn; see http://pastebin.com/d6ffaca44 ; the way i understand the docs the reflection warning shouldn't happen in the second test? am i doing this wrong?

19:01 hiredman: ~performance

19:01 clojurebot: http://clojure.org/java_interop#toc46

19:01 hiredman: fns always have Objects in and out

19:02 the-kenny: Is there a slime command to eval all open clojure-buffers?

19:02 (Like doing C-c C-k on every of them)

19:03 _ato: hiredman: right but he's returning a Set which is an Object

19:03 hiredman: _ato: and calling .contains on it

19:03 which can only be done via reflection

19:03 _ato: skybound: I guess it's not clever enough to propagate the type hint from the returned variable to the function

19:04 that should be doable I'd imagine, so I guess maybe it's just something that got overlooked

19:04 s/variable/local/

19:04 hiredman: _ato: that is not that easy

19:05 _ato: yeah, the function could have multiple exit points

19:05 hiredman: for this specific case, s is a mutable object

19:05 _ato: doable, but perhaps the complexity would be too high for the benefit

19:05 hiredman: so the same object is passed through

19:06 _ato: (defn test-add-set2 [#^Set s] (dotimes [i 1e5] (. s add i)) s)

19:06 hiredman: if you used a PersistentSet

19:06 and something like conj

19:06 or what have you

19:07 _ato: it could propagate the #^Set type hint from s to the function's return value

19:07 hiredman: it could return anything

19:07 _ato: yeah

19:07 probably in general Clojure code it helps less so Rich didn't bother with it

19:08 skybound: i can accept that it doesn't work for the general case, but the java_interop docs claim "...the compiler will track the use of any return values and infer types for their use..."; in what cases would type inference work for return vals?

19:09 _ato: skybound: I think it might be talking about return types of java functions

19:09 hiredman: java methods

19:09 java doesn't have functions (yet)

19:10 _ato: nitpicker :p

19:10 eg. (let [x (.length "foo")] ...)

19:12 hiredman: _ato: keeping a clear dinstiction between java and clojure semantics is a good thing

19:12 if you do, you don't do stuff like (map .toUpperCase ["f" "b" "c"])

19:14 * the-kenny always uses str-utils2's methods

19:14 hiredman: functions

19:14 the-kenny: of course, sorry

19:14 _ato: haha

19:14 I'm not the only one :p

19:14 the-kenny: _ato: Yes ;)

19:15 I get it right in my native language, but I use the wrong name in English every time.

19:15 skybound: _ato: that makes sense, given that it is mentioned in the interop docs. thanks

19:16 tolstoy: Can you use :gen-class even if you're just running a script?

19:16 _ato: I have the distinction clear in my head of course, I just always seem to use the words function, method and procedure interchangeably.

19:16 hiredman: http://en.wikipedia.org/wiki/Confucianism#Rectification_of_names

19:16 tolstoy: nope

19:17 if you are running the new branch you can do things like reify or deftype, which have some overlap with gen-class, but not all of it

19:17 tolstoy: hiredman: I think that means I'm totally screwed using this class which calls an abstract method I'm supposed to implement in my proxy. Sadness!

19:18 _ato: tolstoy: I sometimes do: (compile 'something) (import 'something) in a script, where 'something' is a gen-classed file

19:18 you'll need to set -Dclojure.compile.path=/somewhere/writable and put that directory on the classpath

19:19 skybound: there is gen-and-load-class at the bottom of genclass.clj, though it is commented out. maybe something like that would still work

19:19 hiredman: :|

19:21 tolstoy: Do you guys think this little problem is a Clojure bug of some sort? Or just the limitations of this proxy stuff?

19:21 Does seem to work in Groovy, FWIW.

19:21 hiredman: tolstoy: I would ask chouser or rhickey if you can snag them

19:22 hmmm

19:22 clojurebot: clojure is not groovy

19:22 clojurebot: In Ordnung

19:23 tolstoy: Yeah, yeah, yeah. And I'm happy about that. But praps they're doing something similar. Probably not.

19:23 _ato: part of the difference with proxy compared to what scala or groovy do is that proxy's "methods" aren't really methods, they're clojure functions so their code is not in the proxy class. That's the reason why it's not possible to call protected methods or super in the proxy, for example

19:24 tolstoy: _ato: It seems that it's not possible for the abstract class to call implemented abstract methods in the proxy, either.

19:24 _ato: that gives proxy higher performance (it doesn't need to generate a class for each instance, only one of each class proxied) and it makes it more flexible (you close over stuff and also redefine the methods of an existing proxy instance)

19:25 hiredman: erm

19:25 I doubt your performance claim has any merit

19:25 _ato: hiredman: ah yeah you're right

19:25 you should be able to close over stuff just like a anonymous class

19:25 hiredman: proxy is just a simple way to do it, and it gives you ability (that no one uses) to change the map of functions

19:25 tolstoy: Yeah, I really like the whole proxy thing in Clojure. Kinda bummed about this one thing. And not so happy with my colleagues who foisted this upon me.

19:26 hiredman: ~proxy

19:26 clojurebot: proxy is <Chouser> proxy teases with its ease of use, then suddenly betrays.

19:26 qed: _ato: do you know if in compojure 0.3.1, if you can use (html [:html [:body body-content]]), where body-content is a string of html?

19:26 that makes sense right?

19:27 _ato: qed: yeah, you should be right

19:27 hiredman: tolstoy: you can gen-class a class that takes a runnable and then runs that runnable when the method is called, jar up the class, plop it on the classpath and never worry about it again

19:27 tolstoy: hiredman: Yeah, I think that's what I'll do.

19:28 hiredman: runnable, callable, or even a IFn

19:28 tolstoy: Actually, I was just going to write a Java class that implements the abstract method, jar that up, then "proxy" that class.

19:29 hiredman: could I interest you in using the ASM library provided with clojure to generate the class?

19:30 I have some truly horrible macros

19:31 tolstoy: hiredman: I might be interested. Is it in some version of Clojure?

19:32 hiredman: it would be like, (make-class "a/b/c/foo" "super/class/Here" nil (method [Opcodes/ACC_PROTECTED "methodName" "(Ljava/utill/Map;)V" nil nil] return))

19:32 tolstoy: I was mostly kidding

19:32 http://gist.github.com/254579

19:33 tolstoy: Heh. I think my dorky solution might be easier.

19:33 hiredman: yes

19:35 tolstoy: Kinda compelling, though.

19:37 lambdatronic: I come bearing optimization ickiness.

19:37 howdy folks

19:37 two questions...

19:38 First, I noticed that a number of operations with building up sorted-maps, hash-maps, and vectors got slower and more memory inefficient between versions 1.0.1 and 1.1.0

19:38 and more frighteningly, something very weird is happening with the transients in 1.1.0

19:44 lisppaste8: lambdatronic pasted "transients of doom" at http://paste.lisp.org/display/91970

19:44 lambdatronic: can somebody help me understand what's happening in this code?

19:44 it seems pretty simple to me, just building up a transient vector and returning the persistent copy of it.

19:45 but when I do this in a loop, it explodes due to some kind of memory reuse under the hood.

19:45 doesn't seem to happen for small numbers of iterations.

19:45 but then, boom! gone

19:48 *tap tap* is this thing on? anyone there?

19:50 gbt: hi lambdatronic. I'm a noob so I can't help, but I'm sure someone will be along shortly :)

19:50 lambdatronic: here's to hoping.

19:50 ;)

19:51 gbt: are you using the new branch from git?

19:51 lambdatronic: I am. master 1.1.0

19:51 and when I updated, all my code got slower.

19:51 so umm...yeah. it's a bit upsetting.

19:53 *swirly misty stuff* I call on you, O great clojure gods! Here my poor mortal plea! Save me from 1.1.0!

19:54 gbt: if you get that to work make sure you post the incantation ;)

19:55 lambdatronic: (send-off rhickey help '(with transients of doom))

19:55 something like that, I suspect.

19:55 tolstoy: lambdatronic: Maybe a post to the maiing list, too?

19:57 lambdatronic: tolstoy: It had occurred to me. darned impatience.

20:01 lisppaste8: lambdatronic annotated #91970 "transients of doom - more info" at http://paste.lisp.org/display/91970#1

20:09 cmbntr annotated #91970 "about 1.1.0 being slower..." at http://paste.lisp.org/display/91970#2

20:10 tolstoy: Writing a little Java class in Emacs is fun. You just never know if you're going to get a syntax error!

20:21 interferon:

20:21 anyone know of youtube videos that demonstrate structured editors for lisp, like paredit?

20:25 chouser: lambdatronic: I think I have some answers for you

20:25 lambdatronic: brilliant

20:25 the man himself!

20:25 chouser: lambdatronic: no no, I'm not the man. But I'll see if I can help.

20:26 I think your first problem is one of head-holding.

20:26 lambdatronic: hmm

20:27 if you're referring to my doall, that was intentional. I'm trying to time a large number of these calculations and determine how much memory they'll take. hence I want to hold the list's head.

20:27 but my annotation contains a doseq as well to demonstrate that the problem is still happening.

20:27 chouser: If you feel up to it, you could try the latest from the 'new' branch -- it might help.

20:27 lambdatronic: always nail-biting moments of excitement and adventure in this community.

20:28 I'm up for it, but perhaps you could give me some details.

20:28 I can just rerun the same silly computation multiple times with the doseq (no head holding) and every few runs it throws the IllegalAccessError.

20:28 So it's pretty non-deterministic.

20:29 hence the "of doom" part.

20:29 chouser: well, the latest 'new' has logic to make clearing of locals more pervasive, which is likely to help if it's really a head-holding problem.

20:29 lambdatronic: My code isn't holding on to those transients anywhere. just reducing and then calling persistent!

20:29 hiredman: didn't he just say he wants to hold the head?

20:29 lambdatronic: can you point to the head-holding?

20:29 I'm afraid I don't see it.

20:30 skybound: i tried the code lambdatronic has posted on new, same exception as with current master

20:30 lambdatronic: (sorry about the persistent!. That's not emphasis. Just trying to get the symbol right).

20:30 chouser: lambdatronic: not specifically, which is why I'm not sure.

20:31 lambdatronic: ah, then it's a real bug. excellent.

20:31 I hate wasting people's time with silly stuff.

20:31 chouser: wait wait wait.

20:31 lambdatronic: (await chouser)

20:32 chouser: can you paste the full stack trace?

20:32 IllegalAccessError is weird

20:32 lambdatronic: Yeah, but that's it.

20:32 chouser: (.printStackTrace *e)

20:32 lambdatronic: alrighty.

20:32 just a sec.

20:34 lisppaste8: lambdatronic annotated #91970 "transients of doom - and a stacktrace" at http://paste.lisp.org/display/91970#3

20:35 lambdatronic: voila!

20:37 I might also mention that I have a number of similar functions to rv-plus5-fast (hideous name, I know - just for testing purposes)

20:37 hiredman: uh

20:37 lambdatronic: and when I upgraded from clojure 1.0.1 to the newest master in git.

20:37 hiredman: Mutable used after immutable call

20:37 lambdatronic: they all become much slower.

20:37 hiredman: yes, I see the error. but where is it coming from?

20:38 because if you try running the code snippet without the loop, it works most of the time.

20:38 mind you, most of the time.

20:38 then you get the exception.

20:38 and so on

20:38 so it happens every few runs of the function.

20:39 that indicates that some of the previously allocated transient memory is being recaptured by clojure for future function calls.

20:39 i.e. aaaaahhhh!

20:40 chouser: Does that error mean "Transient used after 'persistent!' called"?

20:40 if so we should get it updated.

20:40 that appears to be what it means.

20:41 lambdatronic: seems like it, boss.

20:41 but how is the question.

20:42 chouser: is randvars.clj:338 the 'then' or the 'else' clause?

20:43 lambdatronic: then

20:45 It's this line in rv-plus5-fast

20:45 (conj! (pop! acc) [v2 (+ p1 p2)])

20:46 hiredman: ,(doc pop!)

20:46 clojurebot: "([coll]); Removes the last item from a transient vector. If the collection is empty, throws an exception. Returns coll"

20:47 hiredman: hmmm

20:48 lambdatronic: (persistent! (pop! (transient (vector [1 2] [3 4]))))

20:48 Yields => [[1 2]]

20:48 Looks right to me.

20:48 hiredman: yes

20:48 lambdatronic: just replacing the last element of the vector.

20:49 as in...

20:49 (persistent! (conj! (pop! (transient (vector [1 2] [3 4]))) [5 6]))

20:49 Yields => [[1 2] [5 6]]

20:50 hiredman: can you try it without the destructuring?

20:51 lambdatronic: hmm...

20:52 alexyk: how do I write a serializable Java object to disk from Clojure?

20:52 hiredman: how do you do it from java?

20:52 lambdatronic: ;)

20:52 alexyk: um... with streams...

20:53 hiredman: sameway

20:55 polypus: is compojure's request handling multithreaded?

20:56 lambdatronic: well, I removed the destructuring and got the same error.

20:56 hmm...

20:57 alexyk: ok how do you write this with ..: new ObjectOutputStream(new FileOutputStream(fileName)) ?

20:57 lisppaste8: lambdatronic annotated #91970 "transients of doom - sans destructuring" at http://paste.lisp.org/display/91970#4

20:57 lambdatronic: (ObjectOutputStream. (FileOutputStream. filename))

20:58 alexyk: ..and I was looking forward to .. ! :(

20:58 lambdatronic: no method calls, just new

20:59 alexyk: right

20:59 lambdatronic: which is native clojure

20:59 *shrugs*

20:59 take a look at clojure.contrib.duck-streams

20:59 it contains magic.

21:00 hiredman: lambdatronic: for binary files duck-streams is not so good yet

21:00 lambdatronic: hmm...ah well.

21:00 worth a shot.

21:00 hiredman: (into (sorted-map) (map identity (persistent! all-unique)))

21:00 lambdatronic: anyway...you still alive, o mighty chouser?

21:01 hiredman: hmmm

21:01 alexyk: I mean it's right as in good! :)

21:01 karmazilla: why (map identity ...)?

21:02 lambdatronic: erm?

21:02 hiredman: I was just trying to stick in a layer of indirection

21:03 lambdatronic: did it help?

21:03 hiredman: haven't tried it yet

21:04 I need to download a copy and muck with it

21:04 lambdatronic: alright, I'll give it a shot.

21:04 it would appear chouser has returned to olympus

21:08 ooh...check it out.

21:08 I might have fixed it!

21:10 lisppaste8: lambdatronic annotated #91970 "transients of doom - shazam!" at http://paste.lisp.org/display/91970#5

21:10 hiredman: interesting

21:11 lambdatronic: isn't it though.

21:11 spooky

21:11 I guess conj! pop! is vetoed

21:17 and here's the amazing part.

21:17 that actually uses more memory and is slower (by a tiny bit) than just building the whole thing up in a sorted map to begin with.

21:17 the transients buy me nothing.

21:17 damn

21:25 lisppaste8: lambdatronic annotated #91970 "transients of doom - profiled" at http://paste.lisp.org/display/91970#6

21:25 lambdatronic: and for the ultimate in irony, ladies and gentlemen, please examine this paste!

21:25 not that the transient version uses more than twice the memory of the non-transient code.

21:25 ??!

21:26 note that...

21:27 pedroteixeira: lambdatronic, is that using the new branch from github?

21:27 lambdatronic: it's the current master

21:30 pedroteixeira: would the recent optimizations http://groups.google.com/group/clojure/browse_thread/thread/14baed8f26097515 do any good?

21:32 tolstoy: Hm. I've created a little Java class. Put some methods on it, then made a proxy of it in Clojure, and none of my overridden methods get called. Clearly, I've completely misconstrued what "proxy" is. Oops!

21:34 lambdatronic: pedroteixeira: it's a good idea, but someone mentioned earlier that a test of my pasted code still bombed hard on new.

21:34 I'll give the fixed version a trial run though for profiling. thanks for the reminder.

21:38 pedroteixeira: nice, lambdatronic :)

22:00 tolstoy: I really love Clojure, but I can't even manage to compile an actual file. Holy Jaysus!

22:09 Ahah! If you have every directory on your filesystem in the class path, it works! ;)

22:10 danm_: haha

22:11 tolstoy: Reminds me of day 1 with java oh those many tortured years ago.

22:11 Lisp and Macros I can handle. Classpath? Oy.

22:24 alexyk: tolstoy: leiningen will save you from the monster of classpath

22:25 tolstoy: alexyk: Thanks.

22:26 alexyk: np

22:27 tolstoy: We have this service framework that you're sposed to subclass (I hate it), but I just don't see how it can be done in Clojure.

22:27 Certainly not in a script context.

22:28 Proxy won't work because I need to implement callbacks. Java calling back into Clojure code.

22:29 danm_: I thought that was one of the use cases for proxy? but I'm just a noob.

22:29 tolstoy: That's what I thought, too.

22:30 drewr: you can do that

22:30 tolstoy: You can use proxy to extend a class. In Clojure, you can call methods on that class. If the methods aren't in the proxy, it'll call the super class.

22:30 BUT, if the superclass calls a method you think you've overridden in your proxy, no go.

22:31 Hell, maybe I've got it all wrong somewhere in here.

22:32 In another test, I was able to create proxies that implemented Jetty Handler interfaces, and hand them off to the Java code an things worked.

22:40 AHA! It's because those esteemed colleagues do massive amounts of side-effects in the CONSTRUCTOR of the superclass!

22:40 Er, wait.

22:44 Okay. So it seems that when you use the proxy, the object is constructed first, and if the constructor calls methods in its class, they're not delegated to the proxy until AFTER the constructor is done.

22:48 itistoday: i'm not sure i understand the double-colon

22:48 what is a name-space qualified keyword?

22:48 why would you need one?

22:48 i've been trying to find documentation on this and haven't been able to

22:50 tolstoy: I think it's just a short cut.

22:50 itistoday: my impression was that keywords exist in a single, global namespace

22:50 tolstoy: I know I just read something where they used it. Hm.

22:50 itistoday: the existence of namespace qualified symbols thus confuses me

22:51 tolstoy: aren't all symbols namespace qualified?

22:51 devlinsf: http://groups.google.com/group/clojure/browse_thread/thread/8d77ad0da8d190c8

22:51 itistoday: err.. i meant namespace-qualified keywords

22:51 devlinsf: The qualified keywords came up there

22:52 itistoday: does clojure not have documentation that explains what they are?

22:52 tolstoy: Keywords exist simply because, as you'll see, it's useful to have names in code which are symbol-like but not actually symbols. Keywords are by default not namespace-qualified. However, in some cases it may be useful to generate a keyword that is namespace-qualified so as to avoid name clashes with other code. For that purpose, one can either qualify the namespace explicitly or type a symbol preceded by two colons

22:53 http://en.wikibooks.org/wiki/Learning_Clojure

22:54 itistoday: ok thanks, but that doesn't explain what how a keyword can be associated with a namespace

22:54 or rather, why that should be at all

22:54 tolstoy: ,::foo

22:54 clojurebot: :sandbox/foo

22:54 devlinsf: ,*ns*

22:54 clojurebot: #<Namespace sandbox>

22:55 itistoday: i.e. what sort "name clashes" are being referred to?

22:55 danm_: ,:foo

22:55 clojurebot: :foo

22:55 hiredman: itistoday: for the same reason symbols can be namespaced qualified

22:55 keywords can be used for just about anything

22:55 danm_: itistoday: in case someone else has defined a keyword with the same name which is in scope I guess?

22:56 itistoday: hiredman: i understand that symbols can be name space qualified, but i thought one of the points of keywords was that they all exist in the same namespace

22:56 danm_: by default they don't resolve to any namespace, right?

22:56 itistoday: thus if you have a map: {:blah 5}, you can look it up with the same keyword no matter what the namespace

22:56 hiredman: itistoday: sure

22:56 :blah is not namespace qualified

22:56 itistoday: ok, so what is this business about namespace qualified keywords?

22:57 if one of the points of keywords is that they're *not* associated with any namespace?

22:57 hiredman: when you are using namespaces as identifiers

22:57 ,::blah

22:57 clojurebot: :sandbox/blah

22:57 hiredman: that is namespace qualified

22:57 itistoday: hiredman: not sure what you mean by "namespaces as identifiers"..?

22:57 hiredman: sorry

22:57 keywords as identifiers

22:58 if you are using a pluggin system

22:58 and plugins have access to store

22:58 if you store something with the key :a, another plugin might overwrite it

22:59 itistoday: hiredman: store something where?

22:59 hiredman: but if you use a anemaspace qualified keyword

22:59 itistoday: whereever

22:59 could just be a hashmap somewere

22:59 could be persisted to to disk

23:00 keywords can be namespace qualified for the same reason symbols are

23:00 to avoid clashes

23:01 itistoday: i think it would greatly help me (and others trying to learn clojure) to understand the reason for namespace qualified keywords if there were some practical example in the docs as to the sort of problems they solve

23:03 tolstoy: hiredman: I figured out what was wrong with the proxy object thing with abstract methods. Not sure you remember that from earlier today.

23:03 hiredman: I just gave you an example

23:03 tolstoy: all ears

23:03 (eyes?)

23:04 itistoday: hiredman: sorry, i didn't quite understand your example, it wasn't very detailed

23:04 tolstoy: hiredman: I think the proxy object instantiates the superclass BEFORE it registers the overridden methods.

23:04 hiredman: In my particular use case (condemned to use bad code five years old), the constructor calls a bunch of its own methods when it instantites.

23:05 hiredman: ah

23:05 yeah it would have to

23:05 itistoday: hiredman: let me know if this is accurate

23:05 hiredman: you have to call super irst

23:05 first

23:05 tolstoy: The constructor context doesn't know about, say, the implementation of the abstract method until AFTER the constructor is done. (Seemingly.)

23:06 hiredman: exactly

23:06 tolstoy: And the folks who wrote all this stuff START UP SOCKET SERVERS in constructors.

23:06 hiredman: because the call to the super class constructor has to be the first thing in a constructor

23:06 tolstoy: Not that I'm bitter, or anything.

23:06 Yeah.

23:07 itistoday: hiredman: nope, never mind, i thought i had a reason for why namespace-qualified-keywords (NQKs) might be needed but turned out to be a bad reason...

23:07 tolstoy: Personally, I took the word constructor litterally, bit naievely. It's just there to assign instance vars, or better, do nothing. ;)

23:08 itistoday: I think there's an example in the printed book that uses them for multi methods.

23:08 itistoday: tolstoy: unfortunately i don't have the book, but i do have this: http://blog.thinkrelevance.com/2009/8/12/rifle-oriented-programming-with-clojure-2

23:08 hiredman: itistoday: like if I want to add something to the metadata mapa on an object, if I just add it with the key :a, it is possible some other function out there also twiddles the key :a

23:09 itistoday: hiredman: then why wouldn't you use a namespace qualified symbol to store it instead?

23:09 hiredman: itistoday: because I can use a namespace qualified symbol

23:10 itistoday: hiredman: you mean keyword?

23:10 hiredman: yes

23:10 itistoday: hiredman: ok, so this is just out of love for using the colon syntax everywhere..

23:10 hiredman: it's just more convient

23:11 keywords print and can be read back with out changing their resolution behaviour

23:11 ,(prn 'foo)

23:11 clojurebot: foo

23:11 hiredman: if you read that back in and eval it you can something completely ddifferent from 'foo

23:12 it will try to resolve foo

23:12 itistoday: why couldn't it print it out as 'foo then?

23:12 hiredman: but keywords don't have that problem

23:12 itistoday: you could never print an unquated symbol then

23:13 quoted

23:13 tolstoy: So, the question is really why keywords instead of symbols, with namespaced keywords just an extra sophistication.

23:13 hiredman: tolstoy: the real question is why itistoday cares so much about it

23:14 my guess is he misses common lisp

23:14 itistoday: hiredman: i care because i'm deeply interested in software and languages

23:14 hiredman: i hate CL

23:14 perhaps hate is too strong of a word ... sorry, i "don't like" it :-p

23:14 hate i usually reserve for C++ ;-)

23:15 hiredman: well CL, from what I gather, has the keyword behaviour you seem to want

23:15 keywords in cl just being symbols in the keyword namespace

23:15 itistoday: it's just that upon discovering these "NQKs" it now seems to me that keywords are no longer as special or different from symbols as they would be without it

23:16 hiredman: no

23:16 tolstoy: so, symbols refer to other things, and keywords refer to themselves

23:16 hiredman: tolstoy: exactlly

23:16 that is the #1 property of keywords

23:16 tolstoy: a keyword can never refer to anything else

23:16 itistoday: tolstoy: yes, i understand that

23:16 hiredman: they are like numbers

23:16 tolstoy: Just working it out for myself, itistoday.

23:17 itistoday: hiredman: ok, that's a perfect analogy, they *should* be like numbers

23:17 imagine if you came across a namespace qualified number

23:17 that is how i feel

23:17 hiredman: itistoday: -1

23:17 interferon: i am completely hitting a wall with these exception messagez

23:17 hiredman: 1i

23:17 tolstoy: Hm. So, using :<name> signifies to all concerned that you're not working with a symbol that might refer to a function or string if it were evaluated.

23:18 interferon: i have a runtime exception trying to evaluate a sequence and i don't see anything but clojure.core functions in the stacktrace

23:18 itistoday: hiredman: not sure what you mean?

23:18 interferon: what do people use to debug?

23:18 itistoday: hiredman: -1 and 1 are different...

23:18 interferon: jswat?

23:18 hiredman: itistoday: what is the difference between 1 and -1

23:19 itistoday: hiredman: that's a philosophical question

23:19 hiredman: lets say +1 and -1

23:19 tolstoy: interferon: You didn't happen to use ( ) for fun params, rather than [ ], did you?

23:19 itistoday: hiredman: +1 and -1, both of them are numbers, they evaluate to the same mathematical quantity

23:19 hiredman: +1 is 1 qualified in the positive namespace

23:19 interferon: tolstoy: doesn't look like it

23:19 hiredman: itistoday: the certianly don't

23:19 itistoday: hiredman: no, you are confusing terms

23:19 tolstoy: interferon: Heh. Well, that one got me a few times.

23:20 interferon: me too :)

23:20 itistoday: hiredman: when i said "same quantity" i meant they both evaluate to the same number (each of them)

23:20 interferon: tolstoy: i come from CL and schema

23:20 *scheme

23:20 itistoday: hiredman: you are confusing terms, mixing namespaces with your newly invented term "namespace" to signify something completely different

23:20 tolstoy: interferon: I've used those as well. But the error message is totally opaque.

23:20 hiredman: itistoday: what does a namespace signify?

23:21 itistoday: hiredman: here is what I am referring to: user/1 being different from foo/1

23:21 that is what a namespace is, not the +/-

23:21 so you would suddenly have a 1 that meant different things in different namespaces!

23:21 hiredman: ,:+/1

23:21 clojurebot: Invalid token: :+/1

23:21 itistoday: that would be bizarre

23:21 hiredman: no you wouldn't

23:21 itistoday: ,user/1

23:21 clojurebot: Invalid token: user/1

23:22 interferon: so is jswat the preferred debugging tool?

23:22 itistoday: see, clojurebot rightfully thinks that's stupid

23:22 interferon: are there other options?

23:22 hiredman: because a keyword always evaluates to ittself

23:22 tolstoy: interferon: I've no idea what people use. I use println. Yep. Sad to say.

23:23 clojurebot: hiredman is correct

23:23 itistoday: hiredman: either you believe in your analogy that keywords are like numbers or you don't, you can't adopt self-conflicting points of view

23:23 hiredman: itistoday: in what way are keywords not like numbers?

23:23 itistoday: hiredman: in that in Clojure, keywords can be namespace qualified

23:23 hiredman: in CL they can't, and that's good

23:23 hiredman: and numbers have a sign

23:23 tolstoy: itistoday: Analogies are just helpful, not metaphysical. Keywords eval to themselves like numbers do, but they're not numbers, eh?

23:24 itistoday: hiredman: the sign is not a clojure namespace

23:25 tolstoy: yes, i understand, in Clojure keywords aren't like numbers, this is what i learned today from you and hiredman, my original question was answered. i just wish they were like numbers. :-p

23:25 hiredman: itistoday: I could write some basic arithmetic functions that manipulate keywords of the form :negative/num_1 and :positive/num1

23:25 tolstoy: itistoday: Ah, well! There's nothing from stopping you using them that way in your code, though, right?

23:25 hiredman: :imaginary/num_1

23:26 itistoday: tolstoy: true. :-)

23:26 tolstoy: itistoday: But if we use your code, and want to use that name for our own thing, we can ::<your-global> and use it locally.

23:26 Rather than, say, :<my-bigass-classname>/keyword.

23:26 itistoday: tolstoy: you could also do it like C and append a short prefix

23:27 tolstoy: Yeah.

23:27 itistoday: tolstoy: i dunno, perhaps i'm old fashioned ;-)

23:27 hiredman: i understand your analogy, but i'm just trying to take it literally, not figuratively as you are

23:28 hiredman: a -1 will be the same thing in all namespaces

23:28 hiredman: clojurebot: :negative/num-1 + :positive/num-1 |=| :zero/zero

23:28 clojurebot: Ok.

23:28 tolstoy: I get the impression that hardly anyone uses it. I mean, let's say it's just wrong to namespace keywords. Is it a deal breaker? ;)

23:28 hiredman: itistoday: only if you are attached to that particular notation

23:28 tolstoy: that is wrong

23:28 it is used everywhere

23:28 tolstoy: hiredman: Ah. Okay. :) I had no idea.

23:29 hiredman: Haven't read enough source code yet. Spending all day on this proxy thing hasn't helped.....

23:29 hiredman: clojure.zip for example, hangs pieces of the zipper infrasrtucture in metadata

23:30 clojurebot's plugin stuff

23:30 any serious use of mutlimethods

23:31 itistoday: see, i suppose the reason i'm a bit upset about this is because to me keywords are now almost self-contradictory in nature in clojure. their purpose was to exist as symbols that evaluated to the same thing *everywhere*, and now there is this new syntax that says "but.. not really", and i'm thinking, "oh, you mean just like symbols?" ... eh... i give in. i can only be incredulous for so long. now that i understand what the :: syntax i

23:31 s, i will be pacified. thank you hiredman and tolstoy for your explanations. :-)

23:32 hiredman: itistoday: the only time a keyword is not evaluated the same every where is if you use the :: shortcut

23:32 itistoday: hiredman: yes. i understand that nwo

23:32 *now

23:32 tolstoy: Hm. But :keyword and ::keyword are not the same keyword, so that's still true?

23:32 itistoday: tolstoy: right

23:32 hiredman: :: just means "qualify this keyword with the namespace I am in now"

23:32 itistoday: ah, so they "could be"

23:32 heh

23:33 confusing

23:33 hiredman: ,:a

23:33 clojurebot: :a

23:33 hiredman: ,::a

23:33 clojurebot: :sandbox/a

23:33 itistoday: i personally would prefer :myPrefix-foo

23:33 hiredman: ,(= :a ::a)

23:33 clojurebot: false

23:33 itistoday: it reduces confusion

23:33 hiredman: nope

23:34 itistoday: and the last reason that i'm upset about this is that this doesn't seem to be documented on clojure's website

23:34 this is an obvious point of confusion

23:34 and it should be clearly explained what they are and why they are

23:34 i.e. a justification (as hiredman provided) for their existence

23:34 hiredman: itistoday: http://clojure.org/data_structures#toc8

23:35 tolstoy: http://clojure.org/data_structures

23:35 itistoday: it's not explained there

23:35 if you think that is an explanation you ... shouldn't ever be allowed to write documentation

23:35 tolstoy: itistoday: I sympathize. For me, a lot of examples of why you'd care one way or another would help.

23:36 itistoday: I don't mean YOU, I mean, how keywords are useful.

23:36 hiredman: the fact that it needed to be explained to you has been anomalous

23:36 itistoday: tolstoy: gotcha :-)

23:36 tolstoy: Er, I mean, I wouldn't mind seeing good example of how one can leverage the feature. There. That's what I meant.

23:36 hiredman: most people either don't care, or understand

23:36 itistoday: hiredman: i would be willing to bet money this is a point of confusion to clojure newcomers

23:37 hiredman: most people either don't care, or don't understand

23:37 you know how I know that? because *it's not explained anywhere*

23:37 hiredman: itistoday: as I have been here for for at least a year helping people learn clojure, I can tell you it isn't

23:38 tolstoy: I visited clojure a year or so ago, and it's stunning the progress on documentation thus far.

23:38 hiredman: itistoday: then explain why people use namespace qualified keywords in libraris all the time?

23:38 itistoday: hiredman: because they know what they are

23:38 as to how they know i couldn't begin to tell you as i'm not them

23:39 hiredman: surely you don't think that most people who use or try to use clojure write clojure libraries?

23:39 hiredman: itistoday: these days, yes

23:40 most people seem to post something to github on their sedcond or thiird day

23:40 usually an uneed wrapper around ajva library

23:40 itistoday: hiredman: you only hear about the ones that do, lol

23:40 you don't hear about the people who go to clojure's website, try to make sense out of it, and leave in disgust

23:41 or perhaps they leave feeling inadequate ;-)

23:42 hiredman: itistoday: I hear plenty of people complain about such and such not ebing documented, and then when I point them at the docs they say "oh, but thats not where I expected" or "there are no examples", or some other execuse for why they want someone to hold their hand

23:43 itistoday: "there are no examples" is not an excuse, but a perfectly valid criticism of documentation

23:43 good documentation always has examples

23:43 clojure's documentation, is not good

23:43 it is barely acceptable (in my opinion)

23:43 hiredman: it is a valid criticism on it's own, but in that context it is just another of a infinite list of complaints basically

23:44 itistoday: in your eyes, whatever, "sounds like 'complaining' to me", lol

23:44 in they're eyes it's shitty or totally non-existent documentation

23:44 *their

23:44 hiredman: the documentation is there

23:44 the code is there

23:45 itistoday: i'm not disputing that

23:45 qed: itistoday: help make it better

23:45 tolstoy: I remember learning Java in 2000 or so, and spent many an hour writing all kinds of code, only to discover it was alreayd in the JDK. Took me quite a while to figure out how to read the docs.

23:45 hiredman: people just what to whine

23:45 itistoday: qed: i would, i would love to, unfortunately my work doesn't involve much of clojure (yet)

23:45 qed: tolstoy: yeah i suck at reading java docs so far

23:45 im a noob

23:45 hiredman: come in and throw their weight around

23:46 qed: itistoday: do it because you're interested in learning something new and helping a community grow in the process

23:46 dont just be an asshole

23:46 itistoday: qed: i would, if i were using clojure more

23:46 qed: just sayin'

23:46 itistoday: qed: currently it's just a passing interest

23:47 tolstoy: qed: After a while you get a feel for it. Weird how that is.

23:47 itistoday: qed: i'm sorry if you view valid criticism as being an "asshole"

23:47 qed: i'm not trying to be an asshole, sorry if i came across that way

23:48 criticizing something is the only way to bring attention to something that needs to be improved

23:48 err... well, that and actually improving it yourself :-p

23:49 if anyone who is involved with clojure's documentation cares, i highly recommend taking a look at how newlisp does its documentation: http://www.newlisp.org/downloads/manual_frame.html

23:49 qed: cool ill check it out

23:49 itistoday: :-)

23:50 hiredman: leave the dead (people who complain about docs) to bury the dead (endless fiddle with docs)

23:50 qed: hiredman: i really just need examples

23:50 hiredman: the docs are there, and good enough to start coding with

23:50 itistoday: hiredman: you know, if the docs were better you'd have fewer people in here complaining and asking questions

23:50 hiredman: it'd make your job easier ;-)

23:51 _mst: I thought #clojure was a collaborative documentation effort... this all gets logged, right?

23:51 qed: indeed it does

23:51 but no one is actively transcribing

23:51 hiredman: itistoday: I have no problem with questions

23:52 tolstoy: I find the docs mostly good enough. When I don't, I futz around with the code, then read the docs again, and see that it told me what I needed to know all along.

23:52 qed: maybe that's my new job... ill start compiling the logs in tagged posts or something

23:53 tolstoy: This was awesome for me (having spent time with CL): http://java.ociweb.com/mark/clojure/article.html

23:53 qed: a well documented project needs to provide many different forms of documentation

23:53 hiredman: clojurebot: can the hyperspec help us here?

23:53 clojurebot: hyperspec is not applicable

23:54 technomancy: itistoday: that's why he wrote clojurebot

23:54 to answer questions for him

23:55 hiredman: in #emacs the bot will treat a single word followed by a question mark as a lookup. kind of funny how often that actually helps.

23:55 hiredman: it's not going well

23:55 technomancy: hmmm

23:56 technomancy: also "what is $TERM?"

23:56 itistoday: technomancy: didn't know hiredman wrote clojurebot. hiredman: cool beans!

23:57 technomancy: itistoday: he did, after I told him to. =)

23:57 itistoday: hehe, wow

23:58 technomancy: and then I told him I'd help him with it, but I never did

23:58 itistoday: clojurebot seems pretty solid as it is though

23:59 technomancy: well I did write some retarded SVN watcher that just shelled out to the svn command-line XML output, but that got quickly replaced

Logging service provided by n01se.net