#clojure log - Nov 03 2010

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

0:12 amalloy: i'll get the hang of spelling my name one of these years :P

0:18 quizme: when i (run-tests 'myproject.core) i get, 0 failures, 0 errors.

0:18 but there is a test there.

0:18 shouldn't there be at least 1 failure ?

0:19 http://www.pastie.org/1268633

0:21 amalloy: quizme: (run-tests 'collatz.test.core)

0:21 quizme: amalloy thanks i'll try

0:23 amalloy: awesome thank you

0:23 amalloy: np. maybe one of these days i'll get around to learning how to use clojure.test myself :P

1:01 _na_ka_na_: hellos.. how do I override equals, hashcode using deftype?

1:05 (defprotocol P (foo [this]) (^boolean equals [this ^Object o]))

1:06 (deftype T [] P (foo [this]) (^boolean equals [this ^Object o]))

1:07 gives an error

1:07 java.lang.VerifyError: (class: user/T, method: equals signature: (Ljava/lang/Object;)Ljava/lang/Object;) Expecting to find object/array on stack (repl-1:37)

1:08 maybe this is the right way

1:08 (deftype T [] P (foo [this]))

1:08 (deftype T [] P (foo [this]) Object (equals [this o]))

1:08 amalloy: _na_ka_na_: i just tried (deftype x [] Object (equals [this other] true)) and it works for me

1:09 _na_ka_na_: amalloy: yes thx

1:09 I figured

1:20 amalloy: how can i add static methods to my deftype which can called as T/a-static-fn

1:20 amalloy: _na_ka_na_: why would you want to? just use a defn

1:21 _na_ka_na_: amalloy: hmm you're right

2:06 I have a bunch of protocols P1, P2, P3 ... it is possible to have master protocol P which is the union of P1, P2, P3

2:08 for example I want my abstraction to be a union of a protocol I wrote P + Serializable + Comparable

2:10 amalloy: _na_ka_na_: would you mind explaining why you're doing this? it kinda smells like using clojure to write java, and there might well be an easier way than these protocol gymnastics

2:14 _na_ka_na_: amalloy: I want an abstraction which comprises of a set of operations i define + i want it to be serializable + so i can use it in sorted-sets (which is really TreeSet and so Comparable)

2:14 how do you think i define that abstraction?

2:15 do I even need an abstraction is a separate concern :)

2:17 amalloy: _na_ka_na_: what about (deftype MyThing [] P Commparable Serializable) and require callers to extend MyThing?

2:17 i don't do a lot of java interop, so this may be a crazy suggestion

2:34 _na_ka_na_: amalloy: but deftype doesn't define an abstraction

3:22 octe: what's the best way of finding memory leaks in clijyure programs?

3:22 clojure*

3:23 kryft: ...Memory leaks in clojure programs? How do you get a memory leak with garbage collection?

3:23 octe: no idea.

3:23 i'm quite curious about it myself.

3:28 i'm quite curious about it myself.

3:28 oops

3:37 eugu: kryft: This way - you accidentally retain references to the objects which are not used in your program anymore. If this occurs regularly it accumulates and can cause OutOfMemory

3:37 albino: holding references will usually do it

3:37 http://www.eclipse.org/mat/

3:38 kryft: eugu: Ok, if that counts as a memory leak. :)

3:38 albino: kryft: it does, because memory is leaked that should be free()d

3:39 kryft: Does that happen easily in clojure then?

3:39 albino: Happens often enough in java, I don't know fo clojure

3:41 happens in python too

3:42 octe: you could try that tool I linked to, I think it's works for jvm implementations and so could work for clojure code

3:42 octe: i'm trying jmap / jhat, built into the jdk

3:47 hmm, that didn't give much useful information..

3:48 angerman: is there a list somewhere what charactes are allowd as symbol names/

4:27 LauJensen: Morning

4:38 LuminousMonkey: Afternoon. :P

4:57 angerman: how do I create a root var?

5:08 _na_ka_na_: guys can you let me know if this is a bug

5:08 (deftype T [] Object (equals [this o] (if (instance? T o) true false)))

5:09 (def t (T.))

5:09 (.equals t t) => false

5:09 I'm on 1.2

5:11 esj: maybe: (instance this o)

5:11 in the (if )

5:12 wait.....

5:12 it looks like you're checking if things are of the same type instead of equality. Did you mean to ?

5:12 jarpiain: or (instance? (identity T) ...)

5:14 sharat87: hello, I want to do an operation on every key-value pair in a map, is there a function for that in clojure or contrib?

5:15 _na_ka_na_: esj: this is just a dummy to reproduce the issue

5:15 jarpiain: ,(into {} (map (fn [[k v]] [k (* 2 v)]) {:a 1 :b 2 :c 3}))

5:15 clojurebot: {:a 2, :b 4, :c 6}

5:16 _na_ka_na_: jarpain: why (identity T) ?

5:16 jarpiain: the compiler has a special case for identity? when the first argument is a symbol that resolves to a class

5:17 _na_ka_na_: jarpain: but (instance? T o) should work as (doc deftype) specifically says that I can use the deftype name inside its methods

5:17 jarpiain: _na_ka_na_: did you try it?

5:17 _na_ka_na_: oops its jarpiain, sorry

5:18 jarpiain: currently I have (= T (class o)) and that works

5:18 sharat87: oh so I can use the map function on maps too, that's an eye opener

5:19 jarpiain: is that anonymous function using pattern matching to unpack a vector in its first argument?

5:19 _na_ka_na_: sharat87: you can also do (zipmap (keys m) (map (partial * 2) (vals m)))

5:19 sharat87: yeah, but in the function I need both the key and the val :)

5:20 _na_ka_na_: oh ok :)

5:20 jarpiain: _na_ka_na_: while compiling the deftype, T resolves to a different class object (a compiler-generated stub class)

5:20 _na_ka_na_: then (map (fn [[k v]] ...) m)

5:20 jarpiain: which might conflict with the special inlining of instance?

5:20 sharat87: yeah, that's what I need then :) thanks jarpiain and _na_ka_na_

5:21 _na_ka_na_: jarpiain: hmm that might explain it, but its a bug then ?

5:21 esj: sharat87: btw, what that pattern matching is called destructuring in clojure (and there's lots you can do with it) just in case you want to google it

5:22 sharat87: esj: ah thanks for clearing that, as you might have guessed by now, I come from haskell :)

5:23 _na_ka_na_: sharat87: welcome :) how did you venture here

5:24 sharat87: browsing peepcode, I came across the clojure video, impressed, here I am :)

5:24 awesome video btw

5:30 _na_ka_na_: jarpiain: one more thing, (source +) tells us that it is inlined, but (source instance?) doesn't; how did you it might be inlined

5:30 jarpiain: _na_ka_na_: it's a really special case. You have to look at Compiler.java

5:31 _na_ka_na_: jarpiain: ok, thanks

5:33 fliebel: Raynes: I've had my Hammock time, I'm ready for it!

5:33 jarpiain: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L3298

5:33 LauJensen: Guys, does this interface seem intuitive? https://gist.github.com/d835630aff8313980813

5:34 fliebel: LauJensen: Why the set?

5:34 LauJensen: fliebel: Which alternative did you have in mind?

5:35 fliebel: LauJensen: I'm thinking...

5:36 bsteuber: LauJensen: I do like maps (and would expect an implicit and for more than one entry), but would rather like explicit and and or instead of sets and vectors

5:36 I also commented on the :invert keyword on github a minute ago

5:37 LauJensen: bsteuber: Yes thanks I got the notification

5:37 So you should prefer [:x 5 :or :y 10] ?

5:37 fliebel: LauJensen: Yea, more like the ns thing. [a :or b

5:37 LauJensen: But wouldnt it be better simply to write pure SQL ?

5:37 esj: intuitive

5:38 angerman: (defprotocol Fly "for flying" (fly [this] "..."))

5:38 that's the specification / contract right?

5:39 LauJensen: esj: what is?

5:39 angerman: (defrecord [a] Fly (fly [self] (str (:a self) " flies ..."))) should work. no?

5:39 fliebel: LauJensen: O second thought, I think it should at least be polish notation, so [:or 1 2 3]

5:39 bsteuber: LauJensen: how about (or {:foo 42} {:bar "baz"})?

5:39 angerman: but it tells me "self" not found in context

5:39 esj: the #{}, [], {} interface

5:40 LauJensen: bsteuber: I wont implement the List interface, that'll rob users of too much power

5:40 bsteuber: well, [:or] seems fine as well

5:41 LauJensen: ok, thought of it as plain functions - but I didn't look at your internals

5:42 LauJensen: bsteuber: The old ClojureQL grabbed all of your Lisp syntax, and made everything (and (> :x 5) (or (< :y 10) (:z 15))) style notation. But that turned out to be a bad idea... I realized after 2.5 yers

5:42 years

5:42 bobo_: hm, why have one map for each statement? and not {:rank "Top" :title "Dev}

5:44 LauJensen: bobo_: The statements are separated, so it makes to show that in the data structure dont you think?

5:46 bobo_: hm, maybe

5:46 Chousuke: hm

5:46 bobo_: it makes more sense in the or example

5:46 LauJensen: bobo_: You can do both though. The compiler is recursive, so its your choice

5:47 clojureql.core> (compile {:rank "top" :title "dev"})

5:47 "rank=top AND title=dev"


5:47 Chousuke: I think it's got maybe a bit too much syntax :P

5:47 LauJensen: Chousuke: Suggestions?

5:47 clojurebot: Huh?

5:48 Chousuke: that case is good though. but for the OR case having to wrap each thing in a map might get boring pretty quickly

5:48 bsteuber: LauJensen: but can't you implement a function and that returns [:and ..] then?

5:48 fliebel: "To many notes" "Which notes did you hand in mind?" - Mozart

5:48 bsteuber: so people could still use list notation but don't lose power

5:49 LauJensen: bsteuber: Sure its possible with a helper

5:49 fliebel: bsteuber: macroes are icing ;)

5:49 Chousuke: with that syntax you could save lists for "user-defined" things I suppose

5:50 LauJensen: Well. I dont want lists in the protocol, that would break {:x 5 :y (let [z ...] z)}

5:50 Chousuke: like [{:id 5} (like :foo "something")] where like returns something that the compiler can handle

5:50 yeah

5:52 LauJensen: I'll try to follow the data-structure trail to the end. Then it might be macro/helper time :]

5:52 Chousuke: I'd be wary of using #{} though

5:52 since the order is undefined

5:52 LauJensen: Chousuke: Order doesnt matter for OR statements

5:53 Chousuke: until you hit some weird corner case where it does ;P

5:54 LauJensen: Yea I guess you're right.

5:55 Chousuke: but if you reserve () for things that are evaluated, it should be easy to implement cql/and and cql/or that you can use in queries

5:55 in addition to perhaps having syntax for them

5:55 bsteuber: I would be in for [:or …] etc then

5:55 LauJensen: yea

5:56 bsteuber: maybe then also [:not] for invert

5:56 though I still like select-not :)

