#clojure log - Jun 29 2011

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

0:00 technomancy: "no, you show _me_ the relevant ruling where it was determined that recursive copyright declaration was declared invalid in court."

0:01 I mostly kid though. I love debian as a user. just not as a developer.

0:01 * amalloy wonders what recursive copyright declaration looks like

0:02 cemerick: technomancy: tell that to the poor guys that apt-get install eclipse, and are left with a steaming pile. :-X

0:03 amalloy: cemerick: that worked fine for me, last time i tried

0:03 technomancy: amalloy: "This file and all subdirectories it contains are copyright [...]"

0:03 cemerick: the JVM stuff seems particularly neglected

0:03 * technomancy remembers running into outright-busted solr packaging a year or so ag

0:03 amalloy: ah. i was thinking: "This file is governed by the copyright declarations that govern it"

0:03 technomancy: probably due to java being non-dfsg-compliant for so long

0:04 amalloy: heh

0:04 cemerick: amalloy: three separate people in the past two weeks got bizarre errors upon attempting to add ccw into pristine eclipse installs; downloading binaries from eclipse.org fixed all three

0:04 technomancy: reminds me of the cliki disclaimer

0:04 "CLiki pages can be edited by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively"

0:05 cemerick: I have a sneaking suspicion that it has something to do with EPL v. GPL compatibility of certain usually-default eclipse plugin repositories that ccw depends upon.

0:05 technomancy: all the debian packaging docs are makefile this, autoconf that; figuring out how to package anything that's not C-based takes a lot of digging

0:05 amalloy: cemerick: well, eclipse on unix has been a pain for me in general, because if you install as root you need to add plugins as root

0:06 so if there was added pain from using a .deb i didn't notice

0:07 technomancy: they screw up rubygems pretty badly too in order to make it fhs compliant

0:07 part of the reason I rejected the idea of writing the lein launcher in ruby

0:07 cemerick: amalloy: I think there's a way to cause it to use ~/.eclipse or something as the plugin/feature root

0:08 technomancy: heh; I added that exact feature to rubygems.

0:08 cemerick: In any case, it's just not something that should ever be packaged the way it is. It's not designed for it, and seems to be done without input from the sources

0:08 s/sources/author(s)

0:08 sexpbot: <cemerick> In any case, it's just not something that should ever be packaged the way it is. It's not designed for it, and seems to be done without input from the author(s)

0:11 tmciver: Hi all. What's the best way to debug Clojure code? Is there a way to step through a library my project uses?

0:13 amalloy: tmciver: not that it's really an answer to your question, but shouldn't you be stepping through your own code? the library is likely to (a) work, (b) be harder to debug

0:14 dnolen: tmciver: http://georgejahad.com/clojure/swank-cdt.html, https://github.com/hugoduncan/swank-clj

0:15 technomancy: cdt is the only stepping debugger I know of

0:15 hugod: swank-clj does stepping too

0:15 technomancy: cool

0:15 cemerick: as does enclojure

0:15 dnolen: technomancy: jswat works as well as far as I know.

0:16 tmciver: amalloy, ideally, yes, but I think there's a bug. Of course it could be a bug in my code. :(

0:16 * technomancy has never found the need to graduate beyond swank break

0:17 tmciver: Is stepping through the code not a *typical* debugging method?

0:17 amalloy: yeah, stepping is a lot less useful in a functional language. there are no "instructions"

0:17 hugod: it's nice to be able investigate exceptions at the throw site - even if the majority of locals are cleared

0:18 tmciver: I've tried putting print statements, :/, in the library and regenerating the jar, but I'm not seeing anything.

0:19 I'll look into swank-clj

0:20 hugod: you can add print statements and just recompile the file in slime with C-c C-k - no need to rebuild the jar

0:21 amalloy: hugod: even someone else's jar? i guess i never tried that

0:21 hugod: yep

0:21 tmciver: Hmm. I just got slime/swank up and running. I'll have to check that out.

0:23 hugod, how does that work? The file needs to be on the classpath?

0:24 hugod: Use M-. on one of the jar's symbols to navigate to the source in the jar file, edit, compile

0:24 or just open the jar file directly in emacs

0:26 tmciver: Open a jar in emacs? Didn't know you could do that.

0:28 If I open the jar file, I get a listing of the class files. If I open one of those, it a binary (bytecode) file with some text . . .

0:29 hugod: I assumed you had .clj files in the jar…

0:30 you can compile any file with C-c C-k, and it should work, whether it is on the class path or not, as long as all the :requires are on the classpath.

0:34 tmciver: Is it typical to have .clj files in the jar?

0:35 hugod: it is generally a good idea not to AOT compile clojure files unless you have a good reason to

0:35 tmciver: Ah, I DO see clj files!

0:36 I assume that if clojure code is not AOT compiled then the jar cannot be used from java?

0:38 amalloy: tmciver: the java code just has to go through the clojure runtime to use clj files

0:38 hugod: I think that depends on how you are using it from java - if you are using any interfaces or classes gen-classed in clojure, you need them to be AOT compiled

0:38 tmciver: Ah, OK. Thanks.

0:40 On that topic: I read that all clojure functions compile to their own class files. Can they be AOT compiled and then called from java?

0:42 amalloy: yes, but ew

0:42 tmciver: Ha. I'm sure, but I'm just curious.

0:42 dnolen: tmciver: you'll probably want to go through Clojure's RT.java.

0:42 amalloy: &(class ((fn [] (fn []))))

0:42 sexpbot: ⟹ sandbox7608$eval11441$fn__11442$fn__11443

0:43 amalloy: tmciver: that classname will change every time you compile

0:43 tmciver: Oh! Yikes, that IS gross!

0:44 amalloy: &(class ((fn [] (fn [])))) ; again, for emphasis

0:44 sexpbot: ⟹ sandbox7608$eval11452$fn__11453$fn__11454

0:45 tmciver: By the way, I'm new to clojure on irc. how do I learn to use sexpbot and clojurebot?

0:45 Raynes: To evaluate code with sexpbot, just prefix any message with & and everything after it will be evaluated.

0:45 amalloy: tmciver: mostly by watching other people use them, really

0:45 Raynes: You can also ##(println "embed code") in your messages.

0:45 sexpbot: ⟹ embed code nil

0:46 Raynes: With clojurebot, prefix messages with a , (comma) to evaluate everything after it.

0:46 amalloy: ,(symbol "reporting for duty")

0:46 clojurebot: reporting for duty

0:46 tmciver: Cool, thanks.

0:46 amalloy: tmciver: sexpbot and clojurebot are both open-source, of course, if you want to look further into what features they have

0:47 Raynes: http://github.com/cognitivedissonance/sexpbot http://github.com/hiredman/clojurebot

0:47 tmciver: clojurebot is clojure-specific and sexpbot is not?

0:47 Raynes: They both have mostly the same functionality.

0:48 sexpbot might have a bit more.

0:48 It can do Haskell evaluation and such as well.

0:48 amalloy: and clojurebot acts more human :)

0:48 tmciver: Hmm. Do people prefer one over the other?

0:48 Raynes: $he [1..4]

0:48 sexpbot: ⟹ [1,2,3,4]

0:48 amalloy: tmciver: well, raynes and i prefer sexpbot. we're the main developers for it

0:48 Raynes: Not really. People just use whatever they feel like.

0:48 amalloy: but use what makes you happy

0:49 tmciver: Great! Thanks for helping out a newb!

0:49 amalloy: oh, you can also /msg either of them if you just want to try stuff out but don't havea repl handy

0:49 Raynes: All sexpbot really does different from clojurebot as far as Clojure evaluation goes is the embedded evaluation.

0:49 amalloy: (and don't want to spam #clojure with your nonsense)

0:50 tmciver: Ha! I never write nonsense. ;)

0:52 amalloy: there's a subtle difference that clojurebot sends one message per newline, which can lead to unintentional spamming if you call println. but, it also makes it easier to tell where a newline is, since sexpbot just collapses all whitespace to single spaces

0:53 Raynes: amalloy: Would it be better to replace the spaces with fake newlines?

2:02 sunnibo: hi guys.

2:03 symbole: Hi.

3:45 clgv: How do I consume something like a stream in clojure? In principle I have to do multiple calls on something like a read-method of the stream but have to check for EOF in-between to avoid having an EOFException thrown. In which control-structure do I put this? I only came up with loop-recur which doesnt seem to fit well since the stream is mutable.

3:49 schasi: Hej hej

3:50 I am searching for a presentable successful example where clojure has been used with a lot of data, presumably in the cloud :)

3:50 What would you present there?

3:50 Fossi: how much is "a lot"?

3:51 schasi: Example would be statistical data sets

3:52 "a lot" being as much that it pays to put the whole thing on a cloud :D

3:53 raek: http://dev.clojure.org/display/community/Clojure+Success+Stories

3:54 Fossi: raek: seriously, most of those read like advertisements for the companies/products

3:55 clgv: humm the last body of the clojure.core/read definition looks quite strange to me

3:55 Fossi: actually i can spot only one that answers the question on top: description of how you've used Clojure

3:56 schasi: Fossi: Which one would that be? :D

3:56 raek: clgv: how are you consuming the stream? what do you want to do with it?

3:57 Fossi: okay, it's more like three

3:57 clgv: raek: I want to return a list of all statements that are in the stream, not only the first

3:57 s/statements/forms/

3:57 sexpbot: <clgv> raek: I want to return a list of all forms that are in the stream, not only the first

3:57 Fossi: but out of ~30 that's pathetic

3:57 raek: line-seq inside a with-open is one common way to read lines

3:58 bsteuber: schasi: http://www.infoq.com/articles/flightcaster-clojure-rails

3:58 Fossi: "our" entry is shitty as well

3:59 clgv: raek: there is not a line-end in the stream necessarily

3:59 schasi: thank you, Fossi and bsteuber

3:59 mids: schasi: backtype.com also uses clojure and seems to handle shitloads of data

