#clojure log - Feb 02 2011

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

2:00 amalloy: ieure: i ran into an issue with php-repl when trying to use it for anything complex

2:01 eg, foreach (range(0,10) as $x) {echo $x;}

2:01 doesn't work because you're doing eval('return foreach (...) {...};')

2:02 i can fix this by writing function f() {...} followed by f(), but yuck

2:05 chouser: the javascript generated by clojurescript has a somewhat startling number of anonymous inner functions.

2:05 and now, to bed.

2:07 amalloy: chouser: startling? i'd expect one for every lexical scope at least

2:08 ieure: amalloy, I haven’t touched PHP or that code in a couple years. If it’s a big issue for you, I’ll lean into it, though.

2:08 amalloy: ieure: don't bother yourself about it yet. i'll fork it on github and take a look; if it's unexpectedly complicated i'll let you know

2:24 fliebel: morning

2:26 hoeck: morning

2:31 amalloy: morning fliebel

2:33 fliebel: amalloy: did tonyl finish his code yet?

2:33 ieure: amalloy, sounds good.

2:33 amalloy: fliebel: if so he didn't tell me

2:33 fliebel: okay

2:36 did you show him the php code?

2:38 amalloy: fliebel: no, didn't think of it

3:04 but now it's bedtime for me, so you'll have to link him if he shows up, fliebel :P

3:06 fliebel: amalloy_: good night :)

4:19 Licenser: aloa

4:39 mduerksen: ,(let [v2scale (fn [s [a b :as v]] (assoc v 0 (* a s) 1 (* b s)))] (time (dotimes [n 1000000] (v2scale 0.2 [2 2]))))

4:39 clojurebot: "Elapsed time: 1895.93 msecs"

4:40 mduerksen: this is the fastest fn i could up with. any suggestions?

4:42 unchecked-math isn't a great improvement in this case, it's share in the overall execution time is quite small

5:46 MrHus: , (= 1 -1)

5:46 clojurebot: false

6:58 clgv: I am curious if anyone tried to build a Clojure DSL for Latex to get rid of some in inadequateness of it...

7:40 bartj: I have a bunch of extremely ugly code to write

7:41 but, I think Clojure will have an "elegant" way of writing it

7:41 here is the task:

7:41 values = v1, v2, v3 and there are fields f1, f2, f3

7:42 I need to concatenate the fields f1-v1, f1-v2, f1-v3 if f1 exists

7:42 ditto with f2, f3

7:42 my normal way of doing it is:

7:42 (for [v values] (if f1 (str f1 "-" v)) (if f2 (str f2 "-" v)) ....

7:43 I was wondering if there is a better way ?

7:46 clgv: (map #(when %1 (str %1 "-" %2)) fields values)

7:46 does that work for you?

7:48 &(map #(when %1 (str %1 "-" %2)) ["f1" "f2" "f3"] [1.0 2.0 3.0])

7:48 sexpbot: ⟹ ("f1-1.0" "f2-2.0" "f3-3.0")

7:48 clgv: as test

7:49 ogonzalez: bartj, using for: (for [f f-values v values :when f] (str f "-" v))

7:49 I think it's right

7:51 &(for [f ["f1" nil "f2"] v ["v1" "v2"] :when f] (str f "-" v))

7:51 sexpbot: ⟹ ("f1-v1" "f1-v2" "f2-v1" "f2-v2")

8:39 bartj: ogonzalez, yep, will try that

8:39 ogonzalez, thanks!

9:28 pppaul: how do i add a classpath to clojure while it's running?

9:28 dnolen: pppaul: no reliable way to do that.

9:29 pppaul: oh

9:29 pdk: http://stackoverflow.com/questions/402330/is-it-possible-to-add-to-classpath-dynamically-in-java

9:29 java isn't really built for this but look into URLClassLoader it seems

9:30 remember java comes from the mindset of the old c style write compile run debug loop

9:30 pppaul: hmmm

9:30 AWizzArd: Instead of directly the URLClassLoader one could also have a look at the DynamicClassLoader that ships with Clojure.

9:31 This IS an URLClassLoader too.

9:31 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/DynamicClassLoader.java

9:41 edw: Any cake users here?

9:42 I'm trying to add /usr/local/share/java to my java.library path and am putitng an entry into $PROJECT/.cake/config with no success.

9:44 dnolen: edw: what does you entry look like?

9:45 edw: Line 1: "project.library.path = /usr/local/share/java"

9:45 Line 2 is the same, but cake.library.path.

9:45 Do I also need to add a "native-path" entry to my project.clj?

9:46 dnolen: edw: if you're on 0.6 I think the syntax changed, jvm.opts = -Xms1024M -Xmx2048M -Dfoo=bar

9:47 nurv101: Question here: is it possible to create a lisp closure in clojure?

9:47 edw: Ah. I'll check that out. Are they additive i.e. can I put that in $HOME/.cake/config and it'll be concatenated with the projects .cake/config file?

9:48 dnolen: nurv101: yes

9:48 raek: nurv101: what exactly do you mean by "lisp closure"?

9:48 nurv101: dnolen: how?

9:48 raek: (let ((x 0)) (defun foo() (incf x)))

9:48 dnolen: edw: no they are separate.

9:49 edw: (let [x 12] (fn [] x))

9:49 raek: (defn create-counter [a (atom 0)] (fn [] (swap! a inc)))

9:49 edw: Ahh. Okay.

9:49 raek: nurv101: ^

9:49 nurv101: raek: that is not a clojure

9:50 raek: clojure won't allow you to change the local introduced by let

9:50 nurv101: raek: closure i mean

9:50 raek: if that was your question

9:50 nurv101: raek: i know

9:50 raek: every time you call create-counter, you will get a function with its own atom

9:50 nurv101: the problem is that even local-vars can't be change

9:51 that way

9:51 raek: in clojure, you have to have some form of mutable cell that does the change part

9:51 i.e. an atom, agent, ref, or var

9:52 all these have their own approach to what mutation means in a concurrent context

9:53 edw: But the answer to your question is that yes, clojure has lexical scoping aka closures.

9:54 raek: yes. functions close over their free variables.

9:54 edw: Yes.

9:55 nurv101: lexical scope isn't a clojure

9:55 closure

9:57 mefesto: Good morning everyone.

9:58 If i wanted to send some clojure data over the network using pr and read -- is there a preferred content-type for this?

9:58 application/clojure-source or something?

9:59 edw: nurv101: A closure is an artifact of lexical scoping combined with the ability to declare a procedure in the scope of another.

10:00 raek: not that I'm aware of. I used "text/x-clojure-source" to mimic "text/x-java-source"

10:01 mefesto: raek: works for me, thanks :)

10:01 raek: the "x-" means that it hasn't been registered

10:12 akopa: A bit rough, but here's an clr interop example adapted from RDNZL for Common Lisp: https://gist.github.com/807795

10:23 edw: Has anyone used zmq and cake on osx? My forehead is bloody from beating it against my monitor.

10:29 __name__: hi

10:31 raek: if __name__ == "__main__": print "__name__: hi"

10:32 __name__: Could any of you be ask kind as to express criticism about https://gist.github.com/806541, I'd like to know where I can improve.

10:53 semperos: I call a function A which returns a vector; I need to call a function B which takes the _contents_ of the vector, like splicing; what's the proper way to handle this?

10:54 mefesto: semperos: (apply B [1 2 3])

10:54 __name__: semperos: do you mean (apply + [1 2 3])

10:54 mefesto: semperos: is the same as calling: (B 1 2 3)

10:55 semperos: makes sense

10:55 thanks, simplest things escape me sometimes...

10:56 pdk: you can also put extra args in front of the vector

10:56 so (apply + 1 2 3 [4 5 6]) is the same as (+ 1 2 3 4 5 6)

10:57 __name__: i wish apply and partial had shorter names

11:11 edw: In cake, "ext-dependencies", what are these things? I'm currently going through the source code, but if cake's project file format is documented anywhere, that would be great.

12:06 Is there a safe way to eval strings? Basically a JSON-y reader procedure?

12:50 phenom_: im having a bit of trouble with cake ... I created a project.clj file correctly and added a single file in the test folder (chapter08/date-operations-spec.clj) but when I run "cake test" it complains (hapter08/date_operations_spec.clj on classpath, note the underscore's)

13:30 Scriptor: hey everyone, I have a question about the sequence implementation as described in http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/

13:32 say you have <32 elements, and you cons a new element on the vector

13:33 following that code, it seems like it finds the right and bottom-most array, and copies it

13:34 what exactly is the new root being created with such a cons?

13:46 amalloy: Scriptor: as i understand it, if you have fewer than 32 elements and cons another, it copies the whole thing

13:46 well. conj, not cons

13:47 Scriptor: amalloy: by the whole thing, you mean just that set of <32 elements, right?

13:47 amalloy: Scriptor: yes, since that is the whole thing

13:47 Scriptor: isn't that still a little inefficient?

13:48 amalloy: edw: maybe check out clojail

13:48 Scriptor: ok, the whole thing could be the whole tree too, right? :)

13:48 amalloy: Scriptor: i don't understand. if you have less than 32 elements, the tree is a single node

13:49 Scriptor: amalloy: oh, I meant 32 elements in the rightmost and bottom-most set of elements

13:49 amalloy: edw: it's the safe-evaluation library Raynes and i have put together, and it's what sexpbot uses. see, for example, ##(inc (eval (read-string "2")))

13:49 sexpbot: java.lang.SecurityException: You tripped the alarm! eval is bad!

13:50 Scriptor: for example, looking at the diagram, if we imagined that red series of 1..32 was instead something like 1..14

13:50 er, 0..14

13:50 and we added another element to it

13:50 amalloy: then yes, those 32 elements are copied

13:51 and that's inefficient but unavoidable, and not terribly inefficient

13:51 Scriptor: ah, I understand now, thanks!

13:51 amalloy: one malloc and 32 pointer copies?

13:52 Scriptor: right, it uses System.arraycopy

13:52 which I guess would be pretty efficient

13:52 amalloy: probably

13:52 and iirc it has to make a copy of every node heading up to the root, but that will be a pretty small number

13:59 pdk: okasaki's book is a good primer on functional data structures scriptor

14:01 Scriptor: pdk: is his thesis paper a good substitute

14:01 ?

14:01 That's what I've been trying to use

14:01 pdk: the book expands it some and adds haskell translations of the ML code samples

14:02 Scriptor: ooh, haskell translation would be nice

14:02 argh, still pricey though :/

14:03 ossareh: morning all

14:03 Scriptor: morning ossareh

14:04 pdk: oh wow it's on kindle now

14:04 Scriptor: yep, I have one too

14:05 I just wish I knew for certain I'd read it

14:05 would you say the book is more beginner-friendly?

14:05 ossareh: which book?

14:05 pdk: i haven't completed it but i doubt it'll be much less dense

14:05 aside from adding introductory bits

14:05 with stuff like the tree copying example

14:06 Scriptor: ossareh: purely functional data structures

14:07 ossareh: Scriptor: ah - nice - man that was a hard read

14:13 Scriptor: ossareh: I know! I'm honestly still trying to find a detailed enough explanation of amortization

14:13 __name__: I know I already posted it, but I think the message was not noticed (and I updated the code): Please tell me if you can see anything unidiomatic in https://gist.github.com/806541.

14:15 opqdonut: looks ok

14:22 shortlord: How can I import a simple .java file that is placed in the same directory as the clojure files?

14:23 I have written a file called Foobar.java

14:23 and used :import [Foobar]

14:23 __name__: opqdonut: Thanks

14:23 shortlord: but (Foobar/foo "test") still doesn't work

14:23 mefesto: shortlord: did you compile it and it's class is on the classpath?

14:25 shortlord: mefesto: I have compiled it using javac

14:25 mefesto: shortlord: are you using leiningen or cake for building this project?

14:25 shortlord: I am using cake

14:26 amalloy: __name__: i don't think we use lazy-cat anymore

14:26 __name__: amalloy: what else?

14:27 mefesto: shortlord: i haven't tried a mixed java + clojure source project using leiningen (or cake) so I'm not sure if this is necessary but did you specify a :java-source-path in your project.clj?

14:27 shortlord: mefesto: no, I didn't. Do you have any link about the :java syntax?

14:27 amalloy: i'm still working through what you're actually *doing*, but it seems like you're using ::p as a sentinel "non-data" value. i usually use (complement #{::p}) rather than #(not= ::p %) for that, but it's not 100% clear it's applicable to your case

14:28 oh, you mean what instead of lazy-cat?

14:28 mefesto: shortlord: im going by this leiningen example: https://github.com/technomancy/leiningen/blob/stable/sample.project.clj

14:30 shortlord: mefesto: thx, I will look at that

14:30 __name__: amalloy: yes

14:30 amalloy: concat should be lazy enough for your purposes

14:30 __name__: so concat is lazy by default?

14:31 amalloy: $source concat

14:31 sexpbot: concat is http://is.gd/e8fROL

14:31 amalloy: the source is messy because of optimizations, but you can see it's wrapped with lazy-seq

14:32 __name__: where's the difference to lazy-cat then?

14:32 amalloy: lazy-cat is a relic of 1.1, i think

14:32 ie, there's no reason to use it

14:32 __name__: amalloy: fair enough, thank you

14:33 brehaut: morning

14:33 __name__: good morning, brehaut

14:33 amalloy: hola brehaut

14:34 __name__: amalloy: the source to concat confuses me :)

14:34 brehaut: $source concat

14:34 sexpbot: concat is http://is.gd/e8fROL

14:36 brehaut: __name__: are you focusing just on the arity-2 version?

14:37 __name__: yes

14:38 amalloy: __name__: ignore the chunked half, too

14:38 brehaut: the guts of the algorithm is the else part of the inner most if; everything else can be handwaved as 'implementation details'

14:38 __name__: (cons (first s) (concat (rest s) y))

14:38 that?

14:38 brehaut: yup

14:39 __name__: $source cons

14:39 sexpbot: cons is http://is.gd/5brDTa

14:39 brehaut: ie a recursive call. it doesnt blow stack because concat is wrapped in a lazy-seq

14:39 cons is the singlely linked list / seq equivalent of conj

14:40 __name__: fair enough, fp still sort of confuses me by times

14:40 amalloy: (defn my-cat [x y] (lazy-seq (let [s (seq x)] (if-not s y (cons (first s) (concat (rest s) y)))))) would be a simple version, and i think correct

14:41 brehaut: did you do something weird when talking about wrapping? i see a \u0008 character right before "wrapped"

14:42 brehaut: i dont ithnk i did?

14:43 amalloy: i thik your version is correct yes

14:43 __name__: amalloy: that makes sense

14:43 amalloy: __name__: oh good

14:43 __name__: thank you very much, amalloy

15:00 opqdonut: this is weird

15:00 (first (map prn [1 2 3])) prints all of the numbers

15:01 even though (map prn [1 2 3]) has class clojure.lang.LazySeq and chunked-seq? returns false for it

15:01 is there something I'm missing?

15:01 amalloy: opqdonut: chunked-seq? isn't very reliable in my experience

15:02 opqdonut: is there some way I can force a seq to be one-by-one

15:02 amalloy: it's definitely a chunking issue

15:02 opqdonut: yes, I figured as much

15:02 (this is 1.2.0)

15:02 amalloy: ummmmm, i'm gonna make chouser answer that question. he put some kind of unchunker in JoC

15:02 tomoj: &(class (next (map prn [1 2 3])))

15:02 sexpbot: ⟹ 1 2 3 clojure.lang.ChunkedCons

15:03 amalloy: &(class (seq (map prn [1 2 3])))

15:03 sexpbot: ⟹ 1 2 3 clojure.lang.ChunkedCons

15:03 opqdonut: indeed

15:03 amalloy: before the seq call, it can't know that the underlying lazy seq will be chunked

15:04 tomoj: is it the side-effects you're worried about?

15:04 opqdonut: I'm worried about consistency

15:04 I'm teaching a course on clojure...

15:04 tomoj: I recommend teaching them not to pass side-effecting functions to map :)