5:56 LauJensen: :invert is a bit counter-intuitive "read this, then totally reverse your understanding" :)

5:56 bsteuber: exactly :)

5:56 Chousuke: maybe have a basic set of compiler operations like :and :or :not and then just have [operator parameters*]

5:58 users wouldn't necessarily have to use that form directly, but it might make sense for the compiler to reduce everything to such vectors before further processing

5:59 LauJensen: Chousuke: Can you gist an example of how you see this playing out?

6:02 jjido: wrt using structures isn't this more readable? https://gist.github.com/559c305e432ff0b0e41e

6:03 LauJensen: jjido: For me its the same, but like I said before, the protocol doesnt do lists

6:03 jjido: ok use a different keyword then

6:09 Chousuke: LauJensen: https://gist.github.com/6fec4a139a299dc17627 ?

6:09 bsteuber: Chousuke: huh, don't like :eq

6:10 I think maps are fine for k/v-pairs

6:10 Chousuke: bsteuber: it could be an implementation detail

6:10 LauJensen: bsteuber: as a user, you would use (= ...

6:10 Chousuke: Looks interesting. I'll play around a little and see what comes out. Thanks for your input

6:11 Chousuke: in the sugared form I did use the map thing so I think it's fine.

6:11 bsteuber: ah, sorry, didn't look at the sugared one

6:11 yeah, seems cool

6:12 Chousuke: I think compile could support some of the sugar directly, so that user functions wouldn't have to worry about desugaring maps for example

6:13 so cql/and could just return [:and {'rank "top"} ...] and the compiler would handle that.

6:13 bsteuber: but then you don't need :eq at all, I guess :)

6:13 Chousuke: it might make the implementation easier

6:14 LauJensen: Yea thats how I imaged I would do it

6:14 Chousuke: and users could still use the compiler ops directly in their own functions

6:18 bobo_: LauJensen: the idea behind clojureql is to abstract away the parts that differ between databases right?

6:19 LauJensen: bobo_: That was the old idea. The revised idea, which I might blog about today, is just to have some slick integration, where the differences between backends are left to the user

6:21 bobo_: ok, please do blog! :-)

6:22 jjido: https://gist.github.com/559c305e432ff0b0e41e

6:22 LauJensen: Yes sir :)

6:23 jjido: Thats definitely not bad

6:24 jjido: LauJensen: inspired by SQL ;)

6:24 LauJensen: Who needs hammock time when you've got #clojure :)

6:25 bobo_: hm, so [] is or in that example?

6:25 LauJensen: yea

6:25 bobo_: think i like it

6:25 fliebel: LauJensen: I do, but I do that when I'm not in #clojure (sleeping)

6:26 bobo_: i wrote a method that converts all OR to UNIONS yeasterday, things like that would be great to have in clojureql aswell

6:27 LauJensen: Got gist?

6:27 bobo_: no it was java :-(

6:27 LauJensen: ouch

6:28 bobo_: yeh i know. but my sql library at work is getting pretty nice, should write it in clojure for fun.

6:28 jjido: LauJensen: do you need nested AND? https://gist.github.com/559c305e432ff0b0e41e

6:28 LauJensen: does not look as good

6:29 LauJensen: You're competing against whats already there

6:29 clojureql.core> (compile #{{:rank "Top"} {:title "Dev" :id 5}})

6:29 "(rank=\"Top\" OR title=\"Dev\" AND id=5)"


6:30 Though the parens needs fixing

6:30 I think your model is showing some code explosion tendencies

6:48 ariejan: Maybe a stupid question, but is there anything in Clojure to get a current timestamp?

6:49 LauJensen: &(-> "x.y" (.split ".") first)

6:49 sexpbot: ⟹ nil

6:50 LauJensen: Am I forgetting my Java-fu, shouldnt that return x ?

6:50 bobo_: split takes a regexp?

6:50 or?

6:51 LauJensen: bobo_: Ah right, Regex AS string :)

6:51 &(-> "x.y" (.split "\\.") first)

6:51 sexpbot: ⟹ "x"

6:51 bobo_: :-)

6:51 LauJensen: ariejan: try (java.util.Date.)

6:51 esj: ariejan: I just go to java with (java.util.Date.)

6:51 pffft

6:51 LauJensen: esj: aaah just a wee bit too slow

6:52 :D

6:52 ariejan: I just found: (. System (nanoTime))

6:52 LauJensen: &(System/nanoTime)

6:52 sexpbot: ⟹ 185913853697964

6:53 ariejan: Exactly. It's just to use some unique value for testing redis performance.

6:53 bobo_: &(Math/random)

6:53 sexpbot: ⟹ 0.698805992174627

6:54 LauJensen: bobo_: unique != random

6:54 bobo_: true

6:55 LauJensen: &(java.util.UUID/randomUUID)

6:55 sexpbot: ⟹ #<UUID d8ec9da7-ea94-430f-8292-fc802a198180>

6:55 LauJensen: 100% concurrency safe

6:57 bobo_: i also think redis already has a testsuite for performancetesting. but thats not as fun

6:58 ariejan: bobo_: Yes, but I wanted to see clojure aleph in combination with setting a key per request. It's blazingly fast. 0.977ms per request on average on my i5 macbook pro.

6:59 bobo_: :-)

7:00 LauJensen: ariejan: With how many concurrent requests?

7:01 ariejan: 50 concurrent requests.

7:01 But I see only 8 redis clients connecting. See details here: https://gist.github.com/660970

7:02 LauJensen: wow

7:03 ariejan: LauJensen: With 8 concurrent requests I get 0.739ms/req. (1354 req/sec)

7:03 If there's any optimalisations I can do in my code, please let me know.

7:04 LauJensen: Could you regist the code, I just logged in/out

7:04 ariejan: LauJensen https://gist.github.com/660970

7:13 What is the reason I see 8 clients connecting to redis? Is that a clojure config option, jvm?

7:17 LauJensen: I think Aleps caps concurrent connections at 8, hence the speed. A Synced framework wouldnt cap so early

7:29 fliebel: Man, this is crazy… The Python version of my parser is 6 times faster on just reading files. And even worse, it keeps them in memory all at once. When I do this in Clojure it never finishes and takes up a massive amount of memory.

7:38 How much memory will a seq of 99844096 bytes consume? (compared to a string or a byte[] of 99844096 itmes)

7:39 jarpiain: ,(doc vector-of)

7:39 clojurebot: "([t]); Creates a new vector of a single primitive type t, where t is one of :int :long :float :double :byte :short :char or :boolean. The resulting vector complies with the interface of vectors in g...

7:41 fliebel: jarpiain: I'll try it.

7:41 raek: fliebel: which seq type?

7:42 fliebel: raek: I do concat on the byte[]'s, so I guess it becomes a lazy seq then.

7:43 raek: a lazy seq usually constructs conses, so I guess 99844096 * the size of a clojure.lang.Cons

7:43 also, the bytes will be boxed, so they will consume more than one byte of memory

7:45 ,(class (seq (make-array Integer/TYPE 3)))

7:45 clojurebot: clojure.lang.ArraySeq$ArraySeq_int

7:46 raek: an array of primitives is probably the most compact way of storing the data, if you really need everything in memory at the same time

7:47 fliebel: raek: I don't really, but I'm trying to figure out why Clojure is 6 times slower at reading the same data Python does.

7:48 raek: fliebel: how do you do the IO? one byte at a time?

7:48 fliebel: raek: No, I use a library which returns a byte[]

7:49 raek: ok. good.

7:50 do you have both versions in gists?

7:51 fliebel: raek: On github at least.