4:00 clgv: how can this work? it seems to be a recursive definition: (defn read ([stream eof-error? eof-value recursive?]   (. clojure.lang.LispReader (read stream (boolean eof-error?) eof-value recursive?))))

4:02 raek: (def eof (Object.)) (defn form-seq [rdr] (lazy-seq (let [form (read rdr false eof)] (when-not (= form eof) (cons form (form-seq rdr)))))~)

4:02 clgv: the last "read" is the name of a java method

4:03 (with-open [rdr (io/reader "file.clj")] (process-the-data (form-seq rdr)))

4:03 clgv: raek: oh, thats the ". form" - I am not used to it, since I use the abbreviated style

4:04 &(doc form-seq)

4:04 sexpbot: java.lang.Exception: Unable to resolve var: form-seq in this context

4:04 clgv: &(find-doc "form-seq")

4:04 sexpbot: ⟹ nil

4:04 raek: so, form-seq can be defined as above

4:04 my previous line starting with (def eof (Object.))

4:05 clgv: ah well. I see

4:05 thx, raek. :)

4:05 guess, I'll make that eof-object local;)

4:06 raek: just make sure the resulting lazy-seq from form-seq does not escape the with-open scope

4:06 clgv: raek: thats probably a reason for not making it lazy ;)

4:06 raek: you could replace "process-the-data" with "doall" or "vec" to force the seq

4:08 clgv: humm one could also close the reader at the end of the seq - which would force the user to consume the whole seq finally.

4:08 raek: but then it will only be closed if the whole seq is traversed

4:09 a client might only look at, say, the first three forms or something

4:09 clgv: do I get an EOF on a closed reader?

4:10 raek: or if the processing is aborted with an exception, the file will remain open too

4:10 clgv: no, I think you get a illegal state error

4:10 clgv: raek: IOException it is

4:10 raek: if you try to read from a closed stream

4:11 clgv: I could build a macro that provides the form-seq where the reader is only opened within the macro-block like in with-open

4:11 and the sequence is only evaluated until EOF or stream closed

4:12 raek: also, there's this: http://dev.clojure.org/display/design/Resource+Scopes

4:14 clgv: raek: it's just a discussion, no implemented concept, right?

4:14 raek: no implementation in any stable release

4:15 but some issues that one might need to look out for is mentioned

4:15 clgv: I think I can live with my macro solution: it has no resource problems but the lazy-seq of the reader will only contain the elements that were evaluated in the scope of the macro

4:21 humm there seems to be no exception-less method to query if a reader is still open

4:23 amalloy: clgv: in what way is this different from with-open, then

4:24 clgv: amalloy: it's a combination of with-open and raek's form-seq

4:25 amalloy: right. i don't think you want to "hide" the details of opening and closing the reader within your implementation of form-seq, especially since you can't do so transparently. the client has to be aware of how long the stream is open, so let him manage it himself with with0open

4:26 providing both transparency and flexibility, as well as fitting in well with line-seq and friends, which don't open or close anything

4:27 clgv: amalloy: I was aiming at a "process-form-seq" macro