15:05 opqdonut: that I am doing, I'd just like to demonstrate laziness

15:06 amalloy: &(first (iterate #(do (prn %) (inc %)) 0))

15:06 sexpbot: ⟹ 0

15:06 amalloy: &(second (iterate #(do (prn %) (inc %)) 0))

15:06 sexpbot: ⟹ 0 1

15:07 opqdonut: &(first (map prn (range)))

15:07 sexpbot: ⟹ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 nil

15:07 opqdonut: &(first (map prn (repeat 50 "!")))

15:07 sexpbot: ⟹ "!" nil

15:08 tomoj: could be dangerous

15:10 imagine defining the ackermann function and using (range), taking a few

15:10 shortlord: does anyone know how to compile .java files using cake?

15:10 opqdonut: tomoj: indeed

15:12 tomoj: I hardly remember ever having actual problems from it

15:26 LauJensen: shortlord: AFAIK the cake javac plugin is loaded by default, so it should just pick up the java files and compile them, try asking in #cake.clj if you have any problems

15:26 amalloy: fwiw opqdonut i've never been impacted by chunking

15:26 opqdonut: well me neither

15:26 amalloy: it's something that sounds appalling but winds up not really mattering

15:26 opqdonut: that's why I was kinda surprised

15:28 for educational reasons I'd like a dechunkifier

15:28 (defn my-seq [s] (map first (iterate next s))) seems to work at least

15:29 amalloy: opqdonut: really? i don't think you can unchunk a seq that's already chunked; you have to prevent it happening in the first place

15:30 opqdonut: that's what I meant, of course

15:30 shortlord: LauJensen: thx for the suggestion, javac does not seem to be loaded with cake by default, but I managed to get it working with lein javac

15:30 opqdonut: so (first (map prn (my-seq [1 2 3]))) prints only 1

15:31 shortlord: is there something like :reload-all for imports?

15:32 amalloy: shortlord: i don't think so. java doesn't like classes to change at runtime

15:33 shortlord: amalloy: I'd like to reimport them in clojure without restarting the REPL though

15:35 amalloy: is there really no way of doing it? it should not be too different from how clojure does it itself, right?

15:35 it works as soons as I restart them REPL and then import the file again, but always closing and restarting the REPL kills the dynamic workflow

15:36 brehaut: shortlord: but for a dynamic workflow you infrequently need to reload more than one ns

15:36 opqdonut: you can google "java class reloading" and read all the problems :)

15:37 amalloy: i don't know. clojure does it, i think, by re-reading the .clj files and generating new classes with different (?) names

15:40 ossareh: hm, if that were the case permgen would run out - and i've not seen that to be the case in any of my super long running repl sessions (often weeks at a time between restarts)

15:41 raek: hrm. when was support for docstrings in 'def' added?

15:42 opqdonut: &(doc def)

15:42 sexpbot: java.lang.SecurityException: You tripped the alarm! def is bad!

15:42 opqdonut: :D

15:42 okay then

15:43 arohner: ossareh: permgen is GC'd when the classloader that created the class is GC'd

15:43 raek: http://clojure.org/special_forms says (def symbol doc-string? init?)

15:43 arohner: ossareh: err. classes *can* be GC'd *after* their classloader is GC'd

15:44 opqdonut: in practice getting classes to GC can be bothersome

15:44 arohner: clojure gets around the permgen issue by creating a new classloader each time it creates classes

15:44 brehaut: raek: presumably thats in 1.3 cause 1.2 erros if i actually try it

15:44 ossareh: arohner: ah, I didn't know that - cool. Cheers.

15:44 opqdonut: when I last meddled in classloaders I think I ended up creating one per loaded class

15:45 (the program was generating a ton of one-off classes)

15:45 ossareh: opqdonut: right - I had a similar issue with a simple web app hosted in jboss, a few deploys and I guess something was keeping class headers around.

15:58 raek: what is the preferred way of testing private variables with clojure.test? @#'foo? something else?

16:05 pjstadig: amalloy: the compiler generates new class names using a global serial number in clojure.lang.RT

16:07 raek: fogus wrote a macro http://blog.fogus.me/2010/09/03/monkeying-with-clojures-deftest/

16:07 or you could just @#'foo

16:10 sritchie: hey all -- I have two clojure functions that are very similar, and wanted to ask advice on how to abstract out the common pattern. here are the functions -- https://gist.github.com/3148f33f2702b029fe78

16:10 I could have all-files call files-with-names and simply not return the ?filename, but the function is exactly the same length

16:11 brehaut: where is <- defined?

16:11 edw: It's cascalog.

16:11 brehaut: oh, cascalog?

16:11 sritchie: brehaut: it's a cascalog macro

16:11 brehaut: uip

16:11 yup

16:12 I suppose I could just give two vectors, input args and output args,to a function

16:12 and have it return the common function

16:13 kumarshantanu: hi, can anybody let me know how can i easily extend IFn of invoke (arity 2) to a type?

16:14 there are like 21 arity signatures for invoke in IFn, and i don't need all of them

16:22 tomoj: do you own the type?

16:22 deftype/defrecord? or what?

16:23 raek: kumarshantanu: from java or using proxy: extend AFn instead of implementing IFn

16:24 sritchie: brehaut: they're similar, but I'm not sure what the pattern is --

16:24 in one case, I'm dropping one of the fields

16:25 brehaut: im not sure im much help, i dont know cascalog at all

16:25 do you only have the two functions?

16:26 amalloy: sritchie: i suspect that <- is a macro in cascalog, so you can't generalize it without adding a macro of your own - a function can't usefully call it since the options will need to be available at compile time

16:27 sritchie: amalloy: in this case, is it worth it to keep the duplication?

16:27 amalloy: the other option is to have the tap return filename for everything, and just ignore it further down the road

16:27 amalloy: as that's essentially what "all-files" does anyway

16:28 amalloy: eg (defmacro casca-fn [name doc v1 v2] `(defn ~name ~doc [arg#] (let [source# (hfs-whole-file arg#)] (<- ~(vec v1) (source# ~@v2)))))

16:29 i don't know anything about cascalog, but that's a macro you should be able to call as (casca-fn all-files "doc" [?file] [?filename ?file]) to reproduce your second defn

16:31 sritchie: amalloy: interesting, let me try that out

16:31 amalloy: this'll be my first macro

16:31 amalloy: sritchie: whew. i just tried it out, and it does

16:31 sritchie: haha, someday I'll be able to churn out working macros in IRC

16:35 amalloy: incidentally, if you wanted to you could eliminate the "source" binding by moving it into the <- in-place

16:42 sritchie: amalloy_afk: done, and playing with macroexpand

16:43 mefesto: ,(= (into-array Byte/TYPE [1 2 3]) (into-array Byte/TYPE [1 2 3]))

16:43 clojurebot: java.lang.IllegalArgumentException: argument type mismatch

16:45 mefesto: ,(java.util.Arrays/equals (into-array Byte/TYPE (map byte [1 2 3])) (into-array Byte/TYPE (map byte [1 2 3])))

16:45 clojurebot: true

16:47 mefesto: hmm is there another way to test array equality?

16:47 companion_cube: ,(= [1 2 3] [1 2 3])

16:48 clojurebot: true

16:48 mefesto: companion_cube: java arrays tho

16:48 more specifically, java byte arrays

16:48 companion_cube: don't know

16:50 amalloy: argument type mismatch? that's a weird exception for that

16:50 &(= (byte-array [1 2 3]) (byte-array [1 2 3]))

16:50 sexpbot: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Byte

16:50 mefesto: amalloy: yup, i forgot to (map byte [1 2 3]) it

16:51 &(= (byte-array (map byte [1 2 3])) (byte-array (map byte [1 2 3])))

16:51 sexpbot: ⟹ false

16:51 mefesto: oh well i guess i can live with j.u.Arrays/equals

16:53 amalloy: mefesto: you could seq them

16:53 &(apply = (map seq (repeatedly 2 #(byte-array (map byte [1 2 3])))))

16:53 sexpbot: ⟹ true

16:54 mefesto: amalloy: sweet, i'll take that over j.u.Arrays. thanks :)

16:54 amalloy: &(apply = (map identity (repeatedly 2 #(byte-array (map byte [1 2 3])))))

16:54 sexpbot: ⟹ false

16:54 amalloy: yeah, just checking. seq is the magic

16:55 opqdonut: gah, lein fails

16:55 can't find org.clojure:clojure:jar:1.2.0

16:55 raek: opqdonut: newest version?

16:55 done lein self-install?

16:56 opqdonut: i downloaded the script and said "lein"

16:56 let's try self-install

16:56 ok, that seemed to do something

16:58 raek: opqdonut: it seems that in the latest versions, self-install should be automatic when you use lein the first time

16:58 opqdonut: ok

16:58 raek: you used the stable version, rigth? https://github.com/technomancy/leiningen/raw/stable/bin/lein

16:58 opqdonut: yeah

17:00 hmm, "lein repl" still complains about org.clojure:clojure:jar:1.2.0 and org.apache.maven:super-pom:jar:2.0 missing

17:00 I kinda hate all these language-specific frameworks, I'm fighting with leiningen *and* cabal at the moment...

17:02 amalloy: opqdonut: lein repl wants you to be in a project

17:03 cake repl will implicitly use the global project

17:03 technomancy: actually lein repl will run in leiningen's classloader if you're outside a project.

17:04 amalloy: technomancy: sorry, i try to avoid singing only-cake's praises, but i forgot this time :)

17:04 technomancy: missing clojure.jar sounds like a firewall issue

17:04 opqdonut: I'm in a project as far as I know

17:05 technomancy: nah

17:05 oh, that's funny

17:05 Exception in thread "main" java.net.SocketException: Network is unreachable (NO_SOURCE_FILE:0)

17:06 I can ping repo1.maven.org and clojars.org just fine

17:06 and browse them too

17:06 and I'm on a basic adsl line

17:09 technomancy: net neutrality?

17:09 for Leiningen access you need the Premium Developer Plus DSL bundle.

17:09 opqdonut: har har

17:10 let's try straceing the call

17:10 32316 --- SIGSEGV (Segmentation fault) @ 0 (0) ---

17:11 32316 getsockname(0, 0x7f7c84a8df90, [28]) = -1 ENOTSOCK (Socket operation on non-socket)

17:11 this sounds bad

17:11 kryft: technomancy: Is this something like expensive speaker cables?

17:11 technomancy: right

17:11 sritchie: can anyone recommend a good tool for counting lines of code in a leiningen project?

17:11 opqdonut: hmm, okay, for some reason it's trying ipv6 addresses

17:12 kryft: sritchie: Are you charging per line?

17:12 sritchie: haha, no, they'd soon realize that clojure could all be one line, technically

17:12 I'm revamping a rather large python project using clojure, and want to make a point to the team

17:12 amalloy: sritchie: as could anything but python :P

17:13 sritchie: amalloy: true, as I'm comparing to python, maybe my comparison should be: here's our former huge application, in one line.

17:14 raek: opqdonut: could you try renaming your .m2 folder to something else and try again?

17:15 amalloy: sritchie: $ find -name '*.clj' | xargs perl -n -e 'print unless (/^\s*(;.*)?$/);' | wc

17:15 is what i use

17:15 opqdonut: raek: same problem

17:15 I even removed all ipv6 addresses from my interfaces

17:19 ah found the debian bug report for this

17:25 amalloy: i see my suggestion was so awesome it broke sritchie's net connection

17:26 opqdonut: yay, workaround

17:59 scottj: Are there any tricks for making lein behave better when there's no internet connection available? does only lein deps cause it to check for updates to dependencies that are SNAPSHOT?

18:01 arohner: scottj: lein uses maven under the hood. Have you looked at the offline settings in http://maven.apache.org/settings.html?

18:01 technomancy: scottj: the Maven API exposes a "don't check for snapshots" setting, but it seems to have no effect in my brief experience with it.

18:02 scottj: but if there are no SNAPSHOT deps and dependencies are in ~/.m2, then an Internet connection isn't needed

18:02 see also :checksum-deps in lein 1.5

18:25 sritchie: hey all -- when defining a multimethod, what's a clean way to direct, say, both byte-arrays and files to the same method?

18:29 wolverian: is there a nicer way than (every? identity coll)? (apply and coll) doesn't work, of course.

18:30 technomancy: wolverian: there's an open ticket for that

18:30 http://dev.clojure.org/jira/browse/CLJ-450

18:35 wolverian: that'd be nice.

18:36 technomancy: I concur.

18:36 amalloy: sritchie: ##(doc derive)

18:36 sexpbot: ⟹ "([tag parent] [h tag parent]); Establishes a parent/child relationship between parent and tag. Parent must be a namespace-qualified symbol or keyword and child can be either a namespace-qualified symbol or keyword or a class. h must be a hierarchy obtained from make... http://gist.github.com/808684

18:37 sritchie: amalloy: great, just ended up deriving both from ::fileable

18:37 thanks

18:37 amalloy: yeah, that's what i was going to suggest

18:38 sritchie: amalloy: all of this syntax ends up being so clean! I'm feeling much clojure love

18:39 amalloy: heh. and now you can count lines, too, right?

18:55 pppaul: anyone know how to use fixtures?

18:55 mefesto: pppaul: clojure.test fixtures?

18:55 pppaul: yup

18:56 when i read about them it tells me to add them to the namespace

18:56 i tried in the (ns ) macro, but that gave me errors

18:56 mefesto: pppaul: yeah there is a function called clojure.test/use-fixtures i think

18:57 pppaul: so, i just put that in my file and that's it? (that's what have now... haven't been able to run my tests cus i'm fighting with classpaths again)

18:58 mefesto: pppaul: http://clojure.github.com/clojure/clojure.test-api.html

18:58 pppaul: i've read that

18:58 a few times

18:59 mefesto: pppaul: in your test ns you define your fixture functions (ex. my-fixture) then call (use-fixtures :each my-fixture)

18:59 pppaul: ok, maybe i'm doing it right

18:59 ug, just crashed lein because my classpath for testing was wrong :(

19:01 mefesto: https://gist.github.com/808773

19:54 sritchie: hey all -- I'm looking for an idiomatic way to take every odd element in a collection

19:55 technomancy: ,(doc keep-indexed)

19:55 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."

19:55 amalloy: sritchie: take-nth

19:56 or wait, do you mean every second element, or every element whose value is odd?

19:56 sritchie: every second element

19:56 amalloy: &(take-nth 2 (range 20))

19:56 sexpbot: ⟹ (0 2 4 6 8 10 12 14 16 18)

19:56 sritchie: ,(take-nth 2 (range 24))

19:56 clojurebot: (0 2 4 6 8 10 12 14 16 18 ...)

19:56 sritchie: cool, that's great

19:57 thanks a lot

19:57 I'm slowly absorbing the sequence API

19:57 brehaut: ,(take-nth 2 (rest (range 24))

19:57 clojurebot: EOF while reading

19:57 amalloy: sritchie: nobody can absorb it all, except chouser

19:57 brehaut: ,(take-nth 2 (rest (range 24)))

19:57 clojurebot: (1 3 5 7 9 11 13 15 17 19 ...)

19:58 sritchie: doc in the repl is extraordinarily helpful

19:58 brehaut: hah

19:58 &(doc apropos)

19:58 sexpbot: java.lang.Exception: Unable to resolve var: apropos in this context

19:59 amalloy: $findfn 2 (range 10) [0 2 4 6 8]

19:59 sexpbot: [clojure.core/take-nth]

19:59 amalloy: sritchie: sexpbot also has a handy little thing for you

19:59 brehaut: amalloy: what are the limits on the syntax for $findfn ?

19:59 amalloy: it's not very flexible, but it can help if you know what you're looking for but not what to call it

19:59 sritchie: amalloy: wow, that's really handy

19:59 brehaut: sritchie: also look at at clojure.repl/apropos

20:00 amalloy: brehaut: no particular limits. it takes N forms, interprets the last as a return value and the rest as args

20:00 brehaut: it lets you search all the currently loaded ns's for a regexp or string

20:00 amalloy: it evals each form in the same sandbox it uses for ##(count "other stuff")

20:00 sexpbot: ⟹ 11

20:01 amalloy: i suppose i could try permuting the arguments so that $findfn (range 10) 2 [0 2 4 6 8] also worked

20:01 technomancy: $find-fn false (loop [] (recur))

20:01 ooops; missing a # there

20:01 brehaut: $findfn (fn [a b] (cons b a)) [] [1 2 3] (3 2 1)

20:01 sexpbot: java.security.PrivilegedActionException: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)

20:02 technomancy: was hoping to have it solve the halting problem

20:02 sritchie: haha

20:02 and then the forum would implode

20:02 brehaut: $findfn (fn [a b] (cons b a)) [] [1 2 3] (list 3 2 1)

20:02 sexpbot: java.lang.Exception: Unreadable form

20:03 brehaut: whats unreadable about that?

20:03 amalloy: brehaut: dunno

20:03 technomancy: it should be eval'ing this in a timeout context. i don't quite see why you never got an exception

20:04 technomancy: ruh roh

20:04 brehaut: somewhere a core is getting hot

20:07 amalloy: lol, no, it probably just doesn't send a message in certain error cases. tbh it's been a while since i wrote this

20:07 also sritchie, you can /msg sexpbot if you want to try things like findfn without cluttering #clojure

20:07 brehaut: while that is clearly better, its a ilittle disappointing :P

20:07 amalloy: yeah

20:08 sritchie: amalloy: good advice

20:08 amalloy: is there anything like sexpbot out there?

20:09 amalloy: what's the competition look like?

20:09 amalloy: sritchie: clojurebot

20:09 ,'meeeeee

20:09 clojurebot: meeeeee

20:09 amalloy: and there are loads of irc bots for various languages

20:10 brehaut: hash haskell has a pretty cool one

20:10 amalloy: $help heval

20:10 sexpbot: amalloy: Evaluates Haskell code with mueval.

20:10 bhenry1: the sexpbot irc room needs a name change to avoid the occasional creeper in there.

20:10 amalloy: bhenry1: yeah, that's funny stuff

20:12 brehaut: heval take 10 $ let fib = 1 : 1 : zipWith (+) fib (tail fib) in fib

20:13 uh oh

20:13 do i need to message it directly to sexpbot?

20:16 amalloy: brehaut: $heval

20:16 brehaut: $heval take 10 $ let fib = 1 : 1 : zipWith (+) fib (tail fib) in fib

20:16 sexpbot: ⟹ [1,1,2,3,5,8,13,21,34,55]

20:16 brehaut: aha

20:17 amalloy: sexpbot's commands need to be prefixed with $, or anything /msged will be tried as a command

20:17 brehaut: ah right of course

20:37 defn: anyone have the "State of the Art" setup for vim and clojure? Don't worry guys, it's for a friend... :D

20:37 brehaut: a friend eh :P

20:39 defn: brehaut: i have my hand over my heart as we speak

21:37 bartj: is it possible to partition a sequence using a regex ?

21:37 grr, re-seq

21:38 brehaut: bartj: can you rephrase the question? its a bit ambigious

21:39 perhaps and example of your hypothetical inputs and outputs?

21:40 bartj: brehaut, basically a re-split which works on sequences ?

21:41 eg: (func #"^$" ["a" "b" "" "c" "d"])

21:41 would give (("a" "b") ("c" "d"))

21:45 brehaut: bartj: hmm. partition-by will get you half way there

21:46 ,(partition-by empty? ["a" "b" "" "c" "d"])

21:46 clojurebot: (("a" "b") ("") ("c" "d"))

21:47 bartj: brehaut, that's exactly what I need, thanks!

21:48 brehaut: bartj: its not _exactly_ it

21:48 a: the pivot is still present

21:48 b: it'll pivot again if another empty string is found

21:49 ,(partition-by empty? ["a" "" "b" [] "c"])

21:49 clojurebot: (("a") ("") ("b") ([]) ("c"))

21:49 bartj: though, I am stumped by:

21:49 ,(empty? '())

21:49 clojurebot: true

21:49 brehaut: the empty list is empty?

21:50 partition-by partitions the seq whenever the result of the fun its provided changes

22:01 bartj: heres an exceedingly scruffy pivot-on fun that does what you wanted https://gist.github.com/808961

22:02 and by exceedingly, it looks like a cat wandered into a text editor and vomited up square brackets

22:03 the clearly ignores the obvious optimisation of just using the remainder as 'r' as soon as the pivot predicate is matched

22:08 pdk`: could always be fancy and write (vec this that...) everywhere

22:08 if those []s bug ya

22:09 i assume this is for a functional version of quicksort or something?

22:09 brehaut: pdk oh man i hope not :P

22:10 bartj: brehaut, thanks, I think I'll stumble through

22:10 I've used:

22:10 brehaut: bartj: i have a loop recur version that is cleaner :P

22:11 bartj: brehaut, thank you, I am done with what I want :)

22:11 brehaut: haha

22:11 no problem

22:12 i just couldnt leave the scruffy version as the only version :P

22:14 gfrlog: (doc vec)

22:15 ,(doc vec)

22:15 clojurebot: "([coll]); Creates a new vector containing the contents of coll."

22:15 Execution Timed Out

22:15 gfrlog: I knew (vec this that) didn't make sense

22:16 brehaut: gfrlog: it'll fit right in with my terrible function implemention :P

22:20 pdk`: well

22:20 vector :p

22:20 bhenry: ,(vector :this :that)

22:20 clojurebot: [:this :that]

22:20 pdk`: hmm

22:21 (fn [[[l r] pivoted] v]

22:21 what exactly is going on with the destructuring for the fn args there

22:21 brehaut: yikes man, no need to go spread that mess about :P

22:21 pdk`: it's a learning exercise :p

22:21 brehaut: ok

22:22 (pivot-on empty ["a" "b" "" "c" "d"]) ;=> [["a" "b"] ["c" "d"]]

22:22 in the reduce, im using a vector as a pair for my accumulator

22:23 the pair consists of the final result (another pair of vectors) and a flag to tell the reducer if it has pivoted

22:25 pdk`: does that make it clearer?

22:26 bartj: ,(doc pivot-on)

22:26 clojurebot: Excuse me?

22:26 bartj: huh?

22:27 zippy314: Hi. How do I determine if a cloujure object is callable as a function?

22:27 brehaut: bartj: its in that gist i made

22:27 bartj: oh

22:27 zippy314: i.e. would return true for a keyword but false for an integer

22:27 bartj: zippy314, ASFAIK most clojure objects *are* functions

22:27 eg:

22:27 brehaut: ,(fn? inc)

22:27 clojurebot: true

22:27 brehaut: ,(fn? {})

22:27 clojurebot: false

22:28 brehaut: (ifn? {})

22:28 bartj: ,(doc keyword?)

22:28 brehaut: ,(ifn? {})

22:28 clojurebot: "([x]); Return true if x is a Keyword"

22:28 true

22:28 bartj: zippy314, here is my version:

22:28 (if (keyword? obj) true false)

22:29 brehaut: zippy314: ifn? for anything callable, fn? for actually a function

22:29 zippy314: thats it!

22:29 ,(doc ifn?)

22:29 clojurebot: "([x]); Returns true if x implements IFn. Note that many data structures (e.g. sets and maps) implement IFn"

22:29 brehaut: bartj: that can be reduced to (keyword? obj)

22:29 phenom_: out of curiosity, what is the plan for binding in clojure 1.3?

22:31 dnolen: phenom_: plan ?

22:32 phenom_: dnolen: rebinding a function in a binding clause no longer works in 1.3, but does for 1.2

22:33 brehaut: phenom_: by default. if you add the :dynamic meta to the var it does

22:34 phenom_: hmmm, correct me if im wrong (and i mean in that in the newbie sense not in the pretentious sense) but does that mean I need to know ahead of time which functions will potentiall be rebound and add the :dynamic meta info ?

22:34 brehaut: yes

22:34 pdk`: i was asking more about the args list for the fn in the line i posted bartj

22:35 Razwelles: How do you load a .net dll and use its classes in clojureclr?

22:35 pdk`: how you got 2 levels of nesting going on in the args list so i was wondering how the destructuring there was playing out

22:35 brehaut: phenom_: its good practise to *ear-muff* your rebindable vars anyway

22:36 phenom_: brehaut: how would stubbing or mocking work for testing ?

22:36 brehaut: phenom_: pass?

22:37 phenom_: brehaut: :S im not familiar with that

22:37 brehaut: phenom_: i mean i dont know sorry

22:38 phenom_: brehaut: kk, thnx

22:41 dnolen: phenom_: known issue, http://clojure-log.n01se.net/date/2010-10-29.html

22:42 phenom_: not sure if it's been addressed yet.

22:43 phenom_: it can be done by changing the var root binding, but I think it's a bit tedious, thus the discussion about a convenience macro for mocking/stubbing.

22:47 phenom_: dnolen: good catch, thnx :)

22:50 pppaul: anyone here work with lein?

22:50 bhenry: pppaul: what;s up?

22:50 pppaul: i'm trying to do testing in it, but i'm not sure how to set up my namespace

22:50 bhenry: you mean like lein test?

22:52 pppaul: (ns test.solve360.name-fixer is my namespace, but when i run lein test it breaks. my folder structre is /test/solve360/name_fixer.clj

22:53 test/ is in my classpath too

22:54 also, when lein test is run, lein totally breaks... i need to restart it

22:55 bhenry: try ns solve360.name-fixer

22:55 https://github.com/technomancy/leiningen/blob/master/test/test_compile.clj

22:55 example

22:55 ^^^ pppaul

22:57 pppaul: thanks

22:58 how would that namespace work? because i have that namespace already taken in my src dir

22:58 bhenry: i think that's why all the leiningen tests have test in the name.

22:59 just change the name of your test file to test-name-fixer

22:59 pppaul: seems a bit redundant

22:59 thanks, though

23:00 bhenry: pppaul: i agree.

23:00 pppaul: oh, i think i did it wrong... should be solve360.test.name-fixer

23:00 i hope

23:01 yup, works

23:02 bhenry: cool.

23:02 i haven't done too much with testing. should probably get in the habit of that.

23:06 pppaul: i really need to test, i can't trust my code

23:31 brehaut: technomancy: does lein backup the 'lein' script when you do upgrade ?

Logging service provided by n01se.net