7:52 raek: also, did you manage to get rid of the reflection? (I'm just curious)

7:52 fliebel: raek: I did.

7:54 raek: great!

7:54 fliebel: Python: https://github.com/l0b0/mian/blob/master/mian/mian.py#L244-254 Clojure: https://github.com/pepijndevos/Clomian/blob/master/src/clomian.clj#L101-119 (gets called at line 133)

7:54 raek: how much did it affect the performance?

7:55 fliebel: raek: Quite a lot. But the biggest win of the day was using a transient.

7:56 raek: has this something to do with Minecraft?

7:56 fliebel: raek: yea, analyzing levels and stuff.

7:58 raek: cool. IIRC, tomoj has coded something Minecraft-related too

8:00 is it the data processing or the IO that takes most time?

8:01 have you compared just reading data in both the clojure and python without processing it?

8:01 fliebel: raek: I have compared just getting the blocks, not the pure reading. But the functions that spit out the files are equally fast.

8:01 yayitswei: quick question: why does (map #(Integer/parseInt %) '("1" "2")) work whereas (map Integer/parseInt '("1" "2")) does not?

8:01 raek: (to rule out that the lib is the bottleneck)

8:02 Chousuke: yayitswei: Integer/parseInt is not a clojure function

8:02 raek: yayitswei: Integer/parseInt is not a real function (an onbject that implements clojure.lang.IFn)

8:02 yayitswei: ah, so the reader macro only works with clojure functions

8:03 Chousuke: no, the reader macro creates a clojure function

8:03 fliebel: raek: So I should just do the FileInputStream and read?

8:03 raek: how is the data read? is it just the bytes of the file?

8:03 Chousuke: #(Integer/parseInt %) expands to something like (fn [x] (Integer/parseInt x))

8:03 which map can use

8:04 fliebel: raek: it's gzipped, but then it's just bytes I believe.

8:04 raek: ...which expands to something like (fn [x] (. Integer parseInt x))

8:05 yayitswei: oh, right.. so how does the (. Integer parseInt x) work then?

8:05 raek: well, if the java lib was as fast as the python lib, this will not make any difference, right?

8:05 yayitswei: it is a special form, handled specially by the compiler.

8:06 yayitswei: i see. thanks guys

8:09 raek: fliebel: does the time include the JVM startup delay too?

8:09 fliebel: raek: no :P

8:10 raek: good... saw the -main method and started to get suspicious

8:10 fliebel: raek: nah, did a (time) on the repl

8:11 raek: gtg, I'll test it later. thanks :)

8:55 tonyl: morning

9:16 djpowell: has anyone had a look at microsoft's reactive stuff? i was just playing around doing similar stuff in clojure the other day. it looks pretty cool

9:19 chouser: djpowell: rhickey recommended understanding it recently.

9:19 djpowell: yeah - i saw that

9:20 noidi: djpowell, do you have an URL for that? or should I just google for "microsoft's reactive stuff"? :)

9:21 djpowell: the idea is that sequence type things are the dual of observable type things that you can register with to be notified about data - they are both just sources of data, so a function can generically convert any seq to an observable, and any observable to a seq

9:21 hang on...

9:21 noidi: blimey, I think that google search actually worked

9:21 Reactive Extensions for .NET

9:22 I had to give it a try :)

9:22 djpowell: http://rxwiki.wikidot.com/101samples is a good way to get a quick summary of what you can do with it

9:22 noidi: djpowell, thanks!

9:24 djpowell: like clojure, microsoft do lots of things with sequence abstractions - eg LINQ lets you do map/filter higher-order function type stuff with them with an SQL-like syntax. Plus lots of things can be seen as having observable events - Desktop UIs, incoming AJAX requests etc; so bringing the two together seems pretty powerful

9:25 Bahman: Hi all!

9:25 djpowell: hi

9:38 pjstadig: re: "reactive stuff" ...i saw a pres on that at the CUFP looked interesting

9:42 fogus_: pjstadig: Matt P at the CAPCLUG is one of the lead devs... you should corner him about it one day. Very interesting ideas

9:48 pjstadig: fogus_: he hasn't been in a while has he? i don't recall

9:49 fogus_: I haven't been in a while either. :-(

11:40 bhenry: what if i want to pull together a handful of imports into one namespace, and then just be able to (:use namespace]) in multiple (ns) calls?

11:41 and have access to all those imported classes

11:41 tonyl: have you tried it?

11:42 bhenry: it doesn't work. i'll show you what i tried in a gist

11:46 fliebel: raek: I tired the file reading thing, and it takes 1961.726 msecs, so I'm afraid it's the NBT library.

11:48 bhenry: tonyl: https://gist.github.com/b16af68b7e6482734992

11:48 pjstadig: bhenry: checkout nstools

11:49 i think that might do what you want

11:49 http://code.google.com/p/clj-nstools/

11:52 bhenry: pjstadig: thanks. looks like i can't avoid having two lines where i want one. i'm just being picky. mine has the (use-karras) after the ns call and that has (use 'nstools.ns) before it.

11:54 tonyl: yeah bhenry, I wouldn't know much about namespaces, but it seems that the ns+ function in nstools might help you

11:56 fliebel: How can I get the entire content of a GZIPInputStream?

11:57 pjstadig: clojure.contrib.io/to-byte-array?

11:57 clojurebot: Yes, Clojure can do that!

11:57 pjstadig: clojurebot: botsnack

11:57 clojurebot: thanks; that was delicious. (nom nom nom)

12:01 fliebel: pjstadig: That might work. What is the classic java way to do that?

12:02 pjstadig: uh...why would you want to do it in java?

12:02 it'll set your hair on fire

12:02 hiredman: to-byte-array is bad

12:02 fliebel: To understand how it works.

12:02 pjstadig: you have to use an apache commons library to make it let painful

12:02 fliebel: and because of what hiredman said ;)

12:02 pjstadig: hiredman knows nothing

12:02 joegallo: No! You have to build a ByteArrayOutputStream and copy over the bytes like a boss!

12:02 hiredman: last I checked to-byte-array shoves things into a StringBuilder then calls getBytes on the String

12:02 horrible

12:03 pjstadig: oh

12:03 hiredman is correct

12:03 but otherwise you have to copy chunks across like joegallo says

12:03 tonyl: anybody knows of any clojure groups in kansas?

12:04 hiredman: (with-open [baos (ByteArrayOutputStream.)] (copy gzipstream baoas) (.toByteArray baos))

12:04 joegallo: fliebel: Like this: http://stackoverflow.com/questions/67275/reading-from-a-zipinputstream-into-a-bytearrayoutputstream

12:05 pjstadig: hmm...looks like to-byte-array uses a BAOS http://bit.ly/addDYt for InputStreams

12:05 fliebel: hiredman: Where does copy live?

12:05 hiredman: clojure.java.io

12:06 fliebel: great

12:13 rata_: hi all

12:13 hiredman: actually my local checkouts of clojure and contrib don't seem to have to-byte-array in them

12:18 rata_: do you know what's the line to put fnparse 3.x as a dependency in project.clj?

12:19 edoloughlin: Anyone care to shed some light on destructuring forms? http://stackoverflow.com/questions/4089162

12:26 Bootvis: ,`(foo bar)

12:26 clojurebot: (sandbox/foo sandbox/bar)

12:26 Bootvis: is it possible to not display the namespace in the above?

12:27 rata_: Bootvis: why do you want such a thing?

12:27 MayDaniel: ,`(~'foo ~'bar)

12:27 clojurebot: (foo bar)

12:27 Bootvis: rata: i'm working through land of lisp in clojure

12:27 rata_: namespaces are important for macros hygenie IIRC

12:28 Bootvis: MayDaniel: thanks maybe I can put that transformation in a macro

12:48 rata_: do you know what's the line to put fnparse 3.x as a dependency in project.clj?

12:54 fliebel: rata_: http://clojars.org/search?q=fnparse

12:54 rata_: fliebel: oh, thanks a lot =)

12:54 fliebel: raek: Are you still around?

12:56 alpheus: Is there a predicate for atom? (I just realized that the obvious meaning of that for a Scheme or Lisp programmer would not apply in Clojure.)

12:57 tonyl: clojure.inspector/atom?

12:57 clojurebot: "[Clojure ...] feels like a general-purpose language beamed back from the near future."

12:59 amalloy: alpheus: there was a longish discussion of this yesterday

12:59 clojurebot: logs?

12:59 clojurebot: logs is http://clojure-log.n01se.net/

12:59 tonyl: http://clojuredocs.org/clojure_core/clojure.inspector/atom_q

12:59 alpheus: Sorry, I didn't see that. I'll review.

12:59 tonyl: the one in inspector just checks if it is not an atom

13:00 amalloy: tonyl: heh, i guess that's one way to do it. personally i'd use (not (coll? x)) directly, but whatever

13:00 tonyl: s/atom/coll/

13:00 sexpbot: <tonyl> the one in inspector just checks if it is not an coll

13:01 tonyl: sexpbot: cool

13:01 amalloy: yeah, beats requiring a ns

13:02 mabes: when I call class on a double does it automatically get coerced into a Double?

13:02 ,(class (double 1.0))

13:02 clojurebot: java.lang.Double