4:29 amalloy: meh. make it a function: (with-open [in (reader whatever)] (process-form-seq in #(println %))) ;; process-form-seq constructs a seq of forms from a reader, and maps the provided function over them

4:32 clgv: humm right. I don't need to defer any evaluation - so a function will do

4:33 amalloy: clgv: i actually don't like my suggestion to use map: what if the client wants to reduce instead? then, of course, you generalize by just calling their function with the whole seq of forms as an arg

4:33 but at that point you're not doing anything but (with-open [...] (some-function (form-seq rdr)))

4:33 clgv: yep

4:37 amalloy: anyway, bedtime for me. have fun reading forms

4:38 clgv: :D

4:58 it works. I just wrapped a try catch for IOException into raek's form-seq

8:25 peteriserins: how to do (a b c) -> ([1 a] [2 b] [3 c])

8:25 clgv: &(map-indexed vec '(a b c))

8:25 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (2) passed to: core$vec

8:25 clgv: &(map-indexed vector '(a b c))

8:25 sexpbot: ⟹ ([0 a] [1 b] [2 c])

8:26 peteriserins: thank you

8:26 clgv: peteriserins: do you really want to start with 1?

8:28 peteriserins: clgv: nope, 0 is better

8:29 clgv: :)

8:53 $findfn vector '(a b c) '([0 a] [1 b] [2 c])

8:53 sexpbot: [clojure.core/keep-indexed clojure.core/map-indexed]

8:53 clgv: $findfn '(a b c) '([0 a] [1 b] [2 c])

8:53 sexpbot: []

8:53 clgv: (doc keep-indexed)

8:53 clojurebot: "([f coll]); Returns a lazy sequence of the non-nil results of (f index item). Note, this means false return values will be included. f must be free of side-effects."

9:00 peteriserins: I am having problems with re-seq

9:01 it duplicates the last line of the input

9:01 in a match

9:05 clgv: e.g.?

9:06 peteriserins: a\nb -> a\nb\n b

9:09 clgv: can you please write your clojure statement and it's output? or write it here with preceding , or &

9:09 peteriserins: tried to upgrade my cake, but that became buggy now

9:10 basically just running "cake" throws an error about not finding "make"

9:10 clgv: I refered to the re-seq issue

9:10 peteriserins: Exception in thread "main" java.lang.Exception: Unable to resolve symbol: make in this context (deps.clj:24)

9:10 clgv: sorry, I cannot address that now atm, because I cannot run clojure code :)

9:11 clgv: I don't use cake.

9:11 peteriserins: clgv: I normally use lein, but I hate that I have to create a project to play around with it

9:11 clgv: so I used cake for that

9:11 clgv: is there perhaps a way to run single-file programs with lein?

9:12 clgv: hm no idea. "create a project" in lein just means write a minimal project.clj or even let lein write it and just fill in the blanks.

9:13 raek: peteriserins: you can run "lein repl" outside a project to get a bare Clojure repl. then you can use load-file, I guess

9:13 clgv: you could just startup a repl yourself and load the single file...

9:13 peteriserins: lein repl < load-file "%" ?

9:14 or (load-file "%")?

9:14 raek: I was thinking about typing (load-file "the_file.clj") in the repl...

9:15 peteriserins: raek: yeah sure, I just want to type it from Vim if possible

9:15 raek: I dunno a convenient way to run scripts, since start only one clojure instance per development session

9:15 clgv: I like the "clj script" build with rlwrap.

9:17 setup is described here: http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started#Enhancing_Clojure_REPL_with_rlwrap

9:17 peteriserins: ok I can use the lein repl meanwhile

9:17 so the issue is

9:17 I'm re-seqing with

9:17 #"(.+\n)+\n"

9:18 on "a\nb\nc\n\n"

9:18 and it gives me ["a\n\b\nc\n\n c\n"]

9:20 fliebel: peteriserins: try #"(.+?\n)+\n"

9:21 hm, wait, maybe not. What do you expect to see?

9:21 Fossi: "...now you have two problems"

9:22 peteriserins: fliebel: I get the same result

9:22 clgv: &(re-seq #"(.+\n)+\n" "a\nb\nc\n\n")

9:22 sexpbot: ⟹ (["a\nb\nc\n\n" "c\n"])

9:22 peteriserins: clgv: I get it, ty, I forgot clojure doesn't use ',' for separation

9:23 can I make it greedy somehow?

9:23 fliebel: Anyone knows what non-reference grouping looks like in java regex?

9:24 &(re-seq #"(?:.+\n)+\n" "a\nb\nc\n\n")

9:24 sexpbot: ⟹ ("a\nb\nc\n\n")

9:24 clgv: peteriserins: the greedy behavior is discussed in javadocs.

9:25 fliebel: peteriserins: Isn't it greedy by default?

9:27 clgv: http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html

9:27 raek: peteriserins: the vecctor you get is the vector of the groups for _one_ match

9:27 clgv: Greedy, Reluctant and Possessive are distinguished

9:28 raek: ,(re-seq #"a(x|y)b" "axbaybaxb")

9:28 clojurebot: (["axb" "x"] ["ayb" "y"] ["axb" "x"])

9:28 fliebel: &(re-seq #"(?:.+\n)+\n" "a\nb\nc\n\na\nd\ng\n\n")

9:28 sexpbot: ⟹ ("a\nb\nc\n\n" "a\nd\ng\n\n")

9:28 raek: if you have n groups in the regex, you get a vector of size n+1 with their matches

9:29 where index 0 is the whole expression

9:29 s/expression/matched substring/

9:29 sexpbot: <raek> where index 0 is the whole matched substring

9:31 peteriserins: raek: riight

9:31 raek: that's helpful

9:38 raek: ...and as fliebel demonstrated, if you don't have any capturing groups, the string with the whole match is not wrapped in a vector

9:57 VT_entity: "Loop requires an even number of forms in binding vector" Why is this?

9:57 why can't I loop one s-expression over and over?

9:58 fliebel: &(loop [a])

9:58 sexpbot: java.lang.IllegalArgumentException: loop requires an even number of forms in binding vector

9:58 raek: VT_entity: the forms in the binding vector are variable-value paris

9:58 fliebel: &(loop [a 1] a)

9:58 sexpbot: ⟹ 1

9:58 raek: *pairs

9:59 VT_entity: what if I just want to loop one expression over and over?

9:59 * clgv like paris more than pairs ;)

9:59 clgv: VT_entity: explain by example

9:59 raek: VT_entity: even when you looop over one thing, you need to give it a name: (loop [x 10] (if (zero? x) 0 (recur (dec x))))

10:00 fliebel: How do I get the latest 1.3.0 alphas/snapshots? I think it was something like [clojure "1.3.0-master-alpha7"]

10:00 VT_entity: (loop [cond (<= 0 (count examplelist)) (do (println "still greater than or equal to zero"))])

10:00 raek: VT_entity: ah, now I get what you mean by "one expression". like this: (loop [] (do-foo ..) (recur))

10:00 VT_entity: oh

10:01 raek: VT_entity: loop marks the point where you can jump back to. recur is the jump

10:01 VT_entity: I was looping the wrong thing?

10:01 ooooooh

10:01 fliebel: raek: Would you prefer loop over while?

10:01 raek: the vector is the loop variables

10:01 fliebel: not in this case, I guess :)

10:02 fliebel: remove the "-master" part

10:02 VT_entity: so, if I put the recur at the end, it should be ok?

10:02 raek: "1.3.0-alpha8"

10:02 clgv: it is (loop [BINDINGS] ...) not (loop [CONDITION] ...)

10:02 raek: or "1.3.0-beta1"

10:02 fliebel: raek: Hm, are we beta already?

10:02 raek: VT_entity: you are probably thinking of 'while'

10:03 VT_entity: I should d something like (while () do)

10:03 clgv: fliebel: yeah beta came out sometime in the last two weeks

10:03 raek: saw a "[ANN] Clojure 1.3 Beta 1" in the mail recently

10:03 fliebel: clgv: You have the announcement handy?

10:03 clgv: fliebel: nope. I just saw it on clojure.org in the downloads section

10:04 VT_entity: oh dammit, wow, I just looked up while, you're right

10:04 edw: technomancy: I'm getting a port-already-in use error using clojure-jack-in. I thought port numbs were dynamically selected.

10:04 raek: (while <cond> <body>) is equivalent to (loop [] (when <cond> <body> (recur))) I think

10:04 fliebel: ah http://groups.google.com/group/clojure/browse_thread/thread/bfad91ece6d1b983#

10:04 clgv: raek++

10:06 fliebel: What does 'approved backlog' mean in Jira?

10:06 VT_entity: thanks a lot raek

10:07 clgv: $inc raek

10:07 sexpbot: ⟹ 9

10:13 fliebel: I wonder what's wrong with this: [org.apache.james/james-server "3.0-M2"] any ideas?

10:15 cemerick: fliebel: doesn't look like there's a jar artifact for those coordinates: http://search.maven.org/#artifactdetails|org.apache.james|james-server|3.0-M2|pom

10:15 Just a super POM, it seems…

10:15 fliebel: cemerick: http://repo1.maven.org/maven2/org/apache/james/james-server/3.0-M2/james-server-3.0-M2.pom

10:16 cemerick: fliebel: right, that's a POM, not a jar. [foo/bar "version"] coordinates describe jar dependencies.

10:17 I think there's a way to specify different dependency types in the lein world, but I don't know them off the top of my head.

10:17 fliebel: cemerick: Uhm, okay, and the other option is just to get all the right jars manually?

10:18 cemerick: fliebel: there looks to be a metric ton of apache james artifacts; presumably you need one (or more) of those?

10:19 fliebel: cemerick: Yea, I guess. I just want to run a mail server with SMTP and POP and then write my own database backend and do weird stuff.

10:19 s/POP/IMAP/

10:19 sexpbot: <fliebel> cemerick: Yea, I guess. I just want to run a mail server with SMTP and IMAP and then write my own database backend and do weird stuff.

10:21 clgv: fliebel: sounds pretty interesting.

10:23 cemerick: fliebel: Seems reasonable; you'll have to figure out which artifacts you need, though. Perhaps a msg to the james ML, or perhaps there's some docs somewhere that describe what each component does.

10:23 fliebel: clgv: Think https://github.com/pepijndevos/twemail without implementing the mail server.

10:25 Maybe I shouldn't even try embedding and customizing a server, and just bang away on the maildir.

10:25 TallAdam: (apply please-help '(me))

10:27 clgv: humm james server itself sounds interesting. I had lots of trouble when trying to setup a mail server with the single debian packages...

10:28 TallAdam: I am writing an open source library and I need to make it testable. I have made my tests but the tests need twitter credentials (as well some other credentials) to run. I need for the user to setup (def )'s just once, so that the tests can work - not sure the best way to do this? anyone got any ideas?

10:28 clgv: TallAdam: can you do some mocking?

10:29 edw: technomancy: ut?

10:29 fliebel: TallAdam: I ran all my Twitter test on a local statusnet instance :D

10:29 TallAdam: clgv: not sure what you mean?

10:30 cemerick: TallAdam: Using system properties for stuff like that is generally reasonable.

10:30 TallAdam: cemerick: thanks - thats a decent plan

10:31 cemerick: but if its not defined, how do I 'abort' the testing process?

10:31 cemerick: TallAdam: if you throw an exception at the top level, that will cause the loading of the test sources to fail, and tests will never be run.

10:32 TallAdam: cemerick: great - thanks for the advice

10:32 cemerick: e.g. (def username (or (System/getProperty "foo") (throw (Exception. "no username!"))))

10:32 I assume lein has a way to specify system properties for a given test run…

10:34 jweiss_: anyone here use clojure.contrib.trace? deftrace says it can be used in place of defn, but it can't - it won't take a docstring

10:35 also the fn it produces will have different metadata than the original - i'd like to keep the docs the same - same docstring and arg list

10:42 jcromartie: hey guys is quoting ever referred to as "code proection"?

10:42 http://blackstag.com/blog.posting?id=9

10:42 I've never heard that term for quoting before

10:45 raek: neither have I

10:51 edw: technomancy: I just sent you a pull request on clojure-mode: it fixes a misfeature I was banging my head against for 45 minutes.

10:56 coopernurse: how do you remove a elpa package installed locally?

10:56 I appear to have two versions of clojure-mode

10:56 1.9.1 and 1.9.2

10:59 jcromartie: coopernurse: check your ~/.emacs.d

10:59 coopernurse: jcromartie: can I just rm -rf the old version in elpa dir?

11:00 jcromartie: I believe so

11:00 coopernurse: ok thanks

11:01 jcromartie: I think elpa just loads from those directories automatically, looking for a certain .el file

11:01 coopernurse: ok

11:02 is it recommended to _not_ install the slime, slime-clj, slime-repl packages?

11:02 I'm gettting this error now when I run: clojure-jack-in

11:02 "Debugger entered--Lisp error: (void-variable slime-clj)

11:04 hugod: slime-clj is specific to swank-clj, and should not be installed if you are only using swank-clojure

11:04 coopernurse: hugod: ok thanks. I removed it from the elpa dir, restarted emacs, and that error went away

11:12 jcromartie: This tutorial (blackstag) made it to the top of HN, but it has a lot of iffy parts

11:13 I'd be wary of any intro to Clojure/FP that starts out with 0-ary functions returning random elements or calculations on def'ed vars

11:16 clgv: jcromartie: the term you cited above was probably the authors own invention as well ;)

11:16 jcromartie: yeah

11:17 Frem: jcromartie: There's probably free karma to be had here by posting corrections or recommending better tutorials. :-)

11:17 jcromartie: I mean, good on him for trying. I'm posting them as I read it.

11:27 edw: I wish people would stop talking about fight club. Can we try a little harder to keep our secret weapon secret?

11:32 jcromartie: edw: by "fight club" do you mean Clojure?

11:33 S11001001: is the behavior of (let [x (transient [])] (conj x x) (persistent! x)) defined?

11:34 ejackson: edw: lol.

11:35 yes, if the other software consultants find out about this, i'll be outta business, chopitty-chop.

11:36 solussd: ,(let [x (transient [])] (conj x x) (persistent! x))

11:36 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector$TransientVector cannot be cast to clojure.lang.IPersistentCollection

11:43 clgv: S11001001: looks pretty strange

11:44 S11001001: clgv: aye

11:45 sorry

11:45 obviously with just plain conj it's defined :]

11:45 ,(let [x (transient [])] (conj! x x) (persistent! x))

11:45 clojurebot: [#<TransientVector clojure.lang.PersistentVector$TransientVector@d66725>]

11:45 S11001001: ,(let [x (transient [1 2 3])] (conj! x x) (persistent! x))

11:45 clojurebot: [1 2 3 #<TransientVector clojure.lang.PersistentVector$TransientVector@11a9e33>]

11:46 S11001001: alright then, that's fair

11:46 clgv: S11001001: be carefull - you have to use transient similar to normal immutable collections, i.e. you have continue your work with the result of (conj! x e)

11:47 S11001001: clgv: which was my position

11:47 we've been having a debate on the subject of what it means, setting aside what it does

11:47 clgv: otherwise that might go wrong when you add a decent number of elements

11:47 S11001001: though I for one am glad that it doesn't let you build structures that at once appear to be functional and are circular

11:51 dnolen: there's clearly a desire for more structured "beginner" Clojure material...

11:52 jcromartie: yeah

11:53 I like that these tuts start from the beginning

11:53 how about one written in Clojure, which compiles to HTML

11:53 that would just be a nice touch

12:04 and this tut starts with doseq, for, loop/recur... them moves on to map, reduce, filter, etc.

12:05 technomancy: edw: what is the problem specifically? basing it on a modulo of the current time seems equivalent to a random number

12:06 is it that your patch is limited to a higher range?

12:10 unless of course the random number generator hasn't been seeded?

12:15 anyway if I were to change the port number heuristic I would make it deterministic based on the path of the project

12:51 bsteuber: strange, on Mac OS I get a "Could not initialize class midje.sweet__init" when requiring midje, while on Linux the code ran just fine

12:52 technomancy: I blame the case-insensitive filesystem.

12:52 not because it makes sense, just because I hate it.

12:52 bsteuber: :)

12:54 it seems that only happens through checkouts

12:57 maybe because in one project it was in dependencies and in the other in dev-dependencies

12:57 anyways, works now :)

13:10 faust45: hi guy's

13:12 can anyone recommend cool book or article about Functional Programming?

13:12 to wrap my mind around

13:14 technomancy: clojurebot: google out of the tarpit

13:14 clojurebot: First, out of 44600 results is:

13:14 Out of the Tar Pit

13:14 http://citeseerx.ist.psu.edu/viewdoc/download?doi=

13:14 technomancy: my favourite FP article

13:19 faust45: technomancy: thanks will read it

13:20 technomancy: it's not terribly technical but provides great background

13:20 faust45: just reading book onLisp

13:21 technomancy: that's not really an FP book, is it?

13:22 faust45: technomancy: have a chapter "Functional Programming"

13:22 technomancy: author try explain FP way to write

13:23 coopernurse: technomancy: Out of the Tar Pit looks very interesting. thanks for the link

13:24 faust45: technomancy: but Out of the Tar Pit looks Theoretical, far from practice

13:25 dnolen: faust45: I recommend the SML books on Hickey's Amazon reading list, the most approachable and comprehensive I've çome across on FP programming.

13:26 faust45: dnolen: SML?

13:26 dnolen: faust45: Out of Tar Pit could use some more context, but it's based on practice not theory.

13:26 faust45: Standard ML

13:26 technomancy: dnolen: dang it man, you made me poke at my screen to try to get that little speck off it

13:26 derp__: I'm sorry, I asked this q yesterday but my machine shutoff for some reason, so I couldn't read any answers

13:26 here is my compiling/broken code: https://gist.github.com/1052284

13:26 dnolen: technomancy: heh oops.

13:26 derp__: and the error I get: https://gist.github.com/1052292

13:27 I think I'm doing everything right for calling a file, but I'm just not sure

13:27 faust45: dnolen: "Hickey's Amazon reading list" can you point me?

13:28 dnolen: faust45: http://www.amazon.com/Clojure-Bookshelf/lm/R3LG3ZBZS4GCTH

13:28 pretty much everything I've picked up off it is killer.

13:29 faust45: dnolen: pretty cool thanks!

13:30 dnolen: most practical, the only thing I've seen that's too mathematical for my tastes if Foundations of Databases

13:30 s/if/is

13:30 sexpbot: <dnolen> most practical, the only thing I've seen that's too mathematical for my tastes is Foundations of Databases

13:31 * dnolen prefers books which emphasize implementations

13:45 derp__: okay, I really don't get this, I am trying to use swank+slime, and it works somewhat. M-. works for core/contrib clojure functions, but for some reason isn't working for looking up functions local to the project

13:46 this isn't working for either my project or https://github.com/technomancy/mire, so I don't think it's just my poor code

13:46 poorly written*

13:47 hiredman: derp__: for M-. to work you have to compile the file first

13:49 edw: technomancy: ut?

13:50 technomancy: edw: sure

13:51 edw: technomancy: The problem with RANDOM is that it's pseudo-random and Emacs intentionally starts the generator with the same seed for every run, which means the clojure-jack-in while always attempt to connect to the same port of you open up a new emacs and invoke the command. Thus I was constantly getting port-in-use exceptions.

13:51 s/while/will/

13:51 sexpbot: <edw> technomancy: The problem with RANDOM is that it's pseudo-random and Emacs intentionally starts the generator with the same seed for every run, which means the clojure-jack-in will always attempt to connect to the same port of you open up a new emacs and invoke the command. Thus I was constantly getting port-in-use exceptions.

13:52 technomancy: edw: I see... I've seeded the random number generator in my dotfiles for so many years now that never occured to me

13:52 edw: technomancy: I didn't want to seed RANDOM because a user might not want it seeded.

13:52 technomancy: what do you think about making it deterministic based on the project path?

13:53 derp__: hiredman: so I have to run lein compile then run lein swank?

13:53 I thought slime/swank was interactive

13:53 edw: That's a toughie. I think that might work, as I think I want to know if I am already swanked into a project.

13:54 technomancy: edw: eh; actually I'm not too attached to that, and the current-time implementation has been written

13:54 so I'll take it

13:54 thanks

13:54 edw: OK. I've run into this before, but I always just tried again after giving a wtf?!-shrug.

13:54 And it would work...

13:54 hiredman: derp__: you have to load the file C-c C-k

13:55 technomancy: merge'd

13:55 edw: Cool. Thank you.

13:56 hiredman: derp__: loading clojure code is compiling it, what `lein compile` does is aot compilation

13:57 dnolen: rpglover64: I'm curious as to why you want to avoid using gen-class ? deftype just isn't designed to do what you want. gen-class is about interop, deftype is not.

13:57 rpglover64: But it seems like it's just one footstep away!

13:58 dnolen: rpglover64: but I don't see deftype getting changed to support what you want.

13:58 hiredman: rpglover64: what are you doing?

13:58 rpglover64: http://stackoverflow.com/questions/6515162/add-constructor-to-deftype-created-class

13:59 hiredman: use a factory

13:59 either a clojure fn as a factor or (deftype SomeTypeFactory [] (create-some-type [] ...))

13:59 factory

13:59 derp__: hiredman: thank you, that's working wonderfully. just out of curiosity, what's the 'apropos' command, so if I wanted to read about the doc/functionality of "C-c C-k"

14:00 hiredman: M-x describe-key maybe?

14:01 rpglover64: clojure fn as a factory won't work; the java code calling me will expect a java class with a nullary constructor

14:01 edw: jcromartie: Yes, clojure.

14:01 derp__: hiredman: thanks!

14:02 hiredman: rpglover64: this is for use with a library? what do you need fields for?

14:03 rpglover64: I'm using an intro to programming assignment to learn clojure

14:04 the assignment provides code for the graphical part that will call the code for the logic (that the student is supposed to write)

14:04 the way it does so is hacky

14:04 it expects to be passed a class (representing a game)

14:04 hiredman: so if it is a stupid exercise, don't do it

14:04 rpglover64: and will call its 0-ary constructor

14:05 it's not a stupid exercise

14:05 edw: rpglover64: This sounds a bit like the C++ source I took as a freshman back in '91, where the instructor was learning C++ along with us. A complete nightmare.

14:05 C++ course, that is.

14:06 hiredman: rpglover64: you just said it is `hacky`

14:06 rpglover64: edw: the instructor knows java quite well; and software engineering concepts; the issue is that his students don't, so he tried to make the interface as easy as possible

14:06 dnolen: rpglover64: deftype doesn't expose any user defined constructors much less a nullary one. if you used gen-class you'd be done already ;)

14:06 rpglover64: hiredman: (not= "hacky" "stupid")

14:07 hiredman: rpglover64: if an exercise makes you do things badly it is not a good exercise

14:07 rpglover64: dnolen: yes, but I won't have learned something very interesting

14:07 edw: rpglover64: Right, and my intructor knew C quite well. But you're in a Clojure course, not a Java course, right?

14:07 rpglover64: edw: i'm not in a course

14:07 bsod1: how can I stop vimclojure repl when it's in an infinite loop

14:07 derp__: I am still getting the same error about a function not existing

14:07 despite clean compilation using C-c C-k and lein uberjar

14:07 clojurebot: lein is http://github.com/technomancy/leiningen

14:08 edw: OK, then I'm completely confused.

14:08 hiredman: derp__: what same error?

14:08 jcromartie: anybody watched "The Last Language" from NDC by Uncle Bob?

14:08 rpglover64: hiredman: I don't expect that if I do use clojure for anything in the corporate world that the java code I work with avoids such stupid hacks

14:08 derp__: error: https://gist.github.com/1052292 code: https://gist.github.com/1052284

14:09 so that's two files in the code gist, but I put it in one to be simpler

14:09 they are both in the same src dir

14:09 hiredman: rpglover64: right, and if you really want to, you an use gen-class

14:09 rpglover64: or even use ASM directly to generate the code you want

14:09 rpglover64: hiredman: ASM = assembly?

14:10 bendlas: http://asm.ow2.org/

14:10 hiredman: rpglover64: deftype/reify/defrecord display better taste

14:10 asm is the bytecode generation library clojure uses

14:11 dnolen: rpglover64: rationale for not supporting user defined constructors in deftype is well covered here, http://jcip.net/

14:11 rpglover64: edw: my friend is teaching an intro programming (in java) course; the final assignment for the course is to implement the logic for a game, and he provided the pretty graphics code.

14:11 dnolen: oooh

14:11 * rpglover64 goes to read

14:11 dnolen: rpglover64: sadly the text of the book isn't at that location.

14:11 * rpglover64 is disappointed

14:11 hiredman: derp__: first off, using '_' in a namespace name is asking for trouble

14:12 dnolen: rpglover64: but a good chunk of Clojure's design philosophy lies therein.

14:12 hiredman: use '-' in the namespace name and '_' in the file/directory name

14:12 dnolen: rpglover64: great book and certainly worth having a physical copy, regardless of what language you actually program in.

14:13 derp__: hiredman: wait, what? so if you are create a file with multiple words in the title, how do you name it?

14:13 rpglover64: dnolen: I'll look into it

14:13 derp__: are you saying I should refer to my code as stupid-func within clojure, and name the file stupid_func_ns.clj?

14:13 hiredman: '-' is more lispy but '-' is not valid as part of a classname, field name, etc, so it gets mapped to '_', and to make clojure files correspond closely to the class files they would generate '_' is also used in place of '-'

14:14 dnolen: rpglover64: Concepts Techniques Models of Computer Programming cites it as the goto book for concurrent programming in imperative languages.

14:14 bendlas: hiredman: does windows have a problem with - in file names?

14:14 hiredman: bendlas: no idea, I suggest #windows

14:15 bendlas: what else would be the reason for the convention of using _ in files?

14:15 derp__: hiredman: so that seems pretty complicated, so you just use '-' and let clojure map it to underscores when needed? seems like camel caps would be easier at this point

14:15 hiredman: bendlas: I just gave the reason above

14:15 bsod1: how can I cast a list to a vector

14:15 hiredman: derp__: how is it not simple?

14:16 amalloy: bsod1: step 1, don't use the word cast for something that's not a cast. it will confuse you and everyone around you

14:16 &(vec '(a b c)) ;; step 2

14:16 sexpbot: ⟹ [a b c]

14:17 bsod1: amalloy: thanks. and sorry for `cast` :)

14:17 amalloy: so what's the proper word for it?

14:17 amalloy: (step three, really try to avoid doing it. if you need a vector, build it to begin with)

14:17 hiredman: "is there a function that takes a list and returns a vector?"

14:18 bendlas: bite my shiny metal ass

14:19 hiredman: amalloy: he must be talking to you

14:19 bendlas: I managed to do a whole mid-sized clojure project while staying convinced that 'src/foo-mod.clj' would be found by (require 'foo-mod) too ...

14:19 lol

14:20 thanks for clearing that up, hiredman

14:20 hiredman: ~namespaces

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

14:20 choffstein: Hey all. I keep running across a pattern where I need to map the values of a hash -- both with, and without knowing the key. I've pretty much just been using reduce, wrapped around an assoc, to reconstruct the hash. I found map-values in clojure.contrib.datalog.util, which I think solves my problem, but seems like it is in a pretty obscure place. Is there anything closer in the core library that solves my need?

14:20 derp__: hiredman: I still don't understand what you are saying. Can you just show a quick example, e.g. filename "hello_dir.clj" and then refer to it within clojure as "hello-dir.clj"?

14:20 hiredman: derp__: file names ahve '_' namespace names have '-'

14:20 have

14:21 jcromartie: choffstein: it should be easy to write your own

14:21 choffstein: jcromartie: I have written my own ... I was just wondering if there was already a pre-built solution :)

14:22 bendlas: choffstein: do you mean ,(map inc (vals {:first 31 :second 63 :third 127}))

14:22 jcromartie: it's a one-liner AFAIK

14:22 bendlas: ,(map inc (vals {:first 31 :second 63 :third 127}))

14:22 clojurebot: (32 64 128)

14:23 raek: derp__: when you eval (require 'aaa.bbb-ccc) Clojure will look for "aaa/bbb_ccc.clj" on the classpath

14:23 jcromartie: ,(into {} (map (fn [[k v]] [k (inc v)]) {:first 31 :second 63 :third 127}))

14:23 clojurebot: {:first 32, :second 64, :third 128}

14:23 choffstein: ah, interesting.

14:24 that is much cleaner than what I am doing :)

14:24 jcromartie: there are a million ways to do it :)

14:24 bendlas: or

14:24 ,(let [m {:first 31 :second 63 :third 127}]

14:24 (zipmap (keys m)

14:24 clojurebot: EOF while reading

14:24 bendlas: (map inc (vals m))))

14:25 dmn

14:25 (let [m {:first 31 :second 63 :third 127}] (zipmap (keys m) (map inc (vals m))))

14:25 derp__: last question: when I create a project, is the accepted nomenclature "my-project" or my_project"?

14:25 bendlas: ,(let [m {:first 31 :second 63 :third 127}] (zipmap (keys m) (map inc (vals m))))

14:25 clojurebot: {:third 128, :second 64, :first 32}

14:25 bendlas: sry for spam

14:25 jcromartie: BAN HIM

14:25 yeah I like the zipmap version

14:26 bendlas: clojurebot: Y U NO UNDERSTAND MULTI LINE INPUT?

14:26 clojurebot: trampoline is the clenched fist in the gauntlet of letfn

14:26 choffstein: ....

14:26 well played, clojurebot

14:26 * bendlas lols

14:26 choffstein: yeah ... zipmap is very sexy there

14:27 jcromartie: it shouldn't matter, but zipmap does mess up the order of keys

14:27 Scriptor: clojurebot has a markov chain builder?

14:28 choffstein: are you guaranteed that the order of (keys m) and (vals m) are the same? i.e. the first element in (keys m) is guaranteed to associate with the first element of (vals m)?

14:28 bsod1: is there a way to stop vimclojure REPL when it's stuck in an infinite loop

14:28 bendlas: choffstein: yes

14:28 choffstein: sweeet

14:28 bendlas: hashmaps have a canonical traversing order

14:28 jcromartie: choffstein: it shouldn't matter

14:29 choffstein: jcromartie: it would if you are doing the zipmap way, right?

14:29 jcromartie: both varieties return PersistentArrayMap

14:30 bendlas: yes, it would matter

14:30 choffstein: not sure I follow why that makes it not matter...

14:31 jcromartie: I mean that when printing the resulting map, the keys are in different order

14:31 the hash-map is correct

14:31 but it prints differently that's all

14:31 choffstein: oh, okay

14:33 jweiss_: is there a predicate that can differentiate between a function and a macro?

14:33 ifn? and fn? say true for both

14:34 technomancy: jweiss_: should be :macro metadata on the var

14:34 jweiss_: technomancy: coll thx

14:34 cool

14:34 technomancy: np

14:35 hiredman: and macros must be held by a var

14:36 jweiss_: hiredman: yeah these are all vars. i'm using a trace lib (hjlee's) and it keeps trying to trace macros and replacing them with vars that don't work.

14:37 it's using fn? so i'll 'and' in that metadata check

14:37 edw: Anyone here use redis with aleph? When a persistent connection has to re-connect, you lose authentication. I'm wondering how people deal with that.

14:38 hiredman: jweiss_: interesting, I wonder why they don't work

14:41 jweiss_: hiredman: i don't know, but when i call macroexpand-1 on my macro *after* i enable tracing on it, it doesn't expand. just returns what I passed to macroexpand.

14:41 disabling tracing doesn't fix it either.

14:42 hiredman: jweiss_: sounds like the trace is removing the :macro metadata

14:42 ok

14:42 my guess is usage of (with-meta …) instead of (vary-meta …)

14:42 *drumroll*

14:43 jweiss_: hiredman: perhaps you can spot the problem: http://clojure.googlegroups.com/web/trace_fn.clj

14:43 hiredman: I recommend using the trace from contrib

14:44 bendlas: jweiss_: you said fn? says true for a macro?

14:45 hiredman: yeah, the implementation of enable-trace is disgusting

14:45 do not use

14:45 bendlas: like in

14:45 ,(fn? #'let)

14:45 clojurebot: false

14:45 bendlas: ?

14:45 jweiss_: hiredman, the trace from contrib is not a replacement for defn like it says.

14:45 hiredman: (type #'let)

14:45 ,(type #'let)

14:45 clojurebot: clojure.lang.Var

14:45 jweiss_: ,(fn? (deref #'let))

14:45 clojurebot: true

14:45 hiredman: not a fn

14:46 bendlas: you can deref a macro var w/o having the compiler scream?

14:46 jweiss_: hiredman: contrib's deftrace doesn't allow docstrings

14:46 bendlas: that's new

14:46 (to me)

14:46 jweiss_: or anything defn does that fn doesn't

14:47 hiredman: jweiss_: https://gist.github.com/1054566

14:48 but the implementation is icky, using a seperate map of traced fns is dumb

14:48 should just use var metadata

14:48 jcromartie: ,@#'for

14:48 clojurebot: #<core$for clojure.core$for@7f3159>

14:49 hiredman: ^- assumes key is a namespace qualified symbol, I didn't check

14:49 jweiss_: hiredman: ok, i think i'm better off fixing up this lib because i don't have to alter my existing code. with contrib.trace I do, pretty severely

14:49 jcromartie: ,for

14:49 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/for

14:49 amalloy: bendlas: the var just holds a function; the metadata on the var is what tells the compiler to treat it as a macro. so if you explicitly deref the var, then what you get back is a plain old function

14:50 jweiss_: hiredman: var metadata to hold the original fn?

14:50 dnolen: STM for PyPy ?

14:50 http://morepypy.blogspot.com/2011/06/global-interpreter-lock-or-how-to-kill.html

14:50 hiredman: jweiss_: yes, I would checkout robert.hooke

14:50 ~hooke

14:50 clojurebot: Titim gan éirí ort.

14:50 amalloy: &(#'and true false)

14:50 sexpbot: ⟹ true

14:50 hiredman: clojurebot: jark

14:50 clojurebot: jark is a clojure daemon for scripting: http://icylisper.in/jark/

14:50 bendlas: amalloy: got it. That's kinda cool

14:50 hiredman: bleh

14:50 ~robert hooke

14:50 clojurebot: excusez-moi

14:51 hiredman: ~google robert.hooke clojure

14:51 clojurebot: First, out of 60 results is:

14:51 Help with Debian packaging - leiningen | Google Groups

14:51 http://groups.google.com/group/leiningen/browse_thread/thread/45dc4c878cd24fc8

14:51 hiredman: ugh

14:51 amalloy: hiredman: foiled again

14:51 hiredman: https://github.com/technomancy/robert-hooke

14:52 clojureot: hooke is <reply> https://github.com/technomancy/robert-hooke

14:52 jweiss_: hiredman: ah, i've heard that lib mentioned before, never knew what it was. now i'll get a chance to try it. thanks

14:53 hiredman: clojurebot: hooke is <reply> https://github.com/technomancy/robert-hooke

14:53 clojurebot: 'Sea, mhuise.

14:53 bendlas: yes, I have been noticing that google doesn't rate gh-pages of clojure libs very well

14:53 dnolen: though it's not clear to me how they'll make it as efficient as Clojure's STM w/o refs and fast persistent datatypes ...

14:54 hiredman: dnolen: yes, and the comments are *sigh* inducing

14:55 "What happens when transaction interleaves together and fail? "

15:11 coopernurse: there seems a certain irony in debugging a Java deadlock whilst reading the Out of the Tarpit PDF in another window

15:15 JohnnyL: coopernurse: Funny, I know a nurse whose last name is Cooper. :)

15:19 coopernurse: heh.. tis not m

15:19 me

15:38 jcromartie: coopernurse: hah awesome

15:38 coopernurse: I've wondered about implementing OotT's recommendations

15:38 I think everybody that has read it wonders the same thing

15:38 how do you actually do it... where does the rubber meet the road?

15:38 especially when it comes to persistence with existing RDBMS

15:38 coopernurse: yes, as is probably evident by my dumb questions here, I'm new to FP

15:39 jcromartie: do you let the storage be "dumb" or what?

15:39 coopernurse: but I find the promises seductive

15:39 jcromartie: absolutely

15:39 there's also the more OOP-oriented Domain Driven Design school of thought

15:39 it's close to FRP

15:39 except wrapped up in objects

15:40 coopernurse: interesting.. I've looked at DDD

15:40 it looked like a lot of indirection

15:40 I haven't gotten to the punchline yet in OotT

15:40 so I don't know all their suggestions yet

15:41 jcromartie: I think some DDD concepts map to FRP. DDD invariants -> FRP logic layer; DDD Entities and Commands -> FRP essential state

15:41 amalloy: it sounds like you guys are more into Acronym-Driven Design

15:42 jcromartie: bah

15:42 coopernurse: well, I'm open to any approach that will help me understand the system I'm building and keep the cost of change low

15:50 S11001001: data display debugger?

16:24 jweiss_: technomancy: remove-hook in robert.hook doesn't seem to work for me the way it seems to in the unit test. i still see the hook in the meta, but with-hooks-disabled says there are no hooks

16:29 fliebel: What is the name of that Clojure graph database and query dsl?

16:29 (two different things I think)

16:30 mids: jiraph?

16:31 fliebel: mids: I guess...

16:32 mids: also neo4j is pretty cool and has clojure bindings

16:32 fliebel: mids: 5 of them even ;)

16:32 mids: heh

16:32 amalloy: fliebel: query dsl is plasma, i think you mean

16:34 fliebel: amalloy: Bingo!

16:35 technomancy: jweiss_: could be; remove-hook hasn't ever been used outside the test suite to my knowledge

16:46 jweiss_: technomancy: i'm not sure how it works anywhere, the :robert.hooke/hook atom contains a cons. calling (remove #{f} ...) on it doesn't seem to have any effect

16:49 hiredman: jweiss_: there are issues with function identity

16:49 amalloy: &(= first (with-meta {:x 1} first))

16:49 sexpbot: java.lang.ClassCastException: clojure.core$first cannot be cast to clojure.lang.IPersistentMap

16:49 jweiss_: hiredman: yeah, i see that. = returns true, but remove doesn't work

16:49 amalloy: &(= first (with-meta first {:x 1}))

16:49 sexpbot: ⟹ false

16:49 bsod1: can anyone help me? when I run (source println) I get this exception: #<CompilerException java.lang.Exception: Unable to resolve symbol: source in this context (REPL:28)>

16:50 amalloy: (use '[clojure.repl :only [source]])

16:50 jweiss_: i'm not sure i buy that. if = returns true, remove will work

16:50 well. (remove (partial = f) ...) will work, anyway. (remove #{f} ...) can in certain cases have problems, but i don't think this is one of them

16:53 hiredman: bsod1: https://github.com/clojure/clojure/blob/master/src/clj/clojure/main.clj#L258

16:54 code in the repl will behave differently from code run outside of the repl

16:54 bsod1: hiredman: great, thanks

16:55 jweiss_: amalloy: hm... well it doesn't work. not sure why

16:55 hiredman: ,(= (fn []) (fn []))

16:55 clojurebot: false

16:56 hiredman: ^- the issue, if you have recompiled since the hook was added you will be unable to remove the hook

16:59 derp__: okay I am so stuck on figuring out how to create a basic project with a main calling functions from another namespace.

16:59 here's my umpteenth try: https://gist.github.com/1054944

17:03 S11001001: jweiss_: I think top-level vars are merely updated

17:04 jweiss_: S11001001: not sure what you mean

17:04 hiredman: S11001001: there are no other kinds of var

17:04 S11001001: hiredman: ah, right :)

17:06 jweiss_: assuming the hook is defined in a var, you could pass in the var instead of the function

17:21 hugod: derp__: you need to use gen-class and aot compile sample-proj.start for that to work, I believe

17:23 you might have more luck with lein run if you just want to run something outside of a repl

17:25 derp__: hugod: wow, it works with lein run! But why is that, and what do I have

17:25 what exactly do you mean by gen-class and aot compile?

17:27 has gen-class changed much recently, or can I use a blog post from a year ago or so to figure it out?

17:29 hugod: derp__: http://clojure.org/compilation

17:30 AWizzArd: Protocol dispatching: most concrete wins?

17:31 most concrete type

17:31 dnolen: AWizzArd: no

17:31 AWizzArd: k

17:31 dnolen: there's no way to know which will win.

17:32 AWizzArd: Can I somehow specify then: for types A, B, C and D use this implementation i1, and for class E take i2?

17:32 dnolen: and in fact it will probably change between JVMs or even JVM runs.

17:32 hugod: derp__: and :aot in https://github.com/technomancy/leiningen/blob/master/sample.project.clj

17:32 AWizzArd: Currently I only implemented the supertype of a, b, c and d

17:32 dnolen: AWizzArd: you cannot prefer as you can with multimethod.

17:33 mrfaison: hi folks! a very basic tutorial for clojure for a java programmer?

17:33 AWizzArd: Yes okay I see, so I will better list explicitly a, b, c and d instead of just implementing it for their superclass.

17:33 dnolen: AWizzArd: yup.

17:33 AWizzArd: So, when I then (foo e-instance) it can not take those.

17:33 Now my question is: if the implementation for a-d is identical, can I then specify this nicely?

17:33 Or will I have to copy/paste the body 3x?

17:34 extend-protocol looks good, only that it expects a type and then the concrete implementation.

17:34 dnolen: AWizzArd: copy/paste or macros. fn maps are currently possible but it sounds like they may go away to allow protocols to sit at the foundation.

17:35 AWizzArd: Okay, be it copy/paste for now. Thanks.

17:35 fliebel: dnolen: As I understood it, only generated maps will go away, in favor of literal maps, so you can still share fn definitions.

17:36 technomancy: is there an easy way to block till all running threads finish?

17:36 derp__: hugod: thank you so much! your suggestions really helped

17:36 dnolen: fliebel: ah I didn't catch that.

17:37 pjstadig: technomancy: doesn't that automatically happen for non-daemon threads when you fall off the end of the main method?

17:37 AWizzArd: What surprised me: I have the type X which has the subtypes A-E. I extended X with implementation i1 and then explicitly E with i2. But it seems it still chose i1 for my call with an E instance.

17:43 technomancy: pjstadig: yeah. I want to do it earlier

17:43 http://p.hagelb.org/shutdown-agents.jpg

17:44 joegallo: ^^

17:44 pjstadig: technomancy: and you mean all running threads, not just like the agent pool

17:44 technomancy: right

17:44 but in this case actually I think I can pick out a single one to block on

17:44 pjstadig: you can enumerate a list of threads from a threadgroup and join them all in turn

17:45 technomancy: pjstadig: yeah, threadgroups ridiculously don't seem to implement any enumerable kind of interfaces

17:45 joegallo: technomancy: hehehehe

17:45 pjstadig: they do have a very convenient enumerate method though

17:46 FSVO convenient

17:46 technomancy: pjstadig: "here's an array bro, could ya populate it for me"

17:46 for very low values of "convenient"

17:46 pjstadig: "by the way how big should the array be"

17:46 technomancy: borders on self-parody

17:49 dnolen: AWizzArd: rhickey thoughts on the matter, http://groups.google.com/group/clojure-dev/msg/2dbd690c7b509b63

18:02 symbole: Is there a way to monkey patch or proxy a Java object?

18:03 hiredman: yes

18:03 amalloy: i guess it depends what you mean by proxy? you certainly can't monkey-patch it

18:04 hiredman: http://www.manning.com/forman/ is a neat book, it will tell you how

18:07 symbole: hiredman: Hmm, I haven't really thought about reflection. I need to create an InputStream and modify one of its methods (close). Right now, I have a function that accepts and InputStream and returns a proxy which closes over the stream. Example, (fn [s] (proxy [InputStream] [] (close [] (foo s)))).

18:07 s/and/an

18:07 sexpbot: <symbole> hiredman: Hmm, I haven't really thought about reflection. I need to create an InputStream an modify one of its methods (close). Right now, I have a function that accepts an InputStream an returns a proxy which closes over the stream. Example, (fn [s] (proxy [InputStream] [] (close [] (foo s)))).

18:07 symbole: Oops.

18:07 hiredman: ~jdoc java.io.FilterInputStream

18:07 clojurebot: filter doesn't stop

18:07 hiredman: clojurebot: jerk

18:07 clojurebot: Pardon?

18:08 hiredman: symbole: close is not a method of inputstream

18:08 amalloy: http://download.oracle.com/javase/1.4.2/docs/api/java/io/InputStream.html#close()

18:10 hugod: btw thanks for telling me i can use swank to recompile code that's part of a separate library. it seems obvious if i'd ever thought about it, but it just seemed impossible. so much easier this way

18:11 hiredman: amalloy: be sure to check the docs for java6

18:11 http://download.oracle.com/javase/6/docs/api/java/io/Closeable.html#close%28%29

18:12 amalloy: hiredman: yeah, i know 6 is more accurate, but nobody's going to remove close() from InputStream

18:12 hiredman: amalloy: but it comes from Closeable

18:12 amalloy: so there's a new Closeable interface in 1.5, but InputStream still implements it and it's still a method of InputStream

18:13 http://download.oracle.com/javase/6/docs/api/java/io/InputStream.html#close%28%29 - i'm not sure what you mean by "not a method of inputstream", if this isn't a counterexample

18:15 hiredman: ,(reify java.io.InputStream (close []))

18:15 clojurebot: java.lang.IllegalArgumentException: only interfaces are supported, had: java.io.InputStream

18:15 hiredman: oh right

18:15 java.io sucks

18:15 amalloy: ,(proxy [java.io.FileInputStream] [] (close []))

18:15 clojurebot: java.lang.IllegalStateException: Var null/null is unbound.

18:15 hiredman: how easy it is to forget

18:15 amalloy: haha yes

18:17 ,(proxy [java.io.ByteArrayInputStream] [(byte-array 10)] (close []))

18:17 clojurebot: java.lang.IllegalStateException: Var null/null is unbound.

18:17 symbole: So I take it there's no straight forward way to monkey patch? Is proxy the easiest way?

18:18 amalloy: &(proxy [java.io.ByteArrayInputStream] [(byte-array 10)] (close []))

18:18 sexpbot: java.lang.IllegalStateException: Var null/null is unbound.

18:18 amalloy: hiredman: what's with that null/null thing? it prints fine in my repl but sexpbot and clojurebot both die

18:19 hiredman: amalloy: not sure

18:20 that must be anonymous var in the compiler

18:20 ,(clojure.lang.Var/create nil)

18:20 amalloy: ah, that makes sense

18:20 clojurebot: #<Var: --unnamed-->

18:21 hiredman: ooo

18:21 amalloy: ,@(with-local-vars [a 1] a)

18:21 clojurebot: java.lang.IllegalStateException: Var null/null is unbound.

18:31 tufflax: I got a stackoverflowerror, but the trace doesn't mention any file of mine. How can I find out where it originated? It just goes on and on like this http://pastebin.com/R7JtWsmZ

18:33 amalloy: tufflax: well, you're probably callling map in a reduce or a loop/recur

18:33 tufflax: ok

18:34 amalloy: but i would be surprised if none of your code appeared in the trace at all? it should be in a caused-by or something

18:37 tufflax: for example, (first (reduce #(filter #{%2} %) nil (range 1e4)))

18:37 tufflax: it does not, i copied all i got which was like a 1000 lines and searched with a regexp

18:37 amalloy: blows the stack instantly for me, with a trace that looks like yours

18:40 and indeed, none of my code appears in the trace. now that i've actually tried it, that makes sense

18:46 tufflax: amalloy: why does that code blow the stack?

18:46 amalloy: $google clojure stackoverflow dbyrne sieve prime lazy

18:46 sexpbot: First out of 1 results is: recursion - Recursive function causing a stack overflow - Stack ...

18:46 http://stackoverflow.com/questions/2946764/recursive-function-causing-a-stack-overflow

18:55 tufflax: Ah, now I get it :p thanks. Hm, so I guess ill go hunting for such patterns in my code :p

20:12 nick_: hello

20:13 mudge: hi nick_

20:13 I'm going to be doing some web programming in clojure and I'm wondering what html library I should use

20:13 maybe hiccup

20:14 but I wonder if anyone has been having fun playing with other stuff

20:15 what's your favorite html librarie?

20:15 anybody used enlive?

20:17 anybody want to chat about clojure?

20:19 Evious: I'd like to chat about clojure's syntax.

20:19 bendlas: mudge: enlive is great

20:19 i'd recommend it

20:20 mudge: bendlas: cool, I'm readin a tutorial about it now: https://github.com/swannodette/enlive-tutorial/

20:20 I really have no idea about it yet

20:20 bendlas: have you used hiccup?

20:20 bendlas: yes

20:20 mudge: how are they different?

20:21 bendlas: hiccup generates html from clojure data structures

20:21 that means coding html in lisp syntax

20:22 enlive OTOH parses plain html templates

20:22 i.e. the stuff you get from a webdesigner

20:22 mudge: yes, mm kay

20:22 bendlas: you write transformation rules with css-like selectors

20:23 mudge: bendlas: sounds neat

20:23 bendlas: and you can use the same syntax to grab websites

20:24 it is

20:24 mudge: bendlas: do you recommend any tutorials or resources for learning enlive?

20:25 bortreb: I have some C code I'm calling through a java JNI interface, and of course, you have to do manual memory management with the java object. I'd like to use the with-open macro from clojure.core to take care of this, but the memory-freeing function is called .deleteLP instead of .close. What is the "right" thing to do in this case?

20:27 mudge: bendlas: i am reading and getting excited about enlive

20:27 amalloy: bortreb: nothing is "right". i'd probably copy the code for with-open and make it call .deleteLP

20:27 bendlas: mudge: the enlive syntax file is an essential ref

20:28 amalloy: but you could instead do something like (let [r (jni-stuff)] (with-open [r* (reify Closeable (close[this] (.deleteLP r)))] ...))

20:28 bortreb: is there a macro in core that allows one to specify the "closing function", shoule I make my own with-my-garbage-non-standsard-c-stuff macro, or can I use protocols and extend type to make my java wrapper (which I don't control) extend Closeable? OR, should I make my own wrapper object?

20:28 ah -- that's it

20:28 thank you amalloy

20:30 dnolen: Evious: what about?

20:30 bortreb: I didn't think about creating a nameless manager object to handle closing down my wrapper object

20:30 that's slick

20:31 bendlas: mudge: TBH i've learned it mostly from the README and linked resources

20:32 Evious: dnolen, I'm trying to use lisp on an obscure functional VM, and am writing utility macros to make it more usable and friendly. I'm not sure what good Lisp style is - and Clojure seems more functional than CL, and prettier than Scheme, so I'm trying to steal ideas from it.

20:32 mudge: bendlas: okay, thanks

20:33 dnolen: Evious: curious, what obscure functional VM ? and what lisp?

20:33 Evious: Lisp flavored Erlang.

20:34 * technomancy still can't believe LFE is a lisp-2

20:34 Evious: I notice that Clojure functions wrap individual arg-body clauses in expressions. But (let [n1 b1 n2 b2] body) doesn't. Is this an inconsistency, or is there some subtle motivation behind it?

20:34 Or does that stuff simply not matter.

20:34 amalloy: Evious: wrap them in expressions?

20:35 hiredman: Evious: https://github.com/dysinger/lfesl might be useful

20:35 Evious: hiredman, seen it, don't think it's idiomatic Erlang, writing my own :)

20:35 bortreb: @Evious I think that it's because a let has only one body, while functions can have more than one body.

20:35 Evious: amalloy, ([] 1) as opposed to just [] 1 in http://clojure.org/special_forms#Special%20Forms--(fn%20name?%20(%5Bparams*%20%5D%20exprs*)+)

20:36 amalloy: Evious: that's only needed when there are multiple bodies

20:36 Evious: Ah. So if functions had only one body (as they generally do in languages that really, really shun side effects) the (let ...) approach makes more sense.

20:36 hiredman: clojure doesn't erlang guards

20:36 Evious: Guards all start with (when ...) so that's okay.

20:36 hiredman: doesn't have

20:36 bortreb: @Evious and if the function only has one body you can dispense with the extra parenthesis

20:36 amalloy: Evious: you mean, if each body had only one expression

20:37 Evious: That would be a more correct way of saying it, yes.

20:37 Doesn't the let syntax break auto-indentation, though?

20:37 hiredman: how so?

20:38 dnolen: Evious: it does not.

20:38 hiredman: (let [bindings] body) is very regular, easy to parse and indent

20:38 amalloy: Evious: sure, it means that in (let [x<newline>expr]), x and expr line up instead of expr being indented

20:38 Evious: Bindings is an even-length list, indented in sets of two, right?

20:38 amalloy: but usually you don't put a newline after x

20:39 Evious: Excellent, looks like I was worrying about auto-indentation needlessly :)

20:39 The square brackets - are they purely convention, or do they have different semantics?

20:39 amalloy: very different

20:39 ibdknox: they're a different datastructure

20:39 amalloy: well. very is a strong word, i guess

20:39 but they denote vectors

20:40 Evious: Ah. So let takes a vector of bindings, not a list.

20:40 amalloy: &(let (x 1) x)

20:40 sexpbot: java.lang.IllegalArgumentException: let requires a vector for its binding

20:40 ibdknox: I believe all binding forms are vectors, right?

20:40 pcavs_: ,(let [x 1 y 2] x)

20:40 clojurebot: 1

20:40 joegallo: somewhere i read that () is mostly used for execution context, but [] is mostly used for definition context, and that seemed to hold true for me -- but yes, also the definition of a literal list versus a literal vector

20:40 amalloy: ibdknox: yes, but of course that's convention. you could write a binding-creating macro that accepts non-vector forms and converts them to vectors for let

20:41 ibdknox: amalloy: yeah, I was just making sure there wasn't something obscure I didn't know about

20:41 bendlas: Evious: in clojure syntax, by convention, lists are used when the first element has a special meaning, vectors are used else

20:42 Evious: I see.

20:42 dnolen: Evious: it's mostly a aesthetics thing. the vector requirement is enforced by the let macro, not by the actual let* special form.

20:43 amalloy: dnolen: oh, i didn't know that. neat. lemme try it! ##(let* (x 1) x)

20:43 sexpbot: java.lang.IllegalArgumentException: Bad binding form, expected vector

20:43 Evious: Syntax = brackets and atoms, expression = a set of matching brackets containing atoms or expressions, and form = the shape and structure of an expression? (Is (let [...] ...) syntax, or a form?)

20:43 dnolen: amalloy: huh, I guess reinforced again by let* ?

20:44 amalloy: Evious: uh. is happiness a word or an idea?

20:44 bendlas: speaking of that makes me wonder why we don't use maps for syntactic positions where groups of two are expected

20:44 dnolen: amalloy: yeah enforced by the Parser.

20:44 bendlas: like in bindings

20:44 Evious: People yell at me for misusing words all the time, I don't want to call stuff "syntax" in documentation and then turn out blatantly wrong :)

20:44 amalloy: bendlas: they don't guarantee order

20:45 bendlas: hmm :/

20:45 ibdknox: bendlas: I thought the same thing at first lol

20:45 bendlas: also wouldn't be to easy on the eyes

20:45 s/to/too

20:45 sexpbot: <bendlas> also wouldn't be too easy on the eyes

20:46 Evious: Where can I find documentation on let* and other low level primitives?

20:46 ibdknox: dnolen: in terms of the enforcement, I think that's actually a good thing

20:46 dnolen: ibdknox: for sure.

20:46 Evious: And one last question: is it possible to learn and understand Clojure, without learning a thing about Java?

20:46 bendlas: Evious: no

20:47 dnolen: Evious: there's a page on special forms on clojure.org

20:47 amalloy: yes and no

20:47 ibdknox: I think you can

20:47 amalloy: clojure the language stands on its own without the . special form

20:47 Evious: dnolen, it only covers (let ...) though, and someone mentioned let*

20:48 amalloy: but it's missing a lot of functions that you'd expect from a real language, because you can use java built-ins instead

20:48 technomancy: Evious: you don't need to learn how to write in the Java programming language. you do need to learn how to interact with certain java classes and libraries.

20:48 bendlas: ok, it's depending on the real-worldness of the problems you're dealing with

20:48 dnolen: Evious: you can get pretty far along, but there are certain bits you really must understand - i.e. classpath

20:48 Evious: Cool.

20:48 dnolen: Evious: if you writing high performance stuff you'll need to expand your knowledge of Java as well.

20:48 amalloy: Evious: "real" special forms are poorly documented. the best i've found is by reading the source of the compiler; they're all listed in once place

20:48 Evious: Is that due to clojure focusing on immutability more than Java?

20:49 ibdknox: dnolen: are you talking primarily about type hints?

20:49 dnolen: Evious: idiomatic Clojure is "fast enough" faring better than other dynamic langs. But if you want to write something like PersistentVector you going need to know something about Java.

20:49 ibdknox: no.

20:50 bendlas: you need to know java to make head and tails of clojure stacktraces

20:50 ibdknox: bendlas: haha and a prayer ;)

20:50 Evious: bendlas, awesome, that's the answer I was looking to find :D

20:50 dnolen: bendlas: heh, I think the stacktraces get a bit of bad rap, I don't have much trouble w/ them these days.

20:51 bendlas: dnolen: do you know java?

20:51 ibdknox: for the most part I agree

20:51 dnolen: bendlas: not well.

20:51 ibdknox: there are still some really crap traces though

20:51 bendlas: dnolen: interesting ..

20:51 ibdknox: yeah, ever mistyped an (ns ..) clause?

20:52 ibdknox: bendlas: oh man, yes

20:52 bendlas: * cannot be cast to ISeq is really notorious

20:52 ibdknox: my first time with Clojure I did something stupid like that

20:52 took me an hour to figure out what the hell was going on

20:53 seancorfield: amalloy: could you point me at where in the clojure compiler source the special forms are listed? just curious

20:53 even an approximate pointer would be enough, tx

20:53 dnolen: bendlas: ibdknox: yeah, those kinds of things don't burn me much anymore. and honestly aren't much worse than my experience with certain classes of cryptic errors in other langs.

20:53 amalloy: seancorfield: just search LispReader.java for "deftype*"

20:53 seancorfield: thanx!

20:54 bendlas: dnolen: true, but in clojure they lurk in such basic functionality as clojure.core/ns

20:55 hiredman: amalloy: LispReader?

20:55 bendlas: can't really tell a beginner not to use it ;)

20:55 amalloy: hiredman: am i wrong, and it's Compiler?

20:55 hiredman: seancorfield: I think he meant Compiler.java

20:55 amalloy: i forget which is where

20:56 good save

20:56 ibdknox: dnolen: also true, it's been a while since I've run into something that really stumped me

20:56 seancorfield: the opcodes list? hiredman amalloy

20:58 ibdknox: seancorfield: line 5716 has the definition for the let form

20:58 as an example

20:58 dnolen: any continuation passing style gurus here, can this be reduced of written better? https://gist.github.com/1055402

20:58 s/of/or

20:58 sexpbot: <dnolen> any continuation passing style gurus here, can this be reduced or written better? https://gist.github.com/1055402

20:58 amalloy: seancorfield: yes, that's the list. they aren't all really special forms (eg clojure.core/list), but they're used often enough by the compiler that you can probably guess

20:59 hiredman: dnolen: looks backwards?

20:59 seancorfield: line 101: static final public IPersistentMap specials = PersistentHashMap.create(

20:59 hiredman: ^-

21:00 mudge: (hn-headlines)

21:00 oops, this is not my repl

21:00 seancorfield: thanx amalloy etc

21:00 loop and let have the same parser... nice :)

21:01 hiredman: dnolen: is the returning of the single argument fn part of the cps? generally for cps you don't return anything

21:03 ibdknox: mudge: what are you doing with the HN headlines? :)

21:03 assuming hn = hackernews

21:05 mudge: ibdknox: i am following the Enlive tutorial: https://github.com/swannodette/enlive-tutorial/

21:07 ibdknox: ah :)

21:08 Penten: /#scheme

21:10 dnolen: hiredman: hmm, yeah, in this case I want to be able to add something to the computation later.

21:18 tomoj: huh, a function named f| works in clojure but breaks in the slime repl

21:18 amalloy: tomoj: | has special meaning in CL, and the slime parser treats it as such

21:18 tomoj: wonder if there is a special key for "just send this damn string"

21:19 amalloy: C-ret?

21:19 failing that, i know C-u ret works

21:19 tomoj: huh

21:19 heh

21:20 it works, but the return values is printed immediately after the closing paren of the input, then a newline and a bolded prompt

21:20 that prompt works normally and the next is back to unbolded

21:20 wastrel: hello friends

21:20 tomoj: bizarre

21:24 you can have vars like %foo, but then you can't use them inside #()...

21:45 amalloy: tomoj: yeah, i don't love how the lexer treats %

21:45 &(#(inc%) 2)

21:45 sexpbot: ⟹ 3

21:45 amalloy: ie, they seem to be single-character tokens except when the next character is a number

21:46 &(#(+ 3%) 2)

21:46 sexpbot: ⟹ 5

21:49 ask_me: hi

21:49 i'm thinking a bit about bok about clojure

21:50 Programming Clojure By Stuart Halloway OR Practical Clojure By Luke Van der Hart OR The Joy of Clojure: Thinking the Clojure Way By Michael Fogus, Chris Houser

21:50 which one is the best for the begginer?

21:50 only these i may buy

21:51 technomancy: any last-minute things to address before leiningen 1.6 is released?

21:53 ask_me: anyone?

21:53 clojurebot: Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help.

21:56 * technomancy liked halloway's as a beginner

21:57 technomancy: but you'll want to buy the Joy of Clojure eventually

21:57 for sure

22:11 seancorfield: Clojure Programming by Chas Emerick, Brian Casper and Christophe Grand is really good IMO

22:11 but, yes, Joy of Clojure is a "must have" once you're beyond the basics

22:12 I have JoC, Clojure in Action and Clojure Programming all on my iPad / iPhone / desktop / netbook and enjoy reading (and re-reading) all of them

22:12 technomancy: clojurebot: peepcode

22:12 clojurebot: peepcode is a commercial screencast series; see the Clojure one at http://peepcode.com/products/functional-programming-with-clojure by technomancy

22:12 * technomancy coughs discreetly

22:13 seancorfield: stu's book is a bit out of date... is he doing a 2nd ed?

22:17 technomancy: it doesn't cover deftype &c, but it's debatable whether that belongs in an introductory text anyway

22:17 I think the only actual breakage revolves around ^ as meta

22:43 seancorfield: does chris redinger hang out here? i want to contact him about the clojure success stories page...

22:43 ah, there he is: redinger ...

22:44 hmm, idle for a week

22:51 mudge: exit

22:51 quite

22:51 quit

22:51 can't get out of my irc client

22:54 amalloy: today has been an exciting day for people typing the wrong things into #clojure

23:20 bpr: quick question: is the behavior of hash shown in this paste by design? https://gist.github.com/1055556

23:24 hiredman: bpr: arrays are mutable so hashing different arrays with the same values to the same thing is a bad idea

23:24 bpr: ok, that's sensible

23:38 amalloy: bpr: i'd also make the point that there's no reason for clojure to treat arrays specially when java doesn't: (hash some-array) just returns (.hashCode some-array)

23:42 technomancy: leiningen 1.6.0 released

23:42 lein update away

23:42 now with search magic

23:42 hiredman: yay!

23:42 pcavs_: technomancy: ooh, sounds cool

23:42 coopernurse: cool, updating now

23:43 pcavs_: wait, don't you mean upgrade?

23:43 technomancy: pcavs_: ah, you are correct.

23:43 pcavs_: w/e weenie question/point

23:44 Raynes: technomancy: Clojars search stuff?

23:44 technomancy: Raynes: search for any remote repo that publishes indices

23:44 clojars, maven central. sonatype, etc.

23:45 Raynes: Neat.

23:45 cake can search clojars, but that's about it. I took that stuff from cljr.

23:46 I'll check out your stuff when I get some time.

23:46 technomancy: sure, it's just basic lucene

23:46 hopefully I can integrate it into the clojars web app soon

23:46 coopernurse: trying out the search now

23:47 seancorfield: technomancy: i get an exception on lein test now

23:47 Exception in thread "main" java.lang.NullPointerException

23:47 at clojure.core$deref.invoke(core.clj:2078)

23:47 at leiningen.util.injected$run_hooks.invoke(NO_SOURCE_FILE:1)

23:47 at leiningen.util.injected$prepare_for_hooks$fn__14$runner__15.doInvoke(NO_SOURCE_FILE:1)

23:47 at clojure.lang.RestFn.applyTo(RestFn.java:137)

23:47 just upgraded to 1.6.0 :)

23:48 any info i can provide to help debug that?

23:50 looks like a problem with 1.3 compatibility

23:50 technomancy: seancorfield: using test selectors?

23:51 seancorfield: nope, bare bones 1.3.0 clojure project

23:51 let me do a clean test

23:52 yup, lein new test13; cd test13; vi project.clj ;; change clojure version to 1.3.0-beta1; lein clean, deps, test

23:52 fails with that exception on test task

23:53 technomancy: the heck; it's failing derefing an atom

23:54 seancorfield: at least the failure is easy to repro :)

23:56 technomancy: I don't think this is a lein bug

23:56 seancorfield: lein 1.5.0 works, lein 1.6.0 fails :)

23:57 technomancy: yeah, with-meta is just failing to attach metadata to a function

Logging service provided by n01se.net