13:02 mabes: (I'm using 1.2)

13:03 I'm dealing with some java interop and I need to pass in an array of doubles (not Doubles). I can't seem to do that though...

13:03 ,(into-array (map double [1.0 2.0]))

13:03 clojurebot: #<Double[] [Ljava.lang.Double;@1280c85>

13:03 mabes: any ideas?

13:03 amalloy: &(make-array Double/TYPE 10)

13:03 sexpbot: ⟹ #<double[] [D@f9de08>

13:04 amalloy: &(into (make-array Double/TYPE 10) (map double (range 10)))

13:04 sexpbot: java.lang.ClassCastException: [D cannot be cast to clojure.lang.IPersistentCollection

13:04 amalloy: oh well :P

13:04 mabes: amalloy: thanks! I'll try to figure it out from here.

13:05 actually..

13:05 ,(into-array Double/TYPE [1.0 2.0])

13:05 clojurebot: #<double[] [D@1283826>

13:05 amalloy: yeah, i just found that too

13:05 mabes: cool, yeah, I didn't know about the Double/TYPE thing until you showed me

13:06 amalloy: &String/TYPE

13:06 sexpbot: java.lang.Exception: Unable to find static field: TYPE in class java.lang.String

13:06 amalloy: only primitives have this sugar to get at their class

13:07 alpheus: tonyl: clojure.inspector/atom? is kind of like the Lisp or Scheme version. I was thinking more about clojure.lang.Atom. Then I remembered that class tells me that.

13:09 amalloy: alpheus: you can generalize with (instance? clojure.lang.IDeref (class foo))

13:09 if you want to just check whether @foo is legal

13:09 alpheus: oh, nice

13:13 Shouldn't that be: (instance? clojure.lang.IDeref foo)

13:16 amalloy: oh

13:16 yeah i guess

13:18 bhenry: is there something that (this-thing "string") will make clojure think it's dealing with a file?

13:19 amalloy: bhenry: java has StringReader - probably some clj analogue

13:19 LOPP: if I have a bunch of calculations that I'd like to start each in its own thread how would I do it?

13:20 amalloy: LOPP: pmap or manage futures yourself

13:20 LOPP: ,(doc pmap)

13:20 clojurebot: "([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless requir...

13:21 kriyative: @bhenry: do you mean something like: with-in-str?

13:21 bhenry: ,(doc with-in-str)

13:21 clojurebot: "([s & body]); Evaluates body in a context in which *in* is bound to a fresh StringReader initialized with the string s."

13:23 alpheus: ,(doc with-out-str)

13:23 clojurebot: "([& body]); Evaluates exprs in a context in which *out* is bound to a fresh StringWriter. Returns the string created by any nested printing calls."

13:23 bhenry: kriyative: i'm not sure. i'm using line-seq on a file and want to know if i can use a string and pretend it's a file in my tests

13:24 amalloy: bhenry: you should be able to

13:24 kriyative: @bhenry: yes, you can use (with-in-str "some string" (line-seq *in*))

13:24 bhenry: ah cool.

13:25 kriyative: @bhenry: also look at with-open, if you don't want *in* to get rebound

13:32 LOPP: what's that string replace function again

13:32 re-something I think

13:32 chouser: clojure.string/replace

13:41 LLLLO: I tried (ns myproj.wiki

13:42 (:require (clojure.string replace)))

13:42 doesn't work :(

13:43 also when I say "lein swank" in project folder, it doesn't actually load anything into repl instance, why's that

13:48 nishant: ,1

13:48 clojurebot: 1

13:51 fliebel: Is there a clojure-contrib for use with clojure 1.3?

13:53 cemerick: alpha contribs have been released in conjunction with clojure alphas

13:55 fliebel: cemerick: Never mind, cake is completely flipping when I use it. I just wanted to see if it ran and if it ran faster.

13:56 LLLLO: I'm officially completely confused about build tools and namespaces

13:56 this stuff never works like it should

13:56 amalloy: LLLLO: namespaces can be confusing

13:57 cemerick: LLLLO: build tools and namespaces have nothing to do with each other?

13:57 amalloy: require only loads the functions, it doesn't create shortcuts for getting at them

13:57 LLLLO: I have a leinigen project. I go to project folder, I run "lein swank". I run emacs, then I run slime-connect in it

13:57 amalloy: so after (:require (clojure.string replace)), you could (clojure.string/replace ...)

13:57 LLLLO: I go to one of my project namespaces and the symbols aren't there

13:58 amalloy: LLLLO: lein swank doesn't load any clj files. it just starts a server for emacs to load stuff into. C-c C-k will compile a file and load it into the running swank server

13:58 * cemerick isn't qualified to provide slime or lein advice :-)

13:58 LLLLO: also stuff like (:require (clojure.string replace)) doesn't even work for me

13:58 so basically I have to manually open and compile all my stuff in emacs?

13:58 cemerick: LLLLO: your environment is borked somehow

13:59 amalloy: LLLLO: yes it does, you're just using it wrong. instead of "it doesn't work", provide a snipped of something you think should work and doesn't

13:59 technomancy: LLLLO: if you want a namespace to be loaded when your repl or slime starts, set :repl-init-script in project.clj

13:59 I think you need the latest swank snapshot for that

14:00 LLLLO: (ns ircbot.watch.wiki

14:00 (:require (clojure.string replace)))


14:00 this for instance

14:00 lrenn: (use 'ircbot.watch.wiki) right?

14:00 cemerick: replace is a function, not a namespace

14:00 LLLLO: ok

14:00 cemerick: (:require clojure.string)

14:01 and then code can use (clojure.string/replace …)

14:01 LLLLO: what if I have multiple

14:01 requires

14:01 cemerick: (:require clojure.string clojure.set clojure.contrib.graph), whatever

14:01 amalloy: or i seem to recall (:require (clojure core string set)) works

14:02 LLLLO: thanks it works now

14:02 cemerick: LLLLO: read (doc require)

14:02 LLLLO: when do I need to use quotation when naming namespaces?

14:02 cemerick: only outside of an ns form

14:02 e.g. at the REPL

14:02 LLLLO: oh ok

14:03 amalloy: cemerick: honestly the documentation on namespaces is really confusing. i've read (doc require) a lot of times, and i still have to look up the syntax every time; plus it doesn't mention the difference between [] and () in (:use) forms

14:03 noidi: is there a difference?

14:04 cemerick: amalloy: http://clojure.org/libs *shrug*

14:04 noidi: and if not, which form is preferred?

14:04 I've used vectors so far, as in (:use [clojure.string :only [replace]])

14:04 cemerick: noidi: parens define a prefix, brackets are an explicit libspec, allowing you to use :as, :only, :rename, etc

14:04 LLLLO: ok

14:05 here's a brain teaser

14:05 noidi: cemerick, ok, thanks.

14:05 amalloy: cemerick: okay, lovely. this page is much better than (doc require)

14:06 LLLLO: I have a string that's all lowercase. Instead of spaces I have _. It can also have ' or -. I'd like to have first letter of each word capitalized. Stuff after - or _ is a new word but not after '.

14:06 noidi: I used to hate the ns macro until I learned the most common invocations. before that I had to copy & paste snippets from other codebases and modify them :P

14:07 LLLLO: a_snake's_mumbo-jumbo -> A_Snake's_Mumbo-Jumbo

14:07 noidi: the error messages could be a lot better

14:07 LLLLO: looking for an elegant way to do this

14:08 fliebel: How can I concatenate multiple byte[] into one byte[]? Preferably avoiding boxing of all the bytes.

14:08 cemerick: fliebel: make-array and System/arraycopy

14:09 fliebel: cemerick: Thanks

14:10 tonyl: LLLL0: what do you have so far?

14:10 cemerick: fliebel: j.io.SequenceInputStream is also handy if you need to concatenate some InputStreams(backed by byte[] if necessary), just FYI

14:10 LLLLO: nothing tbh. I'll probably write a java function that does this

14:10 a for loop and some if sentences

14:11 amalloy: LLLLO: you'll spend way too much time on it in either java or clojure. just use built-in tools like regexes

14:11 &(string/replace "a-bc" #"([-_]\w)" #(.toUpperCase (first %)))

14:11 sexpbot: java.lang.Exception: No such namespace: string

14:11 amalloy: &(clojure.string/replace "a-bc" #"([-_]\w)" #(.toUpperCase (first %)))

14:11 sexpbot: ⟹ "a-Bc"

14:11 LLLLO: I see

14:13 amalloy: if you want to capitalize the beginning of the string too:

14:13 &(clojure.string/replace "na-bc" #"(($|[-_])\w)" #(.toUpperCase (first %)))

14:13 sexpbot: ⟹ "na-Bc"

14:13 LLLLO: I wasn't aware I can use replace like that

14:13 amalloy: &(clojure.string/replace "na-bc" #"((^|[-_])\w)" #(.toUpperCase (first %)))

14:13 sexpbot: ⟹ "Na-Bc"

14:13 amalloy: String.replace takes regexes, and the clojure wrapper around that allows functions as replacements

14:14 LLLLO: so basically you get a vector into that function

14:14 of the match

14:14 and you can return what you want, which gets replaced for the match

14:14 amalloy: yeah. first element is the match, further elements are the capturing groups, if any

14:15 LLLLO: and what you return replaces whole match? or is there an option of specifying replacement for each group

14:15 amalloy: &(re-seq #"((^|[-_])\w)" "na-bc")

14:15 sexpbot: ⟹ (["n" "n" ""] ["-b" "-b" "-"])

14:15 LLLLO: btw you can make non-capturing groups

14:15 amalloy: you get passed that vector, and can do anything you want to it to create a string to replace into

14:15 yeah i know

14:15 LLLLO: (?: )

14:17 amalloy: but when i don't care what's in any of the groups, marking them as non-capturing just clutters everything up

14:17 LLLLO: I hear it works faster

14:17 amalloy: yep

14:18 sexpbot: let me know if you're getting tired, i'll go easy

14:18 LLLLO: you can probably remove the outermost parenthesis here without any consequence

14:18 cemerick: regexes seem like a tough way to handle this...

14:18 amalloy: yeah, i can

14:18 i forgot it returns the whole match as well as the capturing groups

14:18 LLLLO: awesome stuff anyway

14:18 amalloy: cemerick: you have something easier?

14:19 LLLLO: cemerick: do you have a good idea?

14:20 cemerick: well, regexes will *work*, but you're drifting into read-only territory

14:20 one sec

14:21 amalloy: it's true that it's easy to abuse regexes. i'm guilty of that myself

14:21 LLLLO: what do you mean about drifting into read-only territory

14:22 amalloy: LLLLO: regexes are a lot easier to write than read

14:22 LLLLO: oh yes

14:22 I have a regex in my irc bot that recognizes questions

14:22 messy stuff

14:23 amalloy: hm, speaking of which, is there a way to set modifiers in #"" forms, as in m/myregex/x?

14:25 cemerick: LLLLO: https://gist.github.com/0af84c12661344c75114

14:25 probably more verbose than necessary

14:25 LLLLO: aha

14:27 cemerick: updated, better

14:27 LLLLO: this partition-by use on strings is a neat trick

14:27 and using set as a function

14:27 very nice

14:27 I never come up with stuff like that :D

14:27 amalloy: LLLLO: using set as a function is idiomatic

14:28 you get used to it

14:28 LLLLO: I know it's idiomatic

14:28 but I would probably make an anonymous fn that returns true or false if a delimiter

14:28 I usually think only of functions

14:29 somehow using a datastructure as an active participant doesn't ever occur to me :)

14:30 cemerick: updated again -- didn't need the second delim check because uppercasing both - and _ is a no-op :-)

14:30 amalloy: &(filter (comp #{"bar"} :foo) [{:foo 10} {:bleh "bar"} {:foo "bar"}])

14:30 sexpbot: ⟹ ({:foo "bar"})

14:30 amalloy: LLLLO: you can compose them just like functions too

14:31 get all maps whose :foo key maps to "bar"

14:31 LLLLO: I know :) but there is a difference between knowing and routinely thinking in these terms and incorporating something in your own designs

14:31 amalloy: yeah for sure

14:31 exposure helps

14:31 cemerick: there, that's probably as good as it's going to get: https://gist.github.com/0af84c12661344c75114

14:32 LLLLO: these ->> macros also throw me a curveball :)

14:33 * cemerick is getting to be like chouser, taking up other people's challenges ;-)

14:33 amalloy: cemerick: (fn [[x & more]]) instead of #((first %)...(rest %))?

14:33 hsuh: doing (apply + [1 2 3]) is the same than (+ 1 2 3); now what if i wanted + to receive 1 argument, [1 2 3] ?

14:33 *that

14:33 amalloy: hsuh: (+ [1 2 3])...

14:33 cemerick: amalloy: sure, same thing; destructuring does come with a cost though, so I usually avoid it if I'm not actually using the let-bindings more than once.

14:33 hsuh: and the function isn't know at compile time..

14:34 LLLLO: yeah

14:34 you can also ask yourself what's faster

14:34 amalloy: &(let [f rest] (f [1 2 3]))

14:34 sexpbot: ⟹ (2 3)

14:34 amalloy: hsuh: ^^?

14:34 LLLLO: regex or splitting a string into a bunch of sublists then modifying non-mutable strings then recombining them

14:35 amalloy: LLLLO: probably the latter. regexes do the same work, they just hide it

14:35 LLLLO: it's a nice piece of code nevertheless

14:35 they probably have fewer allocations

14:35 amalloy: but who cares which is faster, most of the time

14:36 tonyl: ,(map + [1 2 3])

14:36 clojurebot: (1 2 3)

14:36 amalloy: heh

14:36 &(map + [1 2 3] [4 5 6])

14:36 sexpbot: ⟹ (5 7 9)

14:36 LLLLO: clojure really cranks it up with the memory alocation and garbage collection....your usual code creates 1000s of lists, sublist and fragments then recombines them by adding a single element each iteration resulting in boatloads of allocations more

14:36 hsuh: amalloy: hm, yeah i think that works :)

14:37 amalloy: LLLLO: it's true, but GC is optimized around the idea of lots of short-lived objects and a few long-lived ones

14:37 and clojure's functional data structures can do a lot of pointer sharing, which limits the problem

14:38 LLLLO: :)

14:38 unrelated question

14:38 is it normal that in emacs pressing TAB does autocomplete just in REPL buffer but not in file buffer

14:39 amalloy: yes

14:39 C-c TAB if you want it in the file buffer

14:39 TAB alone is for indenting

14:40 LLLLO: thanks

14:43 amalloy: i'll rebind mine to C-TAB if i ever look up how to specify non-letter keys :P

14:48 cemerick: LLLLO, amalloy: FWIW, a version based on a regex is faster in some bad microbenchmarking, but not by a ton (35% diff here) *shrug* https://gist.github.com/0af84c12661344c75114

14:49 The biggest part of the overhead is the word split, uppercasing, and concat, not the original partition or re-seq

14:49 anyway, back to work

14:50 amalloy: cemerick: i'd use replace, not re-seq, but i agree the benchmark doesn't really matter

14:50 clojurebot: dotimes?

14:50 clojurebot: Excuse me?

14:50 amalloy: clojurebot: benchmark?

14:50 clojurebot: Excuse me?

14:50 amalloy: bah

14:50 i'm sure he has something in there about how dotimes is not a benchmarking toolkit

14:52 Vinzent: Hello. What library for GAE (primarily for accessing it's datastore) you can recommend? There is so much similar libs so I am a little bit confused

14:57 rata_: amalloy: [(control tab)] IIRC

14:57 LLLLO: cemerick you could probably improve on uppercasing by typehinting

14:58 cemerick: LLLLO: that call is already hinted

14:58 LLLLO: how?

14:58 clojurebot: with style and grace

14:58 cemerick: The ^Character hint?

14:58 LLLLO: didn't see it in your first version

14:58 fliebel: Hmmm, is there something like reductions for iterate?

14:59 cemerick: LLLLO: oh, well go to the latest version :-)

15:02 fliebel: Oh well, I'll just use reduction. But… can I do a for loop with 2 seqs in parallel?

15:03 * chouser discovers bit-and-not and is deeply impressed

15:03 mfex: fliebel: can you give an example of what you want with reductions for iterate?

15:04 LauJensen: Chousuke: Your suggesting is in the compiler now, sugared (where (either (= {:a 5}) (<= {:b 10}))) = "WHERE ((a = 5) OR (b <= 10))"

15:04 suggestion

15:04 fliebel: mfex: nvm

15:05 mfex: (reductions #(+ %1 (count %2)) 0 seqs)

15:07 But what I need now is (doseq [x [1 2 3] y [4 5 6]]) to do 1,4; 2,5; 3,6

15:08 mfex: fliebel: (doseq [[a b] (map vector [1 2 3] [4 5 6])] (... a ... b...))

15:09 chouser: fliebel: currently, map is _the_way_ to walks seqs in step. map or loop/recur

15:09 fliebel: chouser: I think loop/recur might be less hacky in this case.

15:12 amalloy: fliebel: disagree

15:12 Vinzent: http://github.com/smartrevolution/clj-gae-datastore/ looks fine, but isn't it a bit outdated?

15:12 rata_: LLLLO, amalloy: also, if you use autocomplete, you can autocomplete in file buffers with tab

15:12 fliebel: amalloy: On second thought I disagree with myself as well.

15:13 amalloy: rata_: i started trying to install autocomplete a while ago, but got confused/frustrated and set it aside

15:16 puredanger: Rich's hammock talk from the conj in "pencast": http://www.livescribe.com/cgi-bin/WebObjects/LDApp.woa/wa/MLSOverviewPage?sid=R4XrwCpdzj5m

15:16 (not mine, just reposting)

15:16 rata_: amalloy: I download it from here http://cx4a.org/software/auto-complete/

15:17 and put this in .emacs: https://gist.github.com/661549

15:17 tonyl: puredanger: thanks!

15:18 mfex: fliebel: how about (reductions + (map count seqs)) instead of (reductions #(+ %1 (count %2)) 0 seqs)

15:19 fliebel: mefx: yea, good one :)

15:21 amalloy: rata_: nice, thanks. looks like it Just Works

15:21 though i haven't figured out how to use it properly yet

15:38 itistoday: what's the difference between 'seq' and 'sequence'?

15:39 MayDaniel: ,((juxt sequence seq) ())

15:39 clojurebot: [() nil]

15:39 chouser: seq never returns an empty collection. It returns an ISeq or nil.

15:40 ...possibly forcing a step of a lazy seq in order to determine if it's empty or not

15:40 itistoday: chouser: thanks!

15:42 rata_: amalloy: welcome =)

15:57 fliebel: Yay, an awesome array concatenation function: https://github.com/pepijndevos/Clomian/blob/master/src/clomian.clj#L101

15:58 itistoday: why can't i create a record called 'test'? it seems to conflict with clojure.core/test ... but what if the record is created in its own namespace?

15:59 fliebel: itistoday: core is always there I think. But I also think having a fn named test in your core is a bad move.

15:59 chouser: itistoday: that's fine, but you have to exclude test from being refered into your namespace

16:00 itistoday: chouser: ah, i see... using the 'ns' macro probably, thanks

16:00 fliebel: this isn't going into any production code :-p

16:02 fliebel: itistoday: I was referring to Clojure. I make functions called test all the time, because it saves thinking about a function name. So this is accidental hacking complexity :(

16:02 raek: itistoday: (ns foo.bar (:refer-clojure :exclude (test)))

16:02 fliebel: any luck with the gzipped streams?

16:03 fliebel: raek: yes and no. Reading just the files was quick, so I figured the lib was to blame but...

16:03 itistoday: fliebel: ah gotcha :-)

16:04 raek: thanks!

16:04 fliebel: I made a function for concatenating java arrays to save memory, and then it seemed to run faster, so it might have been the casting and boxing that was causing trouble.

16:04 raek: I guess you code would benefit from the new goodies in 1.3

16:05 fliebel: raek: Now the bottleneck moved up to the freqs function.

16:06 raek: cake flipped completely when I tried to get that. Can you give me the correct version number for core and contrib?

16:07 I did 1.3.0-SNAPSHOT for core, and the same but with 1.2 for contrib, but I guess that was wrong :(

16:07 raek: there is 1.3.0-alpha2

16:07 see http://build.clojure.org/releases/

16:08 contrib is now split into multiple jars

16:08 but there is a version containing everything

16:08 fliebel: I made this once: https://gist.github.com/661631

16:09 it is probably not as performant as you would like

16:09 since it uses lazy seqs

16:10 fliebel: raek: But what do I enter for contrib now?

16:10 * raek digs through the mail list

16:10 fliebel: oh well, I'm not even using anything from contrib at the moment.

16:11 defn: http://tinyurl.com/38agqgm <--- a "Pencast" of Rich's talk "Step Away from the Computer"

16:11 chouser: defn: I looked at that. Seems like a fun device.

16:12 nickik: does anybody know when the videos are releaved

16:12 raek: hrm, was it "complete" or "standalone"...

16:13 fliebel: raek: cake still goes crazy as soon as I start it.

16:13 raek: standalone

16:13 http://build.clojure.org/releases/org/clojure/contrib/standalone/

16:13 defn: yeah, it's interesting. i think they're marketing is off, though. they need to be focusing more on geeks, hacker conferences, etc.

16:14 @chouser^

16:14 they're => their

16:15 raek: fliebel: I don't use cake, but maybe you have to restart its jvm

16:16 fliebel: raek: It seems there have been a few 1.3 fixes on github. I'm getting that now.

16:16 raek: does cake have separate jvm processes for cake stuff and user stuff, à la lein?

16:16 itistoday: is there a contrib thing for creating records with default values?

16:16 fliebel: raek: What will I gain from Clojure 1.3?

16:16 raek: itistoday: you usually make a factory function for that

16:17 itistoday: raek: ah ok

16:17 just wondering...

16:17 there's this interesting post: http://cemerick.com/2010/08/02/defrecord-slot-defaults/

16:17 raek: fliebel: the ability to use unboxed promitives across function boundaries

16:17 nickik: @itistoday look at defrecord2 on github

16:18 they are like super records

16:18 raek: fliebel: http://www.assembla.com/wiki/show/clojure/Enhanced_Primitive_Support

16:18 itistoday: nickik: thanks, i take it you're referring to: https://github.com/david-mcneil/defrecord2 ?

16:19 raek: I'll be away for a moment. bbl.

16:19 fliebel: raek: Looks like exactly the thing I need.

16:19 nickik: yes, but they do not support default values

16:22 amalloy: raek: yes, cake has two jvms

16:23 (and they're used for cake-stuff vs user-stuff)

16:25 raek: fliebel: http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly

16:26 the article contains measurements of various methods for doing io in java

16:27 the gisted code uses "BufferedInputStream, 8k buffer, varying array read size" (as long as you pass it a BufferedInputStream)

16:28 fliebel: hrm... do you know if the stream is buffered? if not, you should definitely try to wrap in one... (java.io.BufferedInputStream. the-stream)

16:31 fliebel: raek: I don't know. They're using some weird input streams over there.

16:35 wtf, cake is giving ssl errors...

16:35 raek: if adding it has a large effect, they probably don't

16:36 fliebel: raek: I can't test untill I have cake running again :(

16:36 tcepsa: Are there any known issues with lein compile in Windows? I have a project that compiles fine in Linux, but throws a "Don't know how to create ISeq from: Clojure.lang.Symbol (with_ns.clj:1)" at the Windows command line

16:39 Though now that I look more closely, I see that I am using version 1.3.1 on Linux and--apparently--1.1.0 on Windows. I'll see whether upgrading helps.

16:41 fliebel: Can any cake expert tell me why I'm getting SSl errors for a build tool? Is cake trying to get something from Github, and failing because of their move to https?

16:41 crowbar7: Doesn't clojurebot do something with pastebin?

16:42 .pastebin

16:42 hiredman: http://www.delicious.com/clojurebot/pastbin

16:43 crowbar7: thanks

16:44 So he saves links it looks like

16:44 tcepsa: fliebel: I am no cake expert, but that seems reasonable; I'm having similar problems attempting to pull down the latest version of Leiningen with lein self-install

16:44 arkh: is it possible to build a string and pass it to #"" ?

16:45 LLLLO: don't think so

16:45 crowbar7: not that's a cool feature

16:45 LLLLO: you need to construct it using re-mather

16:45 crowbar7: s/not/now/

16:45 sexpbot: <crowbar7> now that's a cool feature

16:45 LLLLO: re-matcher

16:45 fliebel: arkh: … what LLLLO said

16:45 chouser: arkh: no, but you can use re-pattern

16:45 crowbar7: now that's really a cool feature

16:46 arkh: ah - re-pattern; that's what I want

16:46 fliebel: arkh: ony with the function chouser said

16:46 I'm to slow :(

16:47 * arkh hugs fliebel

16:49 amalloy: arkh: also (java.util.regex.Pattern. "some regex str"), which is what re-pattern does

16:50 ~source re-pattern

16:50 tcepsa: Upgrading to Leiningen 1.3.1 solved the issues I was having (which would not surprise me in the least if they were related to my using a more up-to-date format of project.clj...)

16:51 amalloy: or i guess it's Pattern.compile, not new Pattern

16:51 fliebel: tcepsa: I'm doing a git checkout of cake, so I think that would work without downloading stuff.

16:52 amalloy: fliebel: i don't see why. the git repo doesn't have the lib dependencies afaik

16:53 tcepsa: fliebel: Don't git checkouts download things? Or does that only happen when you clone?

16:53 fliebel: amalloy: okay, so what now?

16:54 arkh: amalloy: thanks - I was looking at that, too : )

16:55 amalloy: fliebel: can you post a gist of the error message? a fresh checkout of cake works fine for me

16:56 also maybe ping ninjudd, lancepantz, and Raynes, who are the most likely to be able to help if you find a real problem

16:58 fliebel: amalloy: http://pastebin.com/eFrTtMZA

17:02 Huh, I'm using lein now for a while but it seems my src dir isn't even on the cp...

17:04 amalloy: fliebel: sorry, ruby and cake aren't really my dept; i just fake my way through it

17:05 lancepantz: fliebel: yeah, github has been causing us some headaches

17:05 fliebel: we'll have a fix recently

17:05 s/recently/shortly/

17:05 sexpbot: <lancepantz> fliebel: we'll have a fix shortly

17:06 amalloy: but it looks like the "cake" script downloads the latest copy of cake.jar from https://github/blah if you don't already have it

17:06 fliebel: lancepantz: I'll get back to using the gem and Clojure 1.2 :(

17:06 ninjudd: fliebel: we had to change the uri to https today because github added a redirect from http to https, but i tested and it seems to work even on a machine where i have nothing in ~/.ssh

17:07 fliebel: ninjudd: Which means my ssh is seriously messed up?

17:08 ninjudd: fliebel: not sure. i'm going to create a brand new ssh key now on that machine and see if that causes it

17:08 amalloy: ninjudd: actually, i'm having some trouble getting cake.jar too, now

17:09 it gets maybe 85% through downloading it, hangs for a while, and gives up on "session expired"

17:09 ninjudd: if you are running from git, you need to pull

17:09 amalloy: i did

17:09 ninjudd: hmm

17:09 amalloy: right before i started testing fliebel's problem

17:09 and it worked then

17:09 ninjudd: amalloy: would you classify your connection as fast or slow?

17:10 amalloy: ninjudd: slowish broadband

17:10 ninjudd: i need a slow connection at work to test on ;)

17:11 amalloy: Raynes has had a similar problem, but he is on dialup. he was working on a way to mirror the file on his VPS, but i'm not sure how far he got

17:12 fliebel: raek: Whoa! Adding the buffered speeds it up quite a lot :)

17:12 amalloy: ninjudd: i get ~300KB/s as a microbenchmark

17:13 ninjudd: amalloy: should be plenty fast. it the stop at 85% repeatable?

17:13 amalloy: well, it's happened twice so far. i'll give it another shot

17:13 fliebel: ninjudd: Anything I can do to test my problem?

17:14 amalloy: ninjudd: yes, it's still happening

17:14 ninjudd: fliebel: does 'wget https://github.com/ninjudd/cake-standalone/raw/master/jars/cake-0.5.4.jar' work for you?

17:14 amalloy: git show says i'm at commit 95e1a8ebfcf23514afa4adcee39ae652f8aab866, which is from nov 4

17:14 fliebel: ninjudd: wget: command not found :D Should I try curl?

17:15 amalloy: ninjudd: wget fails for me immediately, actually

17:15 fliebel: ninjudd: curl works :)

17:15 amalloy: ERROR: certificate common name `*.github.com' doesn't match requested host name `github.com'.

17:15 ninjudd: fliebel: yeah. curl -O

17:15 fliebel: -O??

17:15 clojurebot: Clojure ranked #21 on 8/14/2009

17:16 ninjudd: fliebel: isn't that the option to save to a file?

17:16 fliebel: ninjudd: I just watched weird chars pass by :)

17:16 ninjudd: should i more cake-standalone to gitorious? ;)

17:16 fliebel: got it

17:17 amalloy: ninjudd: if i tell wget to ignore bad certs, it gets to 84% and stops

17:17 fliebel: ninjudd: Problem solved: Use system ruby instead of macports :D

17:17 ninjudd: But now I still don't have the 1.3 fixes, do I?

17:18 amalloy: curl downloads the whole thing successfully

17:19 LauJensen: For those interested in ClojureQL I blogged a little about the recent changes: http://bestinclass.dk/index.clj/2010/11/clojureql--revolutions.html

17:20 ninjudd: hmm, gitorious says they will throttle you if you exceed 500MB per month

17:20 amalloy: ninjudd: ouch, worse than the iphone/att data cap :)

17:21 fliebel: ninjudd: How do I use cake with clojure 1.3? I have the git version, but that still downloads the standalone.

17:21 amalloy: fliebel: just list 1.3 as a dependency in project.clj?

17:21 ninjudd: fliebel: add [clojure "1.3.0-alpha2-SNAPSHOT"] to your :dependencies in project.clj

17:22 fliebel: amalloy: Hell breaks loose if I do that.

17:22 amalloy: fliebel: don't do that, then :)

17:22 ninjudd: fliebel: what kind of hell? that should work with master, it is broken with the current gem version though

17:23 fliebel: I'll try… but the master still downloads the standalone, so how is that different from the gem?

17:23 ninjudd: fliebel: your project can use a different version of clojure.

17:24 fliebel: the standalone is only used for deps, the cake code is still loaded from your git checkout

17:25 fliebel: yay, works so far :) At least no infinit stacktrace loop :)

17:27 Thanks all, I'm going to sleep now. UGT is having daylight saving time.

17:28 This is what my script is currently doing:

17:29 "Elapsed time: 8608.225 msecs" reading files

17:29 "Elapsed time: 132289.221 msecs" freqs <<< slow!

17:29 "Elapsed time: 236.694 msecs" plotting

17:29 "Elapsed time: 141319.784 msecs" total

17:29 ninjudd: fliebel, amalloy: i'm switching the uri back to http because that seems to work for me, and i think using https is causing more problems that http was

17:30 fliebel: ninjudd: cool

17:33 amalloy: ninjudd: hm. problem sorta solved

17:33 ninjudd: cool. sorta

17:35 amalloy: okay, all the way fixed. it wasn't fetching the latest copy of standalone after git pull

17:38 vibrant: is there an easy way to run some function after for example 60 seconds in clojure?

17:39 amalloy: vibrant: Thread/sleep

17:39 tomsw: I'm trying to use clojure to interact with a server over a custom (and horrible) SOAP interface. Starting a session and logging in takes a long time, so ideally I'd like to keep the connection in one thread and send it requests from other threads. Is there a clojure-ish way of doing this?

17:39 LauJensen: vibrant: just type the function in the repl, wait 60 seconds, then hit enter

17:39 amalloy: &@(future (Thread/sleep 5000) 1)

17:39 sexpbot: ⟹ 1

17:39 clojurebot: Pardon?

17:39 vibrant: amalloy; what if i run it 100 times?

17:39 it's not gonna pop up 100 threads?

17:39 amalloy: use a threadpool

17:41 &@(future (Thread/sleep 5000) 1)

17:42 sexpbot: ⟹ 1

17:42 amalloy: clojurebot: who were you talking to a minute ago?

17:42 clojurebot: Cool story bro.

17:42 vibrant: well i guess it's better to make a priority queue and a thread checking it every second or so.

17:42 any ready priority queue struct?

17:42 data type i mean

17:43 amalloy: vibrant: java has all these things - see java.util.concurrent.*

17:43 vibrant: k

17:58 duncanm: is it a known bug that i can't inspect-in-frame in slime?

17:59 micahmartin: I could use help understanding how var are bound to their namespace

17:59 here's an example

17:59 user=> (def my-ns (create-ns 'mine))

17:59 #'user/my-ns

17:59 user=> (binding [*ns* my-ns] (def my-var 1))

18:00 Yet if I use load-string ....

18:00 user=> (binding [*ns* my-ns] (load-string "(def my-var 1)"))

18:00 #'mine/my-var

18:00 amalloy: duncanm: yeah, swank-clojure doesn't yet have all the features slime does

18:00 micahmartin: Why without load-string, does the var get bound to the user ns?

18:03 rhickey: any idea?

18:06 raek: LauJensen: reading you blog post... so much DSL beauty!

18:06 LauJensen: raek: you like? :)

18:06 raek: LauJensen: but, should it really be "(take users 1)

18:06 "?

18:07 I was stunned when I looked at cgrand's slides from the conj

18:07 LauJensen: Not necessarily, got better ideas?

18:08 raek: well, the argument order is the opposite of clojure.core/take

18:10 LauJensen: raek: Thats a minor detail, all my consumers should take the table as the first arg. I think I'll want to work take into select somehow though, giving it a representation in the data

18:11 raek: also, does take and sort deref the table?

18:12 LauJensen: yea, they should return a resultset

18:12 raek: ok, so (resolve 'take) does not yeld #'clojure.core/take...

18:13 rickmode: LauJensen: with clojureql, the tables are are actually atoms/refs right? you're just overloading @ / deref for this similar persistent meaning?

18:13 s/are are/are not

18:13 LauJensen: no, Im currently overriding a few functions, conj! disj! < > <= >= =

18:13 raek: I really like the idea of representing tables with a IDeref thing

18:13 LauJensen: rickmode: wrong, Im just overloading

18:14 No need to add Clojures concurrency overhead to something which is already safe

18:14 raek: disj! and conj! does not take the table as an argument?

18:14 LauJensen: raek: Sure they do, its their first arg, like I said, uniform interface

18:15 rickmode: LauJensen: right. interesting. any thought about in-memory cache?

18:15 raek: LauJensen: in the first disj! and conj! examples, the table argument is missing

18:15 LauJensen: rickmode: Not yet

18:15 raek: good catch, thanks

18:16 raek: btw, I agree that the "haystack" arg should be the first one

18:16 amalloy: so if you have a -> chain, with just one command where you need to thread at the end instead of the second position, it's pretty easy: (-> thing form1 (->> form2) ...formN)

18:16 raek: (perhaps with an exception of sequence functions)

18:16 LauJensen: fixed

18:17 amalloy: but i don't see a convenient way to do a ->> chain with one -> link

18:17 rickmode: LauJenson: what if you want to chain operations within a single transaction?

18:17 LauJensen: amalloy: the trick is, typically -> is for things with lists and ->> for collections

18:17 kotarak: amalloy: you have to start with ->. (-> x (->> ....) the-->-link (->> more-->>-stuff ...))

18:17 LauJensen: rickmode: Next step is making the connections nest and adding a dbsync which covers several actions

18:18 raek: (->> thing form1 (#(-> % form2)) ...formN) ; a bit hackish

18:18 kotarak: amalloy: which is a sign, you shouldn't do that.

18:18 LauJensen: Anyway, Can't touch this, its Hammock Time

18:18 Good night all

18:18 kotarak: N8t

18:18 rickmode: LauJensen: ya - both with one table and spanning tables.

18:21 amalloy: kotarak: yeah, i haven't actually had a reason to do that yet

18:23 neotyk: good evening

18:24 Rich Hickey @ Clojure-Conj [Audio] http://sustainablecode.tumblr.com/post/1472289527/rich-hickey-clojure-conj-audio

18:24 is it just me or there is no audio?

18:26 * raek <3 <3 <3 http://vrac.cgrand.net/DSL.pdf

18:27 raek: I hear some audio

18:27 folloed the link to here http://www.livescribe.com/cgi-bin/WebObjects/LDApp.woa/wa/MLSOverviewPage?sid=R4XrwCpdzj5m

18:28 is this the legendary "Hammock Time" talk? :)

18:28 * neotyk hears sound

18:28 neotyk: it is supposed to be this one

18:29 stop hammock time

18:35 jjido: =

18:43 duncanm: is it a bad idea for the arithmatic operators to be generic functions?

18:43 pppaul: would someone be able to help me with a simple classpath problem? (trying to get contrib to work, i followed a tutorial and it did work for a second, but now is broken)

18:45 anyone?

18:45 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.

18:45 amalloy: lol, good work clojurebot

18:46 seriously though pppaul, paste an error message or something. don't make people say "sure i'll help" to find out what your problem is

18:47 pppaul: user=> (System/getProperty "java.class.path")

18:47 "/home/paul/.clojure/clojure.jar:/home/paul/.clojure/clojure-contrib.jar"

18:47 user=> (clojure.contrib.math/round 1000/3)

18:47 java.lang.ClassNotFoundException: clojure.contrib.math (NO_SOURCE_FILE:0)

18:47 amalloy: (require 'clojure.contrib.math)?

18:47 pppaul: i did use that (based on the info on the math API site)

18:48 user=> (require 'clojure.contrib.math)

18:48 nil

18:48 user=> (abs 4)

18:48 java.lang.Exception: Unable to resolve symbol: abs in this context (NO_SOURCE_FILE:3)

18:48 ok, i think i understand what my problem is

18:48 amalloy: pppaul: require doesn't provide "shortcut" banes

18:49 use (use) instead if you want to refer to them without a namespace

18:49 pppaul: do i always have to switch the (ns) for shortcuts?

18:49 amalloy: (use 'clojure.contrib.math)

18:49 pppaul: thank you

18:50 amalloy: getting absolute values now?

18:50 pppaul: yes

18:50 amalloy: clojurebot: another satisfied customer

18:50 clojurebot: It's greek to me.

18:51 raek: pppaul: all the ns clauses do is to call the corresponding functions

18:51 arohner: ok, stupid question. What is the proper lein declaration to get the newest clojure contrib 1.3?

18:52 pppaul: thanks. i'll look up the NS functions.

18:52 arohner: I have [org.clojure.contrib/clojure-contrib "1.3.0-SNAPSHOT"] , which downloads a few poms, and then I get the 'unable to resolve artifact', missing org.clojure.contrib:clojure-contrib:jar:1.3.0-SNAPSHOT

18:52 raek: it has been split into multiple modules (a big jar of all the modules is available though)

18:52 arohner: raek: I'm aware it's been split up. My understanding was depending on what I have above would pull in all the little jars as dependencies. Is that incorrect?

18:53 and I see that pom in build.clojure.org, but no jar with the same name

18:53 raek: well, I think [org.clojure.contrib/complete "1.3.0-SNAPSHOT"] does what you describes

18:53 but I haven't used the new system very much

18:54 arohner: raek: aha. thanks. d/ling complete now, we'll see what it has

18:55 raek: I think 'complete' depends on all the others, so you end up with all the module jars

18:56 I don't remember if there is something like 'complete' but with just one jar

18:59 arohner: raek: looks like complete is empty, just depends on the others, lein pulled down a bunch of jars. thanks.

19:49 clizzin: Is there any way to easily do a case-insensitive match for keyword keys in a map? Due to some annoying data inconsistencies, I have keywords in one map that are all lowercase and keywords in another map with some uppercase letters in them.

19:53 raek: clizzin: you can preprocess the map with (defn lowercase-keys [m] (zipmap (map #(-> % name .toLowerCase keyword) (keys m)) (vals m)))

19:55 clizzin: raek: Let's say the keys in question are actually within a nested map, i.e. {:blah {:case "foo"}} and {:blah {:cAsE "bar"}}. Is there an easy way to apply the lowercase-keys? Some of the values in the outer maps may not be maps.

19:57 raek: i guess you could do something like (zipmap (keys outer) (for [v (vals outer)] (if (map? v) (lowercase-keys v) v)))

19:57 but why not add the lowercase code to the thing that generates the keywords in the first place?

19:58 bhenry: ^^ that's what i'd do

19:58 clizzin: we'll do that on the next run of the data, but it's a very big job and we want to do some analysis before we kick off another run

19:58 otherwise, yeah, that would be nice. =/

21:08 tufflax: How does lazy-seq work to prevent stack overflows when dealing with recursively defined sequences? It's all a little magical to me. Is is somehow related to closures? I mean, the function used to generate the next element when one needs it, is that a kind of closure?

21:09 Is it*

21:10 amalloy: tufflax: yes, it is

21:11 each element in a lazy seq is a pair: value, function-to-generate-next-pair

21:12 (probably not exactly true, but close enough to be useful conceptually)

21:15 tufflax: And when the function-to-generate-next-pair is executed, what is put on the stack? The call to that function, with references to data that is not on the stack? And the next function-to-generate-next-pair is stored together with the seq that's not on the stack? Or something...? :P

21:16 amalloy: &(macroexpand '(fn f [x] (lazy-seq (cons x (f (inc x))))))

21:16 sexpbot: ⟹ (fn* f ([x] (new clojure.lang.LazySeq (fn* [] (cons x (f (inc x)))))))

21:17 amalloy: so really f just returns a LazySeq object, without recurring

21:18 tufflax: Yeah ok, thank you. I think I'm starting to understand.

21:18 amalloy: when you walk a lazy seq, clojure calls the function. that function returns immediately; then it gets the value out and calls the next function

21:19 tufflax: I see.

21:20 amalloy: so it doesn't build up the stack at all

21:23 tufflax: When I was looking for answers to my questions, I came across this http://codemeself.blogspot.com/2010/06/clojurecorelazy-seq-makes-sense.html He uses lazy-seq twice in his function (look at the end of the post) but that is unnecessary, right?

21:26 amalloy: i don't think so, because my example was recursive, and his isn't

21:27 ie, i have an infinite number of calls to lazy-seq; he only has two

21:28 &(lazy-seq [])

21:28 sexpbot: ⟹ ()

21:28 amalloy: &(lazy-seq (lazy-seq []))

21:28 sexpbot: ⟹ ()

21:28 amalloy: but i don't actually know; i don't build raw lazy-seqs very often

21:29 tufflax: Yeah I tried his code, it didn't work without both calls.

21:29 amalloy: &(cons 1 (lazy-seq ()))

21:29 sexpbot: ⟹ (1)

21:35 amalloy: anyway, it's definitely good to know how lazy-seq works under the hood, but knowing exactly how to use it is probably unnecessary for quite a while. just combine the built-in lazy functions and let them do the work for you

21:36 tufflax: Ok :)

21:36 TheBusby: er, what's the easy way to sort a map by it's values?

21:36 tufflax: Thanks again

21:39 amalloy: TheBusby: don't do that :)

21:39 TheBusby: uh oh, is there a better way to find the most frequent elements among multiple sets then?

21:40 amalloy: so you have N sets like #{1 3} #{1 5}, and want to find out that 1 is more common than 5?

21:41 TheBusby: correct, I want to find most common elements

21:41 hopefully end up with something like [[ 2] [3 1] [5 1]]

21:42 sorry, that should have read [[1 2] [3 1] [5 1]]

21:43 amalloy: &(frequencies (concat #{1 3} #{1 5}))

21:43 sexpbot: ⟹ {1 2, 3 1, 5 1}

21:43 amalloy: and you want that sorted by value?

21:43 TheBusby: correct

21:44 I'll likely be dealing with 10,000+ maps, each containing 2000-5000 values...

21:44 amalloy: &(sort (comp < val) (frequencies (concat #{1 3} #{1 5})))

21:44 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (2) passed to: core$val

21:46 amalloy: &(sort (fn [[k1 v1] [k2 v2]] (< v1 v2)) (frequencies (concat #{1 3} #{1 5})))

21:46 sexpbot: ⟹ ([3 1] [5 1] [1 2])

21:46 amalloy: &(sort (fn [[k1 v1] [k2 v2]] (> v1 v2)) (frequencies (concat #{1 3} #{1 5})))

21:46 sexpbot: ⟹ ([1 2] [3 1] [5 1])

21:46 bhenry: is there a way to sort on keys?

21:47 amalloy: &(doc sorted-map-by)

21:47 sexpbot: ⟹ "([comparator & keyvals]); keyval => key val Returns a new sorted map with supplied mappings, using the supplied comparator."

21:47 kzar: How do you know which different versions of packages there are when writing your project.clj?

21:48 tufflax: Hm, I briefly tried to learn common lisp before clojure, and in CL they have :key directives (or whatever they call them) to functions like max, sort, map, etc. Why doesn't clojure have that? I noticed clojure have sort-by for example, but no map-by. :P

21:49 amalloy: &(doc sort)

21:49 sexpbot: ⟹ "([coll] [comp coll]); Returns a sorted sequence of the items in coll. If no comparator is supplied, uses compare. comparator must implement java.util.Comparator."

21:49 amalloy: tufflax: just pass in a comparator

21:49 tufflax: its much easier with a key function

21:49 &(doc sort-by)

21:49 sexpbot: ⟹ "([keyfn coll] [keyfn comp coll]); Returns a sorted sequence of the items in coll, where the sort order is determined by comparing (keyfn item). If no comparator is supplied, uses compare. comparator must implement java.util.Comparator."

21:50 amalloy: tufflax: sort-by does something different

21:50 it applies some function to each element of the seq and then compares the result

21:51 tufflax: Hm, not that different, or what do you mean?

21:51 Yes, thats exactly what its for

21:51 Instead of (sort #(compare (val %1) (val %2)) coll) it becomes (sort-by val coll)

21:51 So, "just pass in a comparator" is not as elegant

21:51 amalloy: oh, yes. i see what you mean

21:51 that's much nicer

21:52 tufflax: CL has that for everything

21:52 I think...

21:52 even map

21:52 TheBusby: ahh, that's exactly what I was looking for

21:52 tufflax: :)

21:53 TheBusby: tufflax, amalloy; thank you both.

21:54 amalloy: tufflax: clojure *has* keyword arguments, but stylistically they're not as prevalent as in CL

21:55 tufflax: Yeah I know it has keyword arguments, it's just that it would be nice with a :key argument for sort, max, car, filter, etc.

21:55 Why not have :key for sort, instead of sort-by?

21:55 amalloy: *shrug*

21:55 tufflax: map, not car*

21:58 amalloy: why have a function with ten modes instead of ten functions?

21:58 tufflax: Because you one have to remember one function name :P

21:59 amalloy: and ten keyword arguments

21:59 tufflax: but the keyword arguments are the same for all functions

21:59 amalloy: at least the compiler can help you with autocompletion of function names - it's a lot harder for it to tell you what keyword arguments it will accept

22:01 tufflax: Yeah, I guess, but it just feels nice to know that :key is always there for you should you need it

22:01 There doesn't seem to be a map-by for example

22:01 I guess one could make his own

22:02 amalloy: tufflax: i only have a little experience with CL. what would you want map-by to do?

22:03 tufflax: just apply (key element) to every element before the regular map function

22:03 hiredman: erm

22:03 amalloy: use comp

22:03 tufflax: hm?

22:03 amalloy: &(map (comp inc :foo) [{:foo 10, :bar 1} {:foo 1}])

22:03 sexpbot: ⟹ (11 2)

22:04 tufflax: ah oh yes

22:04 That's true

22:04 powr-toc: Hey... Is there any reason why (fn? :foo) ; => false ?

22:04 qbg: ,(ifn? :foo)

22:04 clojurebot: true

22:05 amalloy: &(ifn? :foo)

22:05 sexpbot: ⟹ true

22:05 powr-toc: ahh cool

22:05 why have the distinction?

22:05 amalloy: things that are callable, vs things that were defined with (fn)

22:05 qbg: :foo can be used as a function, but isn't actually a function

22:05 powr-toc: I mean why is it useful to know, whether fn created it?

22:05 amalloy: i dunno why, but why not

22:06 tufflax: what qbg said, you can just call :foo like (:foo)

22:06 or, maybe that doesn't make sense

22:06 forget what i said

22:06 :)

22:07 powr-toc: hmm... ok, I suppose it allows you to nest vectors, keywords and maps, whilst using a predicate function to find function values within them (that aren't the containers themselves)

22:07 kinda elegant in that case

22:09 tufflax: :keywords are functions that will look themselves up in maps e.g. (:foo {:foo "bar"})

22:09 tufflax: yeah i know, i dunno what i was talking about

22:09 powr-toc: likewise maps are functions of their values, and vectors are functions of their indicies

22:14 hiredman: ifn? was split from fn? when trampoline was added

22:15 powr-toc: does that make it easier to spot the thunk?

22:15 thunk: no

22:15 powr-toc: lol

22:15 the irony, I didn't spot 'the thunk'

22:16 thunk: the arity!

22:18 powr-toc: I'm hoping the thunks got nil puns left

22:18 thunk: Who da thunk?

22:19 qbg: powr-toc: I think the thunk is just delaying the next one

22:20 powr-toc: qbg: well for heavens sake don't force him

22:20 thunk: Hey guys, no arguments.

22:21 amalloy: oh my god. i'm dying. this is terrible

22:21 qbg: Well, that is not promise

22:21 *no

22:30 arohner: is anyone using slime with clojure-1.3 successfully?

22:30 I'm not getting the stacktrace window when I compile and encounter a stacktrace

22:45 pppaul: zzz

22:45 amalloy: pppaul: boring is better than the pun attack we were having earlier

22:46 pppaul: just testing out my IRC colors.... didn't know what to type :P i think my client is a bit poor, can't tell what i'm changing with respect to the colors

22:46 can't see my own text anymore

22:48 tufflax: the pun attack was awesome :P

22:49 amalloy: pppaul: you could do it in #test or something

22:50 not that i especially care, but there are channels for just that purpose

22:52 pppaul: so, did someone post the pun attack somewhere?

22:52 amalloy: pppaul: it'll be on n01se if it's not already

22:53 yeh, http://clojure-log.n01se.net/date/2010-11-03.html

22:55 pppaul: i found it

22:55 seems noisy

22:55 amalloy: *eyeroll*

23:01 pppaul: what do you guys think of the clojure euler puzzles?

23:41 hiredman: as long as it's quiet in hear, I'm going to restart clojurebot with some features that are rather loud the first time they run

23:41 here

23:48 itistoday: how can i get this sequence to not end in nil? just have the last object be the last object? http://paste.pocoo.org/show/285831/

23:49 and is there a function to check if a value exists in a sequence (and return true immediately if it does)?

23:52 amalloy: &(some #{4} (range 1))

23:52 sexpbot: ⟹ nil

23:52 amalloy: &(some #{4} (range 10))

23:52 sexpbot: ⟹ 4

23:53 amalloy: itistoday: see (iterate) and (take-while) - they should be a cleaner way to do what you want

23:54 &(let [x {:p {:p {:p nil}}}] (take-while identity (iterate :p x)))

23:54 sexpbot: ⟹ ({:p {:p {:p nil}}} {:p {:p nil}} {:p nil})

23:55 itistoday: amalloy: that's really elegant, thanks!

23:56 amalloy: itistoday: that gets you what you wanted, right?

23:57 itistoday: amalloy: yup, that seems to be exactly what i want, and it's much shorter and way more elegant

23:58 i'm a n00b to clojure though so i'm not familiar yet with all of its functions... which is why i was toying with the primitive lazy-seq

23:58 amalloy: sure

Logging service provided by n01se.net