#clojure log - Nov 09 2010

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

0:04 replaca: Raynes: are you here?

0:05 Raynes: replaca: No.

0:05 Yes, I'm here. :)

0:05 replaca: Raynes: got your pull req on autodoc, but I'm kind of moving in a different direction with autodoc

0:06 Raynes: I didn't send a pull request. :o

0:06 replaca: Raynes: I'm on the verge of pulling the lein plugin out into a separate plugin and here's why:

0:06 Raynes: replaca: Oh, my message.

0:06 replaca: is my senile memory messing with me?

0:06 yeah, that :)

0:06 Raynes: replaca: That's completely cool. I'm fine with cake-autodoc being separate. I just wanted to check with you to make sure I was being consistent.

0:07 replaca: when you have leinigen, autodoc and a project all running with possibly different versions of clojure

0:07 you get version headaches out the wazzoo

0:07 we had it with 1.2 and we'll have it with 1.3

0:08 so a very light external plugin that depends on autodoc and invokes it with args based on the project params seems like the way to go

0:09 I hope to get to that soon for leiningen and you could just copy me, but there are a lot of things I hope to get to soon :)

0:09 Raynes: that's all!

0:10 Raynes: replaca: Awesome.

1:06 lenw: hi all

1:06 scottj: new library for webapps, feedback welcome: https://github.com/scottjad/slice/blob/master/src/slice/example.clj

1:09 lenw: scottj: that looks very neat

1:42 quizme: how do you do a hard reload, where it reloads the file and recompiles?

1:42 scottj: C-c C-k in slime

1:42 lenw: (use 'x :reload)

1:42 quizme: I'm using (load) but it doesn't seem to be recompiling

1:42 lenw i'll try that

1:42 thnx

1:45 when i reload I'm getting this error: java.lang.IllegalStateException: flatten already refers to: #'clojure.contrib.seq/flatten in namespace: triangle.core (core.clj:1)

1:45 so it's preventing it from reloading

1:47 is there a way to ignore that warning?

1:47 *error* ?

1:50 lenw: are you not getting that error the first time ?

1:56 quizme: lenw: it's a warning the first time

1:59 LauJensen: Morning all

2:01 ppppaul: moo

2:03 Derander: lenw: I have the same issue as quizme w/ my setup

2:04 lenw: i am not really sure about whats going on there guys - what is the warning that you get the first time - perhaps that the thing to look at ?

2:05 quizme: WARNING: flatten already refers to: #'clojure.core/flatten in namespace: triangle.core, being replaced by: #'clojure.contrib.seq/flatten

2:11 lenw: what does your uses bit look like in your code ?

2:13 quizme: lenw: http://pastie.org/1283802

2:21 lenw: ok i can reproduce the error now

2:23 quizme: lenw: great, we're starting a movement.

2:28 lenw: http://clojuredocs.org/clojure_contrib/clojure.contrib.seq/flatten ?

2:29 use this rather http://clojuredocs.org/clojure_core/clojure.core/flatten

2:50 quizme: lenw: I took out the reference to clojure.contrib.seq and it seems to have removed that warning.

2:50 lenw: hope it doesn't break anything though...

2:51 lenw: i dont think that the behaviour of flatten has changed

2:55 quizme: lenw: ok awesome thanks.

3:20 raek: awesome! someone on the mail list used Clojure to solve a Myst puzzle... :D

4:01 npoektop: hi! i've just read a post about how to make server pick up changes without restarting repl: http://blog.darevay.com/2010/11/compojure-the-repl-and-vars/. There is an example what happens if we do not use var, but i do not get it. Why it prints hi, not hey, when the function greet is redefined?

4:04 raek: in code, the vars are used. in data, the var value is used.

4:04 (fn [] (foo)) ;; <--- this will always call the most recent version of foo

4:05 (some-fn foo) ;; <-- here, the value of foo is looked up, and the function that the var foo currently has is passed as the arg

4:09 so, in the example, partial receives the current value of greet (the function that prints "Hi!")

4:12 when a function is compiled (like the call function in the example) the functions is uses are not looked up, but references to the vars are remembered instead.

4:15 npoektop: raek: i thought there may be only one version of a function. It's a bit confusing. Do i get it right? When i do defn, it just binds an anonymous function to symbol, and if i redefine it, it just rebinds. So there really may be versions of functions.

4:16 rebinds to a new anonymous function

4:16 raek: yes, when you reevaluate the defn, you rebind the var to a new function object

4:17 npoektop: reak: cool. thanks

4:17 raek: the old function object remains unchanged

4:19 I usually start the web server using something like this:

4:19 (def web-server (atom nil))

4:20 (defn start [] (swap! #(do (assert (nil? %)) (run-jetty #'the-handler {:port 8080, :join? false}))))

4:20 sorry, "... (swap! web-server #(do..."

4:21 jowag: if I have a function (defn my-fun [a b c] (foo a) (bar b) (baz c)), what is the best way to document what kind of arguments it accepts? In this case one needs to look into source or doc for foo, bar and baz to know the types of arguments, so some kind of documenting the arguments in my-fun would be helpful

4:22 some partial solutions could be - choose a good argument name, - document it briefly in the docstring, - add a comment explaining arguments, - use metadata/type hints

4:23 npoektop: jowag: http://tech.puredanger.com/2010/02/08/clojure-1-whats-up-doc/

4:26 jowag: npoektop: so you recommend to use docstring to document the argument types?

4:29 npoektop: jowag: sorry. i posted before i read your second line.

4:30 raek: i would write that in the docstring, along with the explanations of what the args are for

4:31 you should always have docstrings for public fns

4:35 ideally, the fn and namespace docstrings should contain everything the user needs to know in order to use the fn

4:53 jowag: I agree that docstring should contain everything user needs

4:53 but sometimes I find myself writing too large docstring if I want to describe fully what the parameters should be

4:56 in one case my function expects map with specified keys present and docstring is than a bit verbose

4:57 Raynes: I wrote excellent documentation for my secret-but-not-so-secret-that-you-cant-find-it-on-github-if-you-look-for-it project. I'm proud of myself.

5:00 jowag: I came from strongly typed land and the feeling that the only way how to elucidate arguments is in the docstring makes me a bit uneasy

5:06 jrp: hm, when I try to run a simple hello world function from a repl inside vim, i get '#<user$hello user$hello@3b26456a>' or similar when i try to run it

5:06 whats going on here?

5:10 jjido: jrp: where's your code?

5:11 jrp: jjido: In the vim window below it. I send it to the repl with vimclojure I think...

5:14 jjido_: jrp: please post the code on github or pastebin

5:15 jrp: jjido_: (defn hello [] println ("Word"))

5:17 jjido: ok, then the output is the result of your code. You define a function.

5:17 try: (defn hello [] (println "Word")) (hello)

5:18 jrp: hm ok, that works. Why cant I call it via the repl though once Ive defined it?

5:19 jjido: this is a function call: (hello)

5:19 the repl will forget the function when you restart it

5:20 jrp: but Im not restarting the repl?

5:23 bartj: I see a very weird behaviour with clojure.contrib.json

5:23 Here is the code sample: http://pastie.org/1283998

5:24 can anyone please take a look?

5:27 is this a bug?

5:28 , (type (json-str (Math/sqrt -1)))

5:28 clojurebot: java.lang.Exception: Unable to resolve symbol: json-str in this context

5:28 bartj: , (type (clojure.contrib.json.json-str (Math/sqrt -1)))

5:28 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.json.json-str

5:29 bartj: ie. (type (json-str (Math/sqrt -1))) = (type (json-str "abc"))

5:30 but, when I do a read-json on this: (read-json (json-str (Math/sqrt -1))) it fails!

7:19 lenw: how do i see the queue's behind an agent ?

7:55 cemerick: lenw: it's in a package-private field `aq` in the agent

7:56 Raynes: cemerick: Mornin'!

7:56 cemerick: There's roughly no good reason to look at the queue, though.

7:56 Raynes: Morning :-)

7:57 jcromartie: hi

7:58 Raynes: jcromartie: Hi.

7:58 jcromartie: I have to confess... Smalltalk (Pharo) is winning me over.

7:58 Raynes: I played with Pharo a while back.

7:58 jcromartie: It's like the opposite of Clojure.

7:58 It is basically just a toolkit for mutable state.

7:58 Raynes: I do declare that I cannot tolerate trying to work in an 'environment'.

7:59 jcromartie: heh, yeah it's weird

7:59 but I wonder if something like Seaside wouldn't be possible in Clojure?

7:59 Raynes: My environment is whatever I want it to be at any particular moment in time, not what somebody decided beforehand.

7:59 jcromartie: hey, at least it's consistent right?

7:59 Raynes: That it is.

8:00 No "Help, I can't get SLIME working"

8:00 jcromartie: Seaside is just hands-down the best web development framework I've ever seen (and I've evaluated a lot)

8:00 what does Clojure have in terms of continuations?

8:00 Raynes: cemerick: I own raynes.me now. I'm getting all fogus_-like.

8:01 jcromartie: could fns be used to build continuations?

8:02 cemerick: Raynes: nice :-)

8:02 BTW, what *is* "Raynes", anyway?

8:02 Raynes: amalloy asked me that earlier.

8:03 I started using it as a username after playing the bloodrayne games several years ago. It started as Rayne, and then became 'Raynes' when I started running into (everything) where Rayne is already taken.

8:03 I am become Raynes.

8:08 cemerick: I remember people calling me Raynes at the conj. It always shocked me back to reality about where I was, because it was so bizarre.

8:20 stuartsierra: I tawt I taw a blue haired Clojurian. I did! I did!

8:21 stuartsierra: What's up, doc?

8:21 (I forget what the cat says.)

8:21 Raynes: That's bugs bunny.

8:29 cemerick: stuartsierra: I think you were looking for…sufferin' succotash! :-D

8:29 of course, severe lisps don't translate in irc

8:30 * cemerick waits for the puns… ;-)

8:30 stuartsierra: I only program in Severe Lisps.

8:30 Other lisps are too milquetoast for me.

8:31 cemerick: "milquetoast" is a fantastic word

8:31 Raynes: $dict milquetoast

8:31 sexpbot: Raynes: noun: a timid, unassertive man or boy fearful of confrontation and easily manipulated and dominated.

8:31 stuartsierra: That's going to be the name of my next project then.

8:33 cemerick: the etymology of it is pretty amusing

8:33 * cemerick finds a lot of things unusually amusing, perhaps

8:34 * fogus_ has made his mark! .... on the Scala community. :-O

8:36 cninja: Hi all! Im new to clojure. As part of teaching myself the language, I was looking at clojure.core and it seems to me the implementation of "distinct" is overly complex. I wrote https://gist.github.com/669075 that seems to be faster. What is it missing?

8:37 scottj_: jcromartie: see clj-cont and weblocks for what's possible.

8:37 Raynes: $source distinct

8:37 sexpbot: distinct is http://is.gd/gRO3Q

8:40 cninja: I thought maybe my faster version held onto the head of the column, but I'm not familar enough with the language to test for that sort of thing.

8:45 chouser: cninja: yours isn't lazy after the first step

8:46 Raynes: chouser: You're a ninja.

8:46 chouser: no, c is.

8:46 har har

8:46 cninja: ha ha

8:46 Raynes: I actually didn't make that association when I saw his nickname.

8:46 cninja: How did you test for that?

8:46 Raynes: I guess that's a sign that I've been awake too long.

8:47 chouser: cninja: still working on a test, but from your code it's clear enough to make a bold assertion on IRC. :-)

8:48 Raynes: chouser: Write me a map function that works like map, but when it comes across a collection, it maps into that collection and always returns the same data structures. It must not blow the stack. I want it on my desk by 9.

8:48 cninja: chouser: I figured I missed something. It didn't make since that I just rewrote a core function and made it twice as fast

8:48 chouser: cninja: :-)

8:49 & (take 2 (distinct (map #(do (prn :took %) %) (list 1 2 3 1 2 3 4))))

8:49 sexpbot: ⟹ (:took 1:took 21 2)

8:49 chouser: cninja: now, try that with distinct2

8:50 cninja: k

8:50 stuartsierra: Raynes: clojure.walk/postwalk

8:51 Raynes: &(doc clojure.walk/postwalk)

8:51 sexpbot: ⟹ "([f form]); Performs a depth-first, post-order traversal of form. Calls f on each sub-form, uses f's return value in place of the original. Recognizes all Clojure data structures except sorted-map-by. Consumes seqs as with doall."

8:51 * stuartsierra keeps wishing somebody would rewrite that as a protocol

8:55 Raynes: stuartsierra: You're my bestest buddy ever.

8:59 My life is so much easier now.

9:00 chouser: contrib generic has multimethod-based solutions

9:00 ((fn gmap [f coll] (clojure.contrib.generic.collection/into (empty coll) (map #(if (coll? %) (gmap f %) (f %)) coll))) inc '[1 2 3 [4 5 6] 7 8 (9 10 11)])

9:01 hm, that's not quite right

9:01 (12 11 10)

9:03 fliebel: Oh, I really want a function-need identification graph.

9:05 Raynes: I find it amusing that Leiningen takes so much memory that I cannot run the 'deps' task with sexpbot running at the same time on my VPS.

9:07 Not that it's Leiningen's fault. sexpbot isn't exactly lightweight. My VPS only has a gig of guaranteed RAM with 2gb burst.

9:07 I should be moving him to a higher end box soon.

9:09 fliebel: Raynes: How hard would it be for me to implement pingpong timing? So me "Raynes: ping" you "fliebel: pong" sexpbot "Raynes's responds time id 5 sec"

9:10 Raynes: fliebel: Isn't that irrelevant when you can just use CTCP PING?

9:10 * Ping reply from fliebel: 0.84 second(s)

9:10 jjido: irc messaging ping

9:11 fliebel: Raynes: It's not about my computers response time, but just to see how long it takes someone to respond ;)

9:11 Raynes: Oh, I misread what you said.

9:11 Meh, shouldn't be very difficult.

9:12 I need to write a plugin tutorial.

9:13 People seem to get by pretty well just by looking at existing plugins.

9:13 fliebel: Raynes: That would be awesome! I looked at one and it didn't seem that hard, but there where a few magic bits.

9:14 Raynes: I'd be happy to explain those magic bits. In PM or #clojure-casual, though. Don't want to fill up #clojure with sexpbotspam. :p

9:15 fliebel: Raynes: I didn't know about casual...

9:15 Raynes: It's a very, very quiet channel.

9:16 jjido: #clojure is casual enough

9:16 Raynes: jjido: That's exactly right. Most of the time it is.

9:16 fliebel: Raynes: I'm going to look at a plugin and I'll be there with questions in a moment.

9:16 Raynes: I like to reserve #clojure-causal for totally non-clojure related stuff, or just long discussions about anything that just doesn't seem quite appropriate for #clojure.

9:19 romainp: Hi, what are a few good sources of clojure code to use as inspiration? (not domain-specific, just to get the feel of it)

9:20 belun: clojuredocs.org

9:20 http://clojuredocs.org/

9:22 i got a q too :)

9:22 if there is let

9:22 and letfn

9:22 is there a mxin function

9:22 ?

9:22 that can bind vars and functions ?

9:24 chouser: belun: no, but you can use let to bind fns. letfn is only needed when the fns are mutually-recursive, a generally pretty rare use case.

9:24 stuartsierra: ~seen dysinger

9:24 clojurebot: Cool story bro.

9:24 belun: what does muttualy recursive mean ?

9:25 stuartsierra: $seen dysinger

9:25 sexpbot: dysinger was last seen quitting 21 hours, 27 minutes ago.

9:25 joegallo: A calls B, B calls A, A calls B, etc...

9:25 chouser: belun: the functions call each other, so at least one of them is calling a function that hasn't yet been defined.

9:26 jjido: belun: if you don't need mutually recursive let is fine

9:26 belun: that's the only usecase for let fn ? i was thinking to use it to give names to inline functions

9:26 for readability...

9:27 chouser: ,(letfn [(odd [x] (if (zero? x) false (even (dec x)))) (even [x] (if (zero? x) true (odd (dec x))))] (odd 5))

9:27 clojurebot: true

9:27 chouser: belun: you can give any fn a name for readability

9:28 & (let [cool (fn cool [a b] (+ a b))] (cool 4 5))

9:28 sexpbot: ⟹ 9

9:29 belun: ya but this way cool stays in the namespace...

9:30 jjido: belun: no it does not go in global nakedness

9:30 lol iPhone autocorrect

9:33 chouser: neither let nor letfn nor fn change any namespace

9:36 jjido_: was I kicked? it was an autocorrect mistake

9:36 chouser: you weren't kicked

9:36 Raynes: Nobody kicked you.

9:36 We <3 you.

9:37 jjido_: lol

9:45 belun: fn does not put functions into namespace ? what does then ?

9:45 chouser: dean: def-things. defn, defmacro, etc

9:45 belun: ^^^ (sorry dean)

9:47 Raynes: 'fn' creates a function. A function is just an object. def things give these things names. For example, (def x (fn [])) is the same as (defn x []). These don't do anything magical, they just create functions with fn and bind them to a name.

10:04 fliebel: Where in Joy of Clojure are reify, defprotcol and deftype covered?

10:06 ah, 9.3

10:06 Raynes: 1.1.4, 9.3

10:11 fliebel: &(= (array-map 1 2 3 4) (hash-map 1 2 3 4)) ; what is the difference?

10:11 sexpbot: ⟹ true

10:12 cemerick: fliebel: you should use the latter :-)

10:13 chouser: really?

10:13 jjido: no

10:13 cemerick: or, actually (into {} …)

10:13 chouser: & (hash-map 3 4 1 2)

10:13 sexpbot: ⟹ {1 2, 3 4}

10:13 chouser: & (array-map 3 4 1 2)

10:13 sexpbot: ⟹ {3 4, 1 2}

10:13 jjido: that is a map indexed by integers, is that what you want?

10:14 cemerick: chouser: you use array-map explicitly on occasion?

10:14 fliebel: jjido: Not particularly… Just to lazy to type :a 1 :b 2

10:14 chouser: cemerick: absolutely

10:15 fliebel: cemerick: I used it in a case where I was doing some strange apply thing that did not work with hash-map, not knowing what I was doing exactly.

10:16 $(type {})

10:16 &(type {})

10:16 sexpbot: ⟹ clojure.lang.PersistentArrayMap

10:16 jjido: &(get (hash-map 1 2 3 4) 3)

10:16 sexpbot: ⟹ 4

10:16 cemerick: chouser: not (into {} …)?

10:17 chouser: cemerick: array-map guarantees order. I do on occasion use that.

10:17 cemerick: huh

10:17 I'd be too paranoid about the resulting map getting too big at some point, and tripping over into PHM

10:18 fliebel: chouser: Is that the only difference?

10:18 chouser: cemerick: right, you can't conj onto it and assume it'll still be an array-map

10:19 but, array-map always returns an array map, so as long as you use only that particular value, you're good to go.

10:22 fliebel: I still don't get the difference though, could you show me an example where it matters if I'm using one or the other?

10:22 chouser: I did.

10:23 & [(hash-map 3 4 1 2) (array-map 3 4 1 2)]

10:23 sexpbot: ⟹ [{1 2, 3 4} {3 4, 1 2}]

10:24 fliebel: chouser: But why does that matter? get is going to return the same thing for both, right? or are you thinking about looping over it?

10:24 jjido: if you map or loop over it the order differs

10:25 cemerick: fliebel: also FWIW, equality isn't a very good indication of the natures of respective data structures. e.g.:

10:25 &(= {1 2 3 4} (doto (java.util.HashMap.) (.put 1 2) (.put 3 4)))

10:25 sexpbot: ⟹ true

10:25 Raynes: My heart stops every time something gets evaluated.

10:25 And then I smile.

10:35 bartj: In a map like this: (def x {:a [1 2 3] :b [] :c [4 5] :d []})

10:35 Is there a better way to remove :b and :d (ie. they have empty vectors/collections)

10:35 than this: (select-keys x (remove nil? (map #(when (> (count (x %)) 0) %) (keys x))))

10:37 jjido: empty? tells you if the collection is empty

10:38 Raynes: &(into {} (filter (comp seq second) {:a [1 2 3] :b [] :c [4 5] :d []}))

10:38 sexpbot: ⟹ {:a [1 2 3], :c [4 5]}

10:39 jjido: what does seq do here?

10:40 ,(seq [])

10:40 clojurebot: nil

10:41 Raynes: &(seq [])

10:41 sexpbot: ⟹ nil

10:41 clojurebot: ⟹ "Returns the metadata of obj, returns nil if there is no metadata."

10:41 Raynes: If seq is called on an empty collection, it returns nil.

10:41 jjido: and nil is interpreted as false... almost obfuscation

10:41 mfex: &(into {} (remove (comp empty? val) {:a [1 2 3] :b [] :c [4 5] :d []}))

10:41 sexpbot: ⟹ {:a [1 2 3], :c [4 5]}

10:42 Raynes: Right, val works here as well. I should have used val.

10:42 Vals have more fun.

10:43 bartj: mfex, Raynes thanks!

10:44 &(remove (comp empty? val) {:a [1 2 3] :b []))

10:44 sexpbot: java.lang.Exception: Unmatched delimiter: )

10:44 bartj: &(remove (comp empty? val) {:a [1 2 3] :b [])

10:44 sexpbot: java.lang.Exception: Unmatched delimiter: )

10:44 Raynes: Missing a }

10:44 bartj: &(remove (comp empty? val) {:a [1 2 3] :b []})

10:44 sexpbot: ⟹ ([:a [1 2 3]])

10:46 bartj: for a moment, I thought that the [:a [1 2 3]] was a vector!

10:46 Raynes: Well, it pretty much is.

10:46 &(type (remove (comp empty? val) {:a [1 2 3] :b []}))

10:46 sexpbot: ⟹ clojure.lang.LazySeq

10:46 jjido: bartj: yeah that is how clojure handles entries

10:46 Raynes: &(type (first (remove (comp empty? val) {:a [1 2 3] :b []})))

10:46 sexpbot: ⟹ clojure.lang.MapEntry

10:47 Raynes: A MapEntry is similar to a vector.

10:48 bartj: cool

10:48 jjido: ,(first {:a [1 2 3]})

10:48 clojurebot: [:a [1 2 3]]

10:48 bartj: , (into {} [[:a 1] [:b 2]])

10:48 clojurebot: {:a 1, :b 2}

10:50 bartj: cool, thanks everyone

10:53 fliebel: hrm, I thought there was a chapter like "when to use reify", but looking at it, those are for atom, agent, ref and these. I guess I'll just have to think hard about my problem ang do some hamocking afterwards.

10:56 jjido: the hammock joke is still making rounds ;)

10:58 bartj: jjido, care to explain?

11:00 belun: i think it;s from teh rich preentation

11:00 http://www.livescribe.com/cgi-bin/WebObjects/LDApp.woa/wa/MLSOverviewPage?sid=R4XrwCpdzj5m

11:00 fliebel: bartj: Something to do with Clojure-conj. Rich gave a talk about problem solving, I think, and he said something about hamock time.

11:00 to slow again.

11:02 belun: :)

11:03 LauJensen: Most dev communities are plauged by insomnia, long hours of coding. Looks like Rich solved that for #clojure :)

11:04 bartj: fliebel, belun thanks!

11:09 fliebel: ouch, this hurts… Python has only 68 core functions, Clojure over 400.

11:10 jjido: fliebel: I did notice clojure has many functions in core

11:10 Raynes: fliebel: clojure.core covers a very wide range of tasks. The entire sequence library is stuffed in there, for example.

11:10 fliebel: jjido: I'll be doing a project about this after the hamock.

11:11 Raynes: I know. That is my whole point. Pythons functions are not very useful on their own at all, so you need to look in the corret module, which makes searching a lot easier.

11:11 *correct

11:12 Raynes: I tend to agree, but I very much like having so much available to me all the time.

11:13 jjido: Raynes: it would not do much harm to do one more (use) at the top

11:13 fliebel: Raynes: Wait and see, it'll be awesome :) But for now: hammock time.

11:13 Raynes: jjido: Yeah, but not necessarily just one.

11:13 jjido: agreed

11:15 LauJensen: tomoj: Hows that screencast coming along?

11:16 scottj_: uses are a pain. I'd hate to start every file of with uses clojure.agents clojure.seq clojure.files clojure.files.extra clojure.futures

11:17 Raynes: scottj_: Exactly.

11:21 bartj: Is this a bug in clojure.contrib.json or am I just using it inappropriately? - http://pastie.org/1283998

11:21 I mean with the read-json function

11:21 can anyone please have a look at the paste ?

11:27 vibrant: ook, so i'm defining a macro in namespace a which produces code using functions from that namespace

11:27 and when i try to call the macro in namespace b, it says that it can't resolve a given symbol (that function name)

11:27 is there a correct way to do it?

11:28 LauJensen: bartj: IIRC clj-json on github is the preferred way to go. Should be 2.5x faster IIRC

11:28 jjido: vibrant: don't use a macro?

11:28 bartj: LauJensen, thanks a bunch, but what is IIRC ?

11:28 LauJensen: If I Remember Correctly

11:29 bartj: LauJensen, will check it out; but, the issue is not of speed, I think there is a bug?

11:30 LauJensen, to put it lightly, what goes in, doesn't come out the same

11:30 LauJensen: bartj: Not sure. I never use JSON.

11:31 bartj: LauJensen, may I ask what do you use?

11:32 LauJensen: bartj: Well it depends a lot of what Im doing. If its just data to/from a browser I use the regular {key: val} notation. I've seen people use JSON is non-web contexts as well. Would never do that.

11:33 bartj: LauJensen, interesting...if you had to use Redis, and had to store mutliple values in a hash map, would you still not serialize the values to json?

11:33 LauJensen: Ask me again once Ive implemented my first Redis solution

11:34 afk

11:35 bartj: forget Redis

11:35 if you had to serialize mutliple values in a hash key ?

11:36 vibrant: why is there no sequential binding clause?

11:36 or is there?

11:37 scottj_: vibrant, do you really mean binding or actually let?

11:37 vibrant: let is sequential i mean binding

11:38 scottj_: vibrant: re macro, are the functions fully qualified after expansion?

11:38 vibrant: scottj; nope.

11:39 scottj_: vibrant: bc you're quoting them?

11:39 vibrant: http://pastebin.ca/1986444

11:40 cmd-* functions reside in another namespace which is :used in the one in which the macro is

11:41 scottj_: maybe wrap (symbol...) in resolve

11:41 Derander: so many functions to learn in clojure

11:41 fun fun fun

11:41 opqdonut: you must mean fn fn fn

11:45 vibrant: scottj; now it says 'can't call nil'

11:46 scottj_: update pastebin

11:48 Derander: When should I use "use" vs "require"?

11:49 scottj_: the bot must have an answer for that faq

11:49 Derander: http://stackoverflow.com/questions/871997/use-vs-require-in-clojure <-- I should have just googled.

11:56 tonyl: morning

11:58 amalloy: morning for real, tonyl

11:59 tonyl: amalloy: i'm in a conference, early morning. now some free time

11:59 * tonyl first time using a command-line irc client

12:00 amalloy: tonyl: fun. maybe erc?

12:00 fliebel: Is there something like exclusive or other than the bitwise one?

12:01 tonyl: amalloy: don't know emacs :( i'm using irssi

12:01 technomancy: they have gui IRC clients now?

12:01 amalloy: awww, no emacs! your life is so sad

12:02 technomancy: the irc guis all collect identification data so that the command-line folks will have no trouble wiping us out when the revolution comes

12:02 tonyl: amalloy: I am learning it... slowly

12:02 hsuh: hi guys... so i have this hairy macro which isnt working (doesnt it always start like this?)... http://pastie.org/1284771

12:03 the "argmap" can't be used like that, i tried using argmap# but that didn't work too, although it would give another error

12:03 i'm wondering if i'm on the right direction or macros like this will just bring pain to me instead of making the rest of the code simpler

12:03 clojurebot: Barking spiders!

12:04 amalloy: argmap# is the right first step

12:04 after that, time to see what the real error is

12:05 hsuh: why? one would think that since argmap is quoted there would be no complaint?

12:05 scottj_: fliebel: don't think so. like this? (defn xor [x y] (= x (not y)))

12:05 amalloy: `(let [argmap 1])

12:05 &`(let [argmap 1])

12:05 sexpbot: ⟹ (clojure.core/let [clojure.core/argmap 1])

12:05 amalloy: &(let [clojure.core/argmap 1])

12:05 sexpbot: java.lang.Exception: Can't let qualified name: clojure.core/argmap

12:05 fliebel: scottj_: Yea, think so...

12:05 amalloy: hsuh: ^^

12:06 `(syntax-quote) is not the same as '(quote)

12:06 hsuh: amalloy: what are you saying that clojure is different from elisp ?

12:07 amalloy: hsuh: say it ain't so! :P

12:07 hsuh: ok with argmap# i have a much more interesting error, now at "runtime"

12:07 amalloy: it also looks like ~(args-names args) is a problem

12:08 it will be saying you can't call the first element of args-names as a function

12:08 hsuh: yeah something like that, java.lang.String cannot be cast to clojure.lang.IFn

12:08 nice clojure evaluator you got there

12:09 amalloy: ?

12:09 hsuh: in your head.. because i totally missed that...

12:09 amalloy: haha

12:09 well

12:09 i had the exact same issue last night

12:09 so...

12:09 &(let [args '("foo" "bar")] `(blah ~(args)))

12:09 sexpbot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

12:09 amalloy: &(let [args '("foo" "bar")] `(blah ~args))

12:09 sexpbot: ⟹ (clojure.core/blah ("foo" "bar"))

12:10 amalloy: hsuh: see what ~args is expanding to?

12:10 &(let [args '("foo" "bar")] `(blah ~(vec args)))

12:10 sexpbot: ⟹ (clojure.core/blah ["foo" "bar"])

12:10 hsuh: gimme two days

12:10 amalloy: this is more like what you meant

12:21 hsuh: working now?

12:22 hsuh: amalloy: err.. almost

12:24 amalloy: oh. you want ~@body

12:25 hsuh: ok, but the error is still on that like, the args-name thing

12:25 amalloy: and you changed it to use (vec args-names)? i don't see that in the paste

12:25 hsuh: i didn't changed the paste, i actually moved 'vec' inside args-names

12:27 Chousuke: what's your macroexpansion at the moment?

12:29 hsuh: i posted a little simpler version

12:29 http://pastie.org/1284828

12:29 Tordmor: ~pasge

12:29 clojurebot: I don't understand.

12:29 Tordmor: ~paste

12:29 clojurebot: lisppaste8, url

12:30 Tordmor: hm

12:30 hsuh: while i get amalloy example, i can't translate it to what is wrong there

12:30 oh and the error is, when trying to eval (test) i get java.lang.String cannot be cast to clojure.lang.IFn (like before...)

12:30 Chousuke: hsuh: I don't understand at all what you're trying to do

12:31 Tordmor: anybody knows why this won't quit, after printing my packages list? http://pastie.org/1284834

12:31 Chousuke: but in (map name (vec args)) the vec is completely redundant

12:31 hsuh: hm

12:32 Chousuke: args-names is still returning a list

12:32 or a seq

12:32 which means a function call

12:32 hsuh: ok now it works...

12:32 what do you mean by "whcih means a function call" ?

12:32 Chousuke: a list form is a function call.

12:33 your macro emits a list, therefore it's evaluated as a function call

12:33 hsuh: of course, now it makes sense

12:33 tks amalloy, Chousuke

12:34 its kinda like '[1 2 3] can be understood as [1 2 3], but '(1 2 3) cant be seen as (1 2 3), right?

12:34 Chousuke: hsuh: hm, well

12:35 ,'(1 2 3) :P

12:35 clojurebot: (1 2 3)

12:35 Chousuke: the thing is, when you evaluate (1 2 3) it's treated as a function call

12:35 amalloy: sure: &|[1 2 3]|& is okay, but &|(1 2 3)|& is no good, and the latter is what you were running after macroexpansion

12:35 sexpbot: [1 2 3] ⟹ [1 2 3]

12:35 (1 2 3) java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

12:36 Chousuke: note though that there's a difference between '[foo bar] and [foo bar] :P

12:36 the former is a vector if symbols, and the latter is a vector of whatever foo and bar evaluate to

12:37 hsuh: hm, true... forget what i said

12:40 Chousuke: macros become a lot easier after you understand the whole "code is data" thing

12:41 and the evaluation semantics of the different data elements used.

12:42 hsuh: amalloy: strangely it only works with ~body instead of ~@body

12:42 Chousuke: hsuh: that's because you only accept a single expression as the body

12:43 You should destructure decl as [args & body]

12:43 hsuh: beautiful

12:43 amalloy: also if won't let you splice

12:44 i mean, it will, but won't do what you want

12:44 you should probably use when here

12:44 Chousuke: or you can just do (.. [name args & body] ...)

12:45 or you can just use do

12:45 for the if

12:46 hsuh: Chousuke: there is an else part to that if, is just that you are seeing the second version i think... let me post the working version

12:47 does seeing a "with-meta" on the macroexpansion means anything special about my code?

12:48 Chousuke: I'm not sure

12:48 do you intend for the macro to expand to code that attaches metadata to something?

12:48 hsuh: no

12:48 i'm just afraid of reflection because i read its eevil

12:48 Chousuke: then it's probably wrong .)

12:48 amalloy: hsuh: metadata has nothing to do with reflection

12:49 hsuh: i also dont knew that too of course

12:49 Chousuke: amalloy: :tag metadata is used to avoid it.

12:49 hsuh: pastie is slow, or i am

12:49 Chousuke: for symbols

12:49 and lists

12:49 hsuh: here is the working thing: http://pastie.org/1284771

12:49 amalloy: Chousuke: okay, fair enough

12:49 hsuh: the idea is that defn* will help me write dozens of similar functions for a webapp

12:49 without repeating code... is that a fair use of macros?

12:50 amalloy: that's pretty much what macros are for

12:51 Chousuke: seems fine.

12:51 I'm not seeing with-metas either :P

12:52 hsuh: so i'm not using macroexpand right

12:52 check the withMeta on http://pastie.org/1284771... am i doing something wrong?

12:53 oh i'm on slime.. that might be it ?

12:54 Chousuke: hsuh: that's defn, not your macro :)

12:54 hsuh: but i want to expand an usage of the macro, or the macro? :)

12:54 Chousuke: anyway, it's fine

12:54 your macro expands to a defn which expands to something .withMeta

12:55 hsuh: heh

12:55 jfields: do dosyncs retry infinitely?

12:55 amalloy: jfields: no

12:55 but they try quite a few times

12:55 Chousuke: 10000, or something :P

12:55 jfields: amalloy, any docs on the web? I'm looking in the Joy of Clojure and not seeing any details

12:55 hsuh: Chousuke: hm, but my test function is almost mempty..

12:56 amalloy: jfields: that's funny, JoC is where i remember learning this. i'll take a look

12:56 Chousuke: hsuh: yes? the expansion looks correct to mee

12:56 -e

12:56 hsuh: Chousuke: what about the withMeta?

12:56 Chousuke: hsuh: that's correct too

12:57 hsuh: it's just adding metadata to the resulting function

12:57 hsuh: oh

12:57 Chousuke: hsuh: it's what defn does

12:57 hsuh: ohhh

12:57 ok ok

12:58 amalloy: jfields: check out 11.1.4

12:59 "First, there are transaction restart limits..."

12:59 hsuh: to be sincere though, if your patience allows, i still don't get why i can't use argmap without gensym... since that is just "literal text" that should appear on the expanded form

12:59 jfields: amalloy, thanks

12:59 amalloy: hsuh: no it isn't

13:00 Chousuke: hsuh: it's not text :)

13:00 it's a symbol

13:00 hsuh: and it might conflict with local bindings

13:00 amalloy: if you used exactly the same name every time, there would be problems with nesting. someone else might use that same name, or you might step on a local

13:00 or you might even expend your macro recursively, stepping on your own local

13:01 Chousuke: what are you going to do if someone does (let [argmap foo] (defn* test [a b c] (somestuff argmap)))?

13:01 hsuh: see it know

13:02 now

13:02 amalloy: hsuh: clojure makes it very hard to make that mistake on accident, but there are occasions when you actually want to do it

13:02 see the google group for an example

13:06 hsuh: using a macro like this i have to make sure that functions used by the macro (the expanded defn) are acessible where the macro is used... is there any alternative to this or just live with it ?

13:07 kotarak: hsuh: use a foo.internal namespace which is :use'd in foo (where your macro lives) or @#'foo/shout-at-the-private-var long enough.

13:14 hsuh: kotarak: tks

13:35 kotarak: Someone ever used expect on Windows? Does anyone still use expect anyway?

13:54 fogus_: pdlogan: Are you the author of the blog http://patricklogan.blogspot.com ?

13:55 pdlogan: fogus_: yep

13:55 fogus_: pdlogan: One of my favorite blogs of all time. I miss it.

13:56 pdlogan: hmm... thanks. I've been thinking about posting a new one re: some clojure / web stuff I've been dinking with.

13:57 fogus_: Well, here's me hoping you do.

13:57 pdlogan: (n.b. my views on clojure have changed a good bit since I was blogging there)

13:58 fogus_: for better or worse. ;-)

13:59 pdlogan: (better)

14:03 pppaul: (inc better)

14:03 sexpbot: ⟹ 1

14:03 fliebel: When I wrote this function, only God and I knew what I was doing. Now only God knows. https://github.com/pepijndevos/clj-fneeid/blob/master/src/fneeid.clj

14:04 pppaul: weird

14:04 (doc resfn)

14:04 clojurebot: It's greek to me.

14:06 amalloy: fliebel: having a truth parameter is bizarre, since you just use (not) anyway

14:07 which always returns either true or false

14:07 fliebel: amalloy: How is it bizarre?

14:08 amalloy: What I'm doing is that if truth is true, I "filter" while otherwise I "remove"

14:08 amalloy: ugh. just make your users pass in (complement f) instead of f; it's more readable on both sides of the function call

14:09 fliebel: amalloy: Doesn't work the same… function is determined on the outer fn, while truth is defined on the inner fn.

14:12 amalloy: Depending on how you call the inner fn it gives you one or the other half of input, which is passed around through either positive or negative.

14:12 pppaul: ,(clojure.contrib.math/round (rand 10))

14:12 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.math

14:13 amalloy: &(rand-int 10)

14:13 sexpbot: ⟹ 5

14:13 kotarak: ,(require 'clojure.contrib.math)

14:13 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/math__init.class or clojure/contrib/math.clj on classpath:

14:16 amalloy: fliebel: i'm not going to try to understand why you want your function to do this. but you could make it more readable, i think, by using (filter (comp #{truth} boolean function)), since you seem to just be using (not) to coerce things to booleans

14:18 fliebel: amalloy: I'm doing sort of a conditional complement, so I could do (if truth fuction (complement function))

14:19 amalloy: yep, you could do that too

14:19 which is probably nicer since it doesn't involve booleans where they don't belong :P

14:22 pppaul: ,(repeatedly 40 #(rand-int 11))

14:22 clojurebot: (10 6 1 4 10 6 6 4 5 4 ...)

14:22 amalloy: &(repeatedly 40 #(rand-int 11)) :)

14:22 sexpbot: ⟹ (3 7 7 5 6 4 1 9 5 5 10 10 10 8 2 2 10 8 1 4 3 7 2 0 10 1 2 3 5 4 9 3 10 4 0 4 8 5 0 7)

14:27 pppaul: &(repeatedly 400 #(rand-int 11))

14:27 sexpbot: ⟹ (4 8 10 6 10 5 8 3 3 5 8 9 4 9 5 8 1 3 6 8 2 10 10 8 3 6 9 8 9 5 5 5 2 9 1 10 8 0 7 2 0 2 8 4 1 8 0 0 4 1 10 7 10 6 6 8 4 9 4 10 10 4 1 6 1 6 1 10 6 1 6 3 9 2 9 6 6 10 10 0 10 6 7 9 1 10 9 3 2 1 7 8 8 0 2 8 6 7 9 4 7 8 10 3 5 8 8 2 1 3 6 4 1 6 4 0 4 3 1 6 2 10 0 8 1 2 10 0 9 1 2 10 4 4 10 9 4 9 3 6 ... http://gist.github.com/669654

14:28 pppaul: sexbot is the way to go!

14:28 bobo_: im impressed!

14:28 ohpauleez: also funny that you called him sexbot, I wonder how many times that will happen

14:29 pppaul: sexbot should know his nick-name

14:30 ohpauleez: haha

14:30 amalloy: ohpauleez: it will happen a lot :P

14:31 i have to type sex<TAB> to get into my repo; i never use the p, so if i ever need to use it in a non-tab-completion context...

14:31 pppaul: it would be cool if clojurebot has a lisp

14:32 amalloy: $sed -pppaul s/s/th/

14:32 sexpbot: <pppaul> it would be cool if clojurebot hath a lithp

14:32 amalloy: :P

14:32 pppaul: ahaha

14:35 &(= '(1 2 3 4) '(4 3 2 1))

14:35 sexpbot: ⟹ false

14:36 pppaul: i guess i have to sort to compare for equality if order doesn't matter for me?

14:37 kotarak: clojurebot: botsnack

14:37 clojurebot: thanks; that was delicious. (nom nom nom)

14:37 amalloy: pppaul: use sets

14:37 fliebel: How can I make partial retain the meta of the original fn?

14:37 pppaul: a set wouldn't work because i need duplicate entries

14:37 amalloy: &(= #{1 2 3 4} #{3 4 1 2})

14:37 sexpbot: ⟹ true

14:38 pppaul: &(= #{1 3 3 3} #{3 3 1 1})

14:38 sexpbot: java.lang.IllegalArgumentException: Duplicate key: 3

14:38 kotarak: fliebel: (with-meta (partial f arg) (meta f))?

14:38 amalloy: pppaul: you could sort, or use every?/some

14:38 ohpauleez: pppaul: You can use sets, or map a set operation across both lists

14:38 fliebel: kotarak: Yea, that sort of stuff.

14:38 ohpauleez: damnit amalloy, stop jumping on my suggestions

14:38 :)

14:38 kotarak: fliebel: well, that was the answer

14:38 amalloy: ohpauleez: mine isn't actually any good

14:38 pppaul: (doc every)

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

14:38 fliebel: kotarak: Thanks :)

14:39 amalloy: oh! i know the answer pppaul!

14:39 pppaul: !

14:39 i think i need to sort

14:39 amalloy: nonono

14:39 pppaul: ^_~

14:39 ohpauleez: I think you can use all, or another set operation

14:39 amalloy: &(= (map frequencies [[1 2 3 4 3] [3 4 1 3 2]])

14:39 ohpauleez: on the lists

14:39 sexpbot: java.lang.Exception: EOF while reading

14:39 amalloy: &(= (map frequencies [[1 2 3 4 3] [3 4 1 3 2]]))

14:39 sexpbot: ⟹ true

14:39 pppaul: wooah

14:39 &(doc frequencies)

14:39 sexpbot: ⟹ "([coll]); Returns a map from distinct items in coll to the number of times they appear."

14:40 amalloy: gonna be much faster than sort

14:40 pppaul: sure that isn't sorting?

14:40 amalloy: although haha i typed it wrong

14:40 &(apply = (map frequencies [[1 2 3 4 3] [3 4 1 3 2]]))

14:40 sexpbot: ⟹ true

14:40 amalloy: yeah it's not doing a full sort. it's hashing

14:41 ohpauleez: yeah, that's a good one actually

14:41 amalloy: &(apply = (map frequencies [[1 2 3 4 3] [3 4 1 4 2]]))

14:41 sexpbot: ⟹ false

14:42 pppaul: $(freguencies [ 1 2 2 3 3 4 5 5])

14:42 &(freguencies [ 1 2 2 3 3 4 5 5])

14:42 sexpbot: java.lang.Exception: Unable to resolve symbol: freguencies in this context

14:42 kotarak: (defn =-by [f & items] (apply = (map f items)))

14:42 pppaul: &(frequencies [ 1 2 2 3 3 4 5 5])

14:42 sexpbot: ⟹ {1 1, 2 2, 3 2, 4 1, 5 2}

14:42 pppaul: um, that is a sort

14:43 amalloy: pppaul: no it isn't. it's a hashmap

14:43 pppaul: it's like count-sort

14:43 amalloy: &(frequencies [ 1 2 2 3 3 4 5 55 1231])

14:43 sexpbot: ⟹ {1 1, 2 2, 3 2, 4 1, 5 1, 55 1, 1231 1}

14:43 pppaul: or bucket-sort

14:43 amalloy: bucket-sort, if you like. but that's faster than actually sorting the list

14:43 kotarak: &(frequencies [1 2 3 4 2 1231 55])

14:43 sexpbot: ⟹ {1 1, 2 2, 3 1, 4 1, 1231 1, 55 1}

14:43 pppaul: i know ^_^

14:43 amalloy: ah. thanks kotarak

14:44 pppaul: oh

14:44 amalloy: there, see? no sorting pppaul, just hashing :P

14:44 kotarak: small maps are array maps.

14:44 amalloy: oh yeah

14:44 LauJensen: large maps are sorted with rand-elt

14:44 amalloy: &(frequencies (range 2000))

14:44 sexpbot: ⟹ {0 1, 1024 1, 32 1, 1056 1, 64 1, 1088 1, 96 1, 1120 1, 128 1, 1152 1, 160 1, 1184 1, 192 1, 1216 1, 224 1, 1248 1, 256 1, 1280 1, 288 1, 1312 1, 320 1, 1344 1, 352 1, 1376 1, 384 1, 1408 1, 416 1, 1440 1, 448 1, 1472 1, 480 1, 1504 1, 512 1, 1536 1, 544 1, 1568 1, 576 1, 1600 1, 608 1, 1632 1, 640 ...

14:44 amalloy: &(frequencies (range 200))

14:44 sexpbot: ⟹ {0 1, 32 1, 64 1, 96 1, 128 1, 160 1, 192 1, 1 1, 33 1, 65 1, 97 1, 129 1, 161 1, 193 1, 2 1, 34 1, 66 1, 98 1, 130 1, 162 1, 194 1, 3 1, 35 1, 67 1, 99 1, 131 1, 163 1, 195 1, 4 1, 36 1, 68 1, 100 1, 132 1, 164 1, 196 1, 5 1, 37 1, 69 1, 101 1, 133 1, 165 1, 197 1, 6 1, 38 1, 70 1, 102 1, 134 1, 16... http://gist.github.com/669681

14:45 pppaul: cool

14:45 LauJensen: &(set (range 32))

14:45 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}

14:45 amalloy: it's "sorted" by hashcode, because it's a hashmap

14:45 LauJensen: &(set (range 33))

14:45 sexpbot: ⟹ #{0 32 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}

14:45 kotarak: &(frequencies (range 8))

14:45 sexpbot: ⟹ {0 1, 1 1, 2 1, 3 1, 4 1, 5 1, 6 1, 7 1}

14:45 amalloy: LauJensen: that one never gets old :)

14:45 kotarak: &(frequencies (range 9))

14:45 sexpbot: ⟹ {0 1, 1 1, 2 1, 3 1, 4 1, 5 1, 6 1, 7 1, 8 1}

14:45 pppaul: &(frequencies (repeatedly 10000 (rand-int 11)))

14:45 sexpbot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

14:45 LauJensen: amalloy: that and hardcoded small ints and booleans

14:45 kotarak: &(frequencies (range 10))

14:45 sexpbot: ⟹ {0 1, 1 1, 2 1, 3 1, 4 1, 5 1, 6 1, 7 1, 8 1, 9 1}

14:46 kotarak: bleh

14:46 amalloy: ?

14:46 kotarak: 8 entries is the limit IIRC.

14:46 for array maps

14:46 amalloy: kotarak: small integers hash to themselves, so even a hashmap will look sorted

14:47 &(frequencies (range 50 60))

14:47 sexpbot: ⟹ {50 1, 51 1, 52 1, 53 1, 54 1, 55 1, 56 1, 57 1, 58 1, 59 1}

14:47 pppaul: &(frequencies (repeatedly 1000 (rand-int 11)))

14:47 sexpbot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

14:47 pppaul: what am i doing wrong?

14:47 amalloy: &(frequencies (repeatedly 1000 #(rand-int 11)))

14:47 sexpbot: ⟹ {0 105, 1 101, 2 85, 3 94, 4 71, 5 80, 6 83, 7 91, 8 99, 9 93, 10 98}

14:47 pppaul: oh yeah

14:48 silly me

14:48 amalloy: sexpbot: you don't like 4?

14:48 (inc 4)

14:48 sexpbot: ⟹ 1

14:48 amalloy: *giggle*

14:49 pppaul: &(frequencies (repeatedly 100000 #(rand-int 11)))

14:49 sexpbot: ⟹ {0 9216, 1 9098, 2 8977, 3 9098, 4 9005, 5 9053, 6 8979, 7 9227, 8 9041, 9 9151, 10 9155}

14:50 pppaul: so, in your solution, what's the diff of (=... and (apply =...

14:50 amalloy: &(= (range 2))

14:50 sexpbot: ⟹ true

14:50 amalloy: &(apply = (range 2))

14:50 sexpbot: ⟹ false

14:51 amalloy: 1: is (range 2) equal to itself? yes

14:51 2: is 0 equal to 1? no

14:52 micahmartin: What's the better name for a rspec port to clojure: 'specl' or 'speclj' (both pronounced 'speckle')?

14:52 pppaul: &(map frequencies '((1 2) (2 1)))

14:52 sexpbot: ⟹ ({1 1, 2 1} {2 1, 1 1})

14:53 pppaul: &(=(map frequencies '((1 2) (2 1))))

14:53 sexpbot: ⟹ true

14:53 pppaul: &(apply = (map frequencies '((1 2) (2 1))))

14:53 sexpbot: ⟹ true

14:53 pppaul: i understand the reason to use apply, since we are getting back a seq

14:53 amalloy: &(=(map frequencies '((1 2) (212321))))

14:53 sexpbot: ⟹ true

14:54 pppaul: why is (=... working?

14:54 amalloy: it's not

14:54 it will always return true

14:54 pppaul: oh

14:54 &(= 5)

14:54 sexpbot: ⟹ true

14:54 pppaul: i see

14:56 amalloy: &(=)

14:56 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$-EQ-

14:56 amalloy: aw

14:56 &(+)

14:56 sexpbot: ⟹ 0

15:03 pppaul: &(replicate 100 '10)

15:03 sexpbot: ⟹ (10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10... http://gist.github.com/669721

15:03 pppaul: better than cycle!

15:07 fliebel: It is working! https://github.com/pepijndevos/clj-fneeid/blob/master/src/fneeid.clj Line 17 and 18 can be other questions, which can contain other questions in turn. This way you can get down to the function you need.

15:10 pppaul: my input is (1 + 2 + 3 + 4) i want my output to be (1 2 3 4) (+ + +) i've looked over the seq functions and thought (partition would do what i wanted, but i don't think so... is there something like (take with steps?

15:11 fliebel: pppaul: take-nth?

15:12 pppaul: thanks

15:13 fliebel: &((juxt #(take-nth 2 %) #(take-nth 2 (next %)) [1 2 3 4 5 6])

15:13 sexpbot: java.lang.Exception: EOF while reading

15:13 pppaul: (take-nth 2 data) & (take-nth 2 (rest data))

15:14 kotarak: &((juxt #(take-nth 2 %) #(take-nth 2 (next %))) '(1 + 2 + 3 + 4))

15:14 sexpbot: ⟹ [(1 2 3 4) (+ + +)]

15:14 kotarak: &separate

15:14 sexpbot: java.lang.Exception: Unable to resolve symbol: separate in this context

15:14 pppaul: is there a reason for using next instead of rest?

15:14 fliebel: pppaul: Not unless you care about total lazyness

15:14 kotarak: pppaul: next is faster in case you know you'll need the result anyway

15:15 pppaul: rest is required to be 100% lazy

15:15 pppaul: i thought they were almost the same cept one returned nil

15:16 kotarak: pppaul: which implies that it can't be 100% lazy.

15:16 pppaul: it has to realise the sequence to judge whether to return nil or not.

15:16 amalloy: $source next

15:16 sexpbot: next is http://is.gd/gSsNS

15:16 amalloy: hm. i didn't realize next was faster; i just assumed it was (comp seq rest). thanks kotarak

15:17 kotarak: amalloy: using the result of next may be faster

15:17 pppaul: the details of the source is pretty hidden

15:17 one calls more, one calls next...

15:18 kotarak: amalloy: whether next is (comp seq rest) depends on what you have. eg. for lazy-seq yes. For a seq on a vector rest is rather (or (next s) ()).

15:19 amalloy: pppaul: you can look up the java source for more and next, though that tends to be hard to track down too :P

15:19 kotarak: huh. i guess that makes sense

15:19 kotarak: look in src/jvm/clojure/lang/ASeq.java

15:19 fliebel: What questions do you ask yourself to get to the function you need? I'm trying to come up with useful questions for https://github.com/pepijndevos/clj-fneeid/blob/master/src/fneeid.clj

15:20 kotarak: amalloy: it depends on your underlying thing being lazy or not. datastructures are not lazy.

15:20 amalloy: right

15:21 pppaul: ^_^

15:21 amalloy: fliebel: what are you trying to do? write a decision tree that asks the user "are you doing x? what about y? in that case, maybe you should use pmap"?

15:22 fliebel: amalloy: Exactly :)

15:22 amalloy: you could do it like those online 20-question games

15:23 hm, i can't find one easily

15:23 aha! fliebel: http://www.guessthename.com/

15:26 fliebel: amalloy: That's the plan. :)

15:26 amalloy: fliebel: my point is, they don't build this ahead of time

15:27 fliebel: amalloy: huh?

15:27 amalloy: they crowdsource it: if you think of an entry they can't guess, then they prompt you for a question that would disambiguate

15:27 and add that to the question database

15:27 http://www.guessthename.com/movie/?pos=20387n

15:28 so rather than building a tree yourself by hand, write a program that will ask you questions and build a tree itself

15:31 fliebel: amalloy: Then it'd have to be a web app or something.

15:32 amalloy: fliebel: my plan was for you to run it yourself at the repl to build up the db :P

15:33 the idea being that that's easier than hard-coding the tree

15:33 fliebel: amalloy: And another problem is that their system only rules out one show per question, if I'm correct.

15:34 amalloy: no, although it does have kinda a poor database

15:36 imagine you had a tree that looked like: (is it a sequence? {yes: (do you want a sequence as a result? {yes: map, no: reduce}), no: inc})

15:36 then answering no to the first question eliminates both map and reduce

15:36 fliebel: amalloy: How? I tell them at the end that I was thinking about b and now a and give them a rule to define that. So depending on my answer they can rule out a or b, but there is no way to tell if c matches my question or not.

15:37 amalloy: They haven't a tree where you can kill branches.

15:37 pppaul: &(drop 3 [1 + 2 + 3 + 4])

15:37 sexpbot: ⟹ (#<core$_PLUS_ clojure.core$_PLUS_@8b8791> 3 #<core$_PLUS_ clojure.core$_PLUS_@8b8791> 4)

15:37 amalloy: fliebel: yeah, actual crowd-sourcing tends to lead to not-very-good data

15:38 KirinDave: So you all can see what a lousy clojure coder I am. ;)

15:38 amalloy: i was just proposing a way to make your development more interactive and intuitive by having the program ask you for questions. if you want to do it another way, feel free

15:38 pppaul: &(drop 3 [1 '+ 2 '+ 3 '+ 4])

15:38 sexpbot: ⟹ (+ 3 + 4)

15:39 fliebel: amalloy: You have a point there.

15:39 pppaul: wisdom in crowds

15:39 or was is crows?

15:41 amalloy: KirinDave: how can we see what a lousy coder you are? i don't see any other messages from you

15:41 KirinDave: amalloy: Oh. There is this twitter thing. But...

15:41 https://github.com/BankSimple/Clothesline

15:43 amalloy: I guess it's customary to fire off an ANN to the mailing list, huh?

15:44 amalloy: KirinDave: i dunno. i've seen some of those and it certainly wouldn't be spam, but you can invent your own customs

15:44 but some of us don't follow twitter

15:45 KirinDave: Better people than me don't use twitter. ;)

15:45 kzar: How come 08 is an invalid number? ,08

15:45 (well I get that it's because it starts with 0 but why does that make it invalid?)

15:46 &08

15:46 sexpbot: java.lang.NumberFormatException: Invalid number: 08

15:46 amalloy: KirinDave: i don't use twitter either :P

15:46 &010

15:46 sexpbot: ⟹ 8

15:46 tlockney: kzar: because it's read as octal when you put the 0 in front

15:46 KirinDave: kzar: Here is a hit

15:46 ,07

15:47 clojurebot: 7

15:47 kzar: Oh gotya, thanks

15:47 KirinDave: ,09

15:47 clojurebot: Invalid number: 09

15:47 KirinDave: (fail)

15:47 fliebel: &(read-string (str "0." "08" "e2"))

15:47 sexpbot: ⟹ 8.0

15:48 kzar: Oh cool there was an easy way to strip the leading 0 in my code

15:49 amalloy: kzar: &(apply str (drop-while #{\0} "0008"))

15:49 kzar: &|(apply str (drop-while #{\0} "0008"))|&

15:49 sexpbot: ⟹ "8"

15:50 amalloy: hmmm. maybe i should get sexpbot to recognize nick: &expr

15:50 fliebel: amalloy: Good one :)

15:51 kzar: amalloy: and then get it to check the nick and if it's kzar fuck with me by showing the wrong results

15:51 amalloy: kzar: that code is already there

15:51 kzar: heh

15:52 amalloy: kzar: &|(= (map range [10 20]))|&

15:52 sexpbot: ⟹ true

15:52 amalloy: see?

15:53 kzar: amalloy: I get it, you want apply =

15:53 amalloy: *chuckle* yes. but for a second it looks like sexpbot is lying to confuse you

15:53 fliebel: amalloy: I think that made it upstream into Clojure, it gives the same result for me on my own repl :S

15:53 amalloy: hahaha

15:53 kzar: amalloy: (apply = (map range [10 20]))

15:53 oops

15:53 amalloy: |&(apply = (map range [10 20]))

15:53 amalloy: &|(apply = (map range [10 20]))

15:54 fliebel: kzar: traing one as well

15:54 amalloy: kzar: &|'[some expr]|&

15:54 sexpbot: ⟹ [some expr]

15:54 amalloy: it needs to be on both ends

15:54 kzar: amalloy: &|(apply = (map range [10 20]))|&

15:54 sexpbot: ⟹ false

15:54 kzar: oh yea

15:54 amalloy: and yes, i know. this was a topic of discussion in #clojure an hour or two ago

15:54 fliebel: that is what i... tried to say :(

15:55 amalloy: kzar: btw, if you can think of a better way to unambiguously delimit exprs than the &| nonsense, let me know

15:55 kzar: amalloy: How about this, if you type a sexp with no special characters the bot doesn't eval but it notices. Then if you type eval it evals it

15:55 amalloy: i will happily add it

15:56 kzar: too hard, and also vague. everything you type is a sexp

15:56 how does he know "sexp" wasn't something i might want to eval later? it's a valid symbol

15:57 kzar: amalloy: Well for that feature it would just worry about things in parenthesis I guess but good point

15:57 amalloy: &[(inc 1) (dec 1)]

15:57 sexpbot: ⟹ [2 0]

15:57 amalloy: anyway

15:58 but if you can think of something within a single message that's easier to type than &| i'd love to hear it

15:58 maybe #=expr=#

15:59 jarpiain: ,`=#

15:59 clojurebot: =__147__auto__

15:59 amalloy: ah

15:59 jarpiain: =# is legal clojure, but so is |&. they're both things nobody is likely to type though :P

15:59 jjido: amalloy: does it have to have a closing tag?

16:00 kzar: Yea I mean if there's a end of message before the closing tag couldn't it just take the hint ?

16:00 amalloy: jjido: without it, you can't do &|'clever|& stuff like &|(inc 1)|&

16:00 sexpbot: 'clever ⟹ clever

16:00 (inc 1) ⟹ 2

16:00 amalloy: but you're right, i could let it implicitly close at EOM

16:02 though atm only Raynes has permission to restart sexpbot, and he's taking a nap

16:03 jjido: how about &|('clever) &|((inc 1))

16:04 amalloy: jjido: yeah, i can do that too

16:05 i think i'll add ## as well, with similar shorthand forms

16:09 jjido: ##10 ##11

16:09 buttered-toast: 10 ⟹ 10

16:09 11 ⟹ 11

16:10 amalloy: good? any other suggestions?

16:11 jjido: amalloy: good. I suggest skipping ## if it appears inside a matched pair of double quotes

16:11 buttered-toast: java.lang.Exception: Unable to resolve symbol: if in this context

16:11 amalloy: jjido: sadly that's kinda too hard :P

16:11 regexes aren't that clever

16:11 jjido: (println "## hello")

16:11 buttered-toast: java.lang.Exception: Unable to resolve symbol: hello in this context

16:11 amalloy: yes, i know what you mean

16:12 but such is life. that's why Raynes picked the super-obscure &|'syntax|& - to avoid any accidental matches

16:12 sexpbot: ⟹ syntax

16:12 buttered-toast: ⟹ syntax

16:12 amalloy: haha sorry bots

16:12 pppaul: i want to (eval (+ 1 2)) from seq (1 + 2) named 'data' i tried (eval (list (second data) (first data) (nth 3 data))) but got a cast error from lazySeq to number

16:13 amalloy: &|(nth [1 2 3] 2)|& &|(nth 2 [1 2 3])|&

16:13 sexpbot: (nth [1 2 3] 2) ⟹ 3

16:13 (nth 2 [1 2 3]) java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number

16:14 pppaul: i think my problem is (class +) != (class (second data))

16:14 amalloy: no pppaul, see my eval above for what your problem is

16:14 you have two: params in wrong order; (nth n 0) == (first n)

16:15 pppaul: oh

16:15 amalloy: i think you also need to quote the + if it's not already quoted

16:15 pppaul: (eval (list (second data) (first data) (nth data 3)))

16:15 java.lang.Exception: Unable to resolve symbol: 1 in this context (NO_SOURCE_FILE:159)

16:15 the error changed

16:16 &(class +)

16:16 sexpbot: ⟹ clojure.core$_PLUS_

16:16 pppaul: my '+' is a symbol, though

16:16 jjido: ,(re-seq #"(([^\"]*\"){2})*##" "(println \"## hello\")")

16:16 clojurebot: (["##" nil nil])

16:16 pppaul: &(class (quote +))

16:16 sexpbot: ⟹ clojure.lang.Symbol

16:17 amalloy: &(list* (map #(nth '(1 + 2) %) [1 0 2]))

16:17 sexpbot: ⟹ (+ 1 2)

16:17 pppaul: &(class (unquote (quote +)))

16:17 sexpbot: java.lang.IllegalStateException: Var clojure.core/unquote is unbound.

16:17 amalloy: jjido: and what about \\"? that really is the end of a quote

16:17 and \\\" isn't

16:18 it's probably possible but i think failing when ## is part of the string is an acceptable compromise for getting easy multi-eval

16:19 jjido: yes, at worse there will be more messages in the channel

16:19 amalloy: right, or someone who actually wants to write ##(println "##foo") will have to use & instead :P

16:19 pppaul: see my list* for how i would rearrange your list

16:20 pppaul: yeah, that's what i'm doing, your's is shorter

16:20 amalloy: and eval isn't working?

16:22 cs02rm0: does anyone know why lein would complain at _everything_ (e.g. lein deps) that it is not a task?

16:22 amalloy: cs02rm0: lein self-install?

16:22 cs02rm0: amalloy: it complains that isn't a task too

16:23 amalloy: clojurebot: lein?

16:23 clojurebot: lein is http://github.com/technomancy/leiningen

16:23 pppaul: i was inputting wrong data, i changed it and debugging now...

16:23 amalloy: cs02rm0: you could get a fresh copy of lein from https://github.com/technomancy/leiningen/raw/master/bin/lein and see if that helps

16:23 raek: cs02rm0: did it work before, or is this after a fresh install?

16:24 technomancy: cs02rm0: there's a bug in 1.3 where it would say that if you ran tasks that required a project.clj in a directory without one.

16:24 cs02rm0: raek: fresh. OSX.

16:24 technomancy: this is 1.2.0

16:24 amalloy: cs02rm0: fresh from where? last i heard the macports version of lein wasn't very good

16:25 cs02rm0: amalloy: ports. i'll give it a go from github. thanks

16:27 technomancy: cs02rm0: that bug may be present there too

16:29 romain_p: Hi everyone, http://clojure.pastebin.com/D4AjBJ80

16:29 how do I make this function return an empty vector if the input is an empty seq?

16:29 hsuh: shouldn't you be using map ?

16:30 amalloy: hsuh: i would, but for is fine too

16:30 hsuh: fun, wasnt aware of its existence

16:31 amalloy: &(let [x #{}] (if (seq x) [] (conj x 10)))

16:31 sexpbot: ⟹ #{10}

16:31 amalloy: &(let [x #{}] (if-not (seq x) [] (conj x 10)))

16:31 sexpbot: ⟹ []

16:31 amalloy: romain_p: this what you want?

16:32 romain_p: amalloy: probably, thanks

16:34 cs02rm0: superb - the github version of lein seems to work flawlessly, many thanks.

16:36 amalloy: cs02rm0: enjoy

16:36 technomancy: just pinging you for ^^

16:37 technomancy: great!

16:38 kotarak: ,(or (seq nil) [])

16:38 clojurebot: []

16:39 jccc: how do i best accomplish something like (insert [1 2 3] 0 4) -> [1 4 2 3]

16:40 kotarak: jccc by using finger trees maybe. vectors are not designed for such things.

16:40 jccc: yeah i was hoping not to have to pull in contrib

16:41 kotarak: jccc: if you need to: (defn insert [vektor idx value] (into (subvec vektor 0 idx) [value] (subvec vektor idx))) or something like that

16:43 jccc: kotarak: yeah i was thinking i would have to do something like that. guess ill try to figure out finger trees. thnx

16:49 raek: instead of _insterting_ elements at the right places, would i be possible to make a function that _selects_ the elements in the right order and returns them as a sequence?

16:50 jccc: ^

16:50 kotarak: raek: (concat (subvec v 0 idx) [value] (subvec v idx))

16:50 But you loose random access.

16:52 raek: I was thinking about something like the difference between insertion sort and selection sort

16:52 pppaul: woot! got my recursive infix function working

16:57 raek: ...since instertion into the middle is costly, but making lazy sequences is cheap

16:57 jccc: raek/kotarak: i think just vectorizing kotaraks solution is fine for now. not sure of its performance

16:57 rata_: hi all

16:57 hsuh: KirinDave: i'm trying to understand how clothesline/webmachine differ from ring in how you have to write your services

16:58 kotarak: jcc: O(N) in vector length

16:58 jccc: kotarak: yeah where like assoc on a vector is O(1)

16:59 kotarak: jccc: yes, but assoc != insertion

16:59 honestly it's O(log_32 N)

17:00 jccc: kot: no i know. i wish it could though :). oh true

17:00 LauJensen: kotarak: enough chatting, start blogging :)

17:00 kotarak: LauJensen: argh.

17:00 * kotarak hides.

17:00 kotarak: ;)

17:01 LauJensen: currently mulling about a C program.

17:13 kzar: How would I do something like this?

17:13 &(map + [[1 2 3] [1 2 3]])

17:13 sexpbot: java.lang.ClassCastException: Cannot cast clojure.lang.PersistentVector to java.lang.Number

17:13 amalloy: &(apply map + [[1 2 3] [1 2 3]])

17:13 sexpbot: ⟹ (2 4 6)

17:14 kzar: amalloy: How come map gets evaled there?

17:14 amalloy: &(doc apply)

17:14 sexpbot: ⟹ "([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."

17:15 amalloy: kzar: so it turns into (map + [1 2 3] [1 2 3])

17:15 kzar: &(apply map + - * / [[1 2 3] [1 2 3]])

17:15 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$_

17:15 amalloy: &(apply map (juxt + - * /) [[1 2 3] [1 2 3]])

17:15 sexpbot: ⟹ ([2 0 1 1] [4 0 4 1] [6 0 9 1])

17:16 kzar: amalloy: I don't really understand how you can have one extra function but not two?

17:16 amalloy: kzar: you don't have any extra functions

17:16 apply is a way to tell clojure that the last argument should not be treated as a single list-argument, but rather expanded, and each element treated as its own argument

17:17 so apply mucks around with the last argument, then gets out of the way and calls map

17:17 kzar: amalloy: OK so (apply map + [[1 2] [1 2]]) only expands the last argument so it's something like (apply map + [1 2] [1 2]) which is then something like (map + [1 2] [1 2])?

17:18 amalloy: yep. i said that, in fact, with my "so it turns into..."

17:19 kzar: amalloy: yea thanks, I got that it worked but I didn't understand the process

17:19 amalloy: so my dodgy example would be (map + - * / [1 2 3] [1 2 3]) which ovbiously isn't going to work

17:19 amalloy: exactly

17:19 kzar: sweet I understand :)

17:20 amalloy: but you can get results basically like that by wrapping + - * / all into a single function, like i did with juxt

17:20 kzar: amalloy: Yea I get you

17:21 to start with I thought it was some special case or something

17:22 KirinDave: hsuh: I don't understand

17:22 hsuh: Clothesline uses ring.

17:22 amalloy: KirinDave: i think he's asking what clothesline does for him that ring doesn't

17:22 KirinDave: Oh

17:22 hsuh: It provides (or, it will provide) correct http 1.1 behavior by default.

17:23 hsuh: KirinDave: yep, kinda.. because from what it seems to me now, using ring, because you get the http request as a map, you can do anything with it easily..

17:23 KirinDave: hsuh: Well, you won't be altering the request.

17:23 hsuh: WebMachine's benefit is not in golfing low code count on a simple http service.

17:24 hsuh: It's more about providing a very clean way to link your code with a http handler and not have to worry about crazy edge cases in protocol.

17:24 You get correct behavior by default.

17:24 It also lets you do things like handle incoming content types much more easily.

17:25 ohpauleez: KirinDave: re: "...but none of them are specifically oriented towards designing APIs with correct HTTP 1.1 behavior"

17:25 KirinDave: ohpauleez: Did I miss one>

17:25 ohpauleez: In the past I have found Moustache to fill this spot for me, quite well

17:25 KirinDave: I know of coda's jersey for Scala...

17:25 technomancy: it does begs the question why not just fix ring...

17:26 ohpauleez: or enhancing Ring

17:26 hiredman: technomancy: or at least implement as a wrapper for ring

17:26 KirinDave: Right now it produced handler functions that are suitable for use with ring.

17:26 There are some produce-sever functions for convenience there, but they all just use ring.

17:26 hiredman: well then

17:27 KirinDave: I mean, Ring is plenty good at what it does. It's like Rack. Putting tools for making restful APIs into Ring seems outside the scope of that project. The same argument would work against compojure (w.r.t serving generated content).

17:28 hsuh: Does that answer the question?

17:29 hsuh: KirinDave: oh yeah, i'll keep an eye as well :) sooner or later someone will use it for something neat and mind will be blown.. or something

17:30 KirinDave: Maybe.

17:32 ohpauleez: You know, I have been considering making some mustache-like syntax for generating clothesline handlers.

17:32 ohpauleez: Currently Clothesline is awkward.

17:32 ohpauleez: KirinDave: I've been doing the same for some stuff I'm working on in Aleph

17:32 KirinDave: It'd be nice to get a familiar and helpful layer on top for actually delivering things.

17:32 ohpauleez: I find it extremely powerful and elegant

17:33 KirinDave: Could I see a snippet of moustache code for doing some restful stuff?

17:35 ohpauleez: Do you have a git project I could peer at?

17:36 ohpauleez: Currently none of that is sitting in git, but when I hurray up and finish net-ns, it'll be in there

17:36 let me link you

17:37 KirinDave: https://github.com/ohpauleez/net-ns A whole lot of nothing but scratches right now.

17:37 KirinDave: I'm curious how you'd do things like handle http headers properly

17:37 e.g., if-modified-since

17:37 (Not that clothesline does that just yet)

17:43 nickik: does anybody know why form-dot-clj isn't working on the appengine?

18:09 pppaul: someone want to help me with a regex problem?

18:11 amalloy: pppaul: don't use regexes? :)

18:11 pppaul: but they are sexy

18:11 amalloy: clojurebot: ask?

18:11 clojurebot: Gabh mo leithscéal?

18:11 amalloy: clojurebot: anyone?

18:11 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:11 pppaul: ^(?:\d[\\+])+\d$ what does the '$' mean?

18:11 amalloy: clojurebot: regex?

18:11 clojurebot: Sometimes people have a problem, and decide to solve it with regular expressions. Now they have two problems.

18:11 amalloy: bah

18:11 anyway pppaul it means only match at end of input

18:11 replaca: pppaul: you said that the other night. I think you need to go review "sexy" as a concept :)

18:12 pppaul: regex is kinky

18:12 amalloy: pppaul: are you trying to match either a \ or a +? that's kinda a weird thing to want

18:12 replaca: pppaul: in the sense that you might get all tangled up and not be able to get out, yeah

18:12 pppaul: ^_^

18:12 amalloy: replaca: haha awesome

18:13 pppaul: i want to match "1+2+3+4" and not "12+2+3+4"...

18:13 amalloy: you want...only single digits?

18:13 pppaul: it is weird, but it's for the 24 game, so it's got to be that way

18:13 amalloy: ah

18:14 [\\+] is not what you want. \+ is fine, and so is [+], but what you have will match 1\2\3+4

18:14 pppaul: my tests pass with \\+. i'll try with \+

18:15 amalloy: yes, it matches everything you want, and also some things you don't want

18:15 is my point

18:15 replaca: pppaul: you don't need any \ there. inside the [] you don't need to escape +

18:16 amalloy: &(re-find #"^(?:\d[\\+])+\d$" 1\2\3\4)

18:16 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (5) passed to: core$re-find

18:16 amalloy: &(re-find #"^(?:\d[\\+])+\d$" "1\2\3\4")

18:16 sexpbot: ⟹ nil

18:16 pppaul: ok, i'll try not escaping...

18:16 amalloy: pppaul: don't "try" it; it's guaranteed to work :P

18:17 replaca: pppaul: *either* escape or [] will work, both doesn't really make sense

18:17 pppaul: java.util.regex.PatternSyntaxException: Illegal character range near index 10

18:17 ^(?:\d[+-\*])+\d$

18:17 ^

18:17 java.lang.Exception: Unable to resolve symbol: string in this context (NO_SOURCE_FILE:0)

18:17 java.lang.Exception: Unmatched delimiter: )

18:17 java.lang.Exception: Unmatched delimiter: ]

18:17 user=> java.lang.Exception: Unable to resolve symbol: match in this context (NO_SOURCE_FILE:683)

18:17 java.lang.Exception: Unmatched delimiter: )

18:17 java.lang.Exception: Unmatched delimiter: )

18:17 didn't work

18:17 amalloy: pppaul: don't escape * either!

18:17 inside []

18:17 pppaul: i wasn't

18:17 i want to capture it

18:17 replaca: what's this for: \

18:18 ?

18:18 amalloy: \ != /

18:18 pppaul: ^(?:\d[+-/*])+\d$ works

18:18 replaca: amalloy: I think you made a new emoticon

18:18 amalloy: hahaha

18:18 joegallo: Ah, \ != /, I'm pretty sure that's an operator in perl.

18:18 replaca: joegallo: most things are

18:18 amalloy: my secret identity is Angry Regex Man

18:18 pppaul: lol

18:19 love regex

18:19 regex grows hair on my chest

18:19 amalloy: or maybe "I'm so excited by operators!"

18:37 anyone have experience with somnium.congomongo? i'm trying to store a tree/nested-map like {:word "doctor" {:links {"phil" 1}}} {:word "phil" {:links {...}}}

18:37 but it coerces all the map keys to keywords, and all the map values to strings. i'd be totally fine with only strings or only keywords, but i'm having some serious trouble getting either

18:38 (because if i look up "doctor"s links i see that the key is :phil, not "phil", and so the map manipulation i do in clojure doesn't work too great)

18:50 Raynes: amalloy: Hahaha a nap.

18:52 amalloy: ish

18:55 Raynes: scottj: Huh?

18:55 scottj: I used it in SLIME, and almost all of my development was in a cake REPL. I don't understand.

18:57 * Raynes tries it again.

18:59 Raynes: Oh shit. You're right. How weird.

19:03 gertalot: hey all. I need to write a function that given a vector [a b c d] returns a vector [a a+b a+b+c a+b+c+d]. How would I do that?

19:04 amalloy: &(reductions + [1 2 3 4])

19:04 sexpbot: ⟹ (1 3 6 10)

19:04 gertalot: ah!

19:04 i love clojure :)

19:04 thx

19:04 amalloy: welcome gertalot

19:05 pppaul: (inc gertalot)

19:05 sexpbot: ⟹ 1

19:10 pppaul: commenting in emacs is messed up

19:11 amalloy: ...blaming emacs for your problems tends to end with "gosh, i see now why the way it works is better than what i expected"

19:12 pppaul: i dono

19:12 i'm putting in comments, and emacs is doing it's own thing

19:12 then i try to format the comments and my code suddenly ends up in the middle of sentences i wrote in my comments

19:14 technomancy: pppaul: are you using M-;?

19:15 pppaul: i'm not sure

19:15 i'm using ;

19:15 let me try the meta key

19:15 * technomancy suspects amalloy is correct

19:16 pppaul: so, how do i change the setting where it word-wraps?

19:16 amalloy: M-x autofill-mode to toggle it entirely, C-x f to change the width

19:16 pppaul: doesn't C-x f open a new file?

19:17 amalloy: no, that's C-x C-f

19:17 pppaul: my emacs settings are diff

19:17 C-x f does file stuff

19:18 oh well

19:18 Raynes: technomancy: ping

19:19 technomancy: What is SLIME's 'eval thread' and how can one kill it with Clojure code? It appears that I'm doing just that, and I have absolutely no clue how. In any case, when my code runs, C-x C-e and the like don't work any longer.

19:21 amalloy: Raynes: is it possible that starting the java security manager kills some daemon threads?

19:21 ie, i bet it's swank, not slime

19:21 technomancy: I'm not sure how to do it from clojure. you can try M-x slime-list-threads

19:21 Raynes: It never did this from clj-sandbox, so it has to be something specific to my code.

19:23 https://github.com/Raynes/clojail/blob/master/src/clojail/core.clj#L65 Is the relevant function if anyone has any epiphanies.

19:23 * Raynes doesn't even know where to start on this one.

19:25 amalloy: Raynes: it happens when all you do is call (sandbox ...)?

19:25 Raynes: I believe so. Not sure if it happens then or when you call what sandbox creates.

19:25 I'll test.

19:25 amalloy: if the former then it *has* to be the security manager, since that's the only code that actually executes

19:26 Raynes: It's the former then.

19:27 defn: Hey Raynes -- what's this new project I heard about on twitter?

19:27 Raynes: amalloy: Removing that code doesn't do anything to fix this.

19:27 amalloy: hm

19:27 Raynes: defn: This one. My awesome new sandbox problem that doesn't work properly in SLIME.

19:28 Great introduction, eh?

19:28 project*

19:28 amalloy: Maybe it happens when I use, let's try that.

19:29 amalloy: hey technomancy: C-c M-p doesn't work if the ns form has ^{metadata}

19:30 Raynes: It actually appear SLIME isn't working properly for me at all, even fresh.

19:30 ...

19:31 amalloy: Can you clone clojail and try this out yourself, pretty please?

19:31 amalloy: Raynes: just did

19:31 in the slime repl, i evaluated (sandbox secure-tester)

19:31 C-x C-e still works fine

19:31 defn: Raynes: How is this different from yours and Licenser's sandbox?

19:31 Raynes: Yeah, I guess my SLIME is just all of a sudden broken.

19:31 technomancy: amalloy: true. IMO ns metadata is not a good idea, but I would take a patch to fix slime.

19:32 amalloy: Raynes: and now i've called the resulting sandbox: (s '1), and C-x C-e still works

19:32 Raynes: defn: Mine is arguably a bit cleaner, and it's simpler. Most of all, it's documented and not monolithic.

19:32 amalloy: defn: he's reimplementing it but in a less bad way

19:33 * amalloy doesn't have to be as diplomatic since he doesn't know Licenser

19:33 defn: :D

19:33 Raynes: defn: I'm trying to take clj-sandbox and just reimplement it in a more sane way.

19:33 defn: Cool.

19:33 Raynes: amalloy: I'm going to nix Emacs and restart it.

19:34 defn: I'd love to see a sandbox that is like Licenser's, but runs in an honest-to-god VM

19:34 so you can be liberal about running everything under the sun

19:34 amalloy: Raynes: sounds good. really everything slime is working for me still: C-c C-m and friends work fine

19:34 defn: side effects and all

19:35 amalloy: defn: if you have a few GB of ram to host some VMs on we're accepting donations

19:35 Raynes: Yep, it's all working great now.

19:35 I don't know what happened with scottj.

19:36 I found a bug though.

19:36 * Raynes fixes it.

19:38 amalloy: hah, what was it?

19:46 hsuh: can someone give me an insight on how to go from [["a" "b"] [1 2]] to [["a" 1] ["b" 2]] ? trivial in imperative way, but cant see it in clojure

19:46 amalloy: &(apply map vector [["a" "b"] [1 2]])

19:46 sexpbot: ⟹ (["a" 1] ["b" 2])

19:46 amalloy: even more trivial in clojure :)

19:48 hsuh: the apply converts it to (map vector [...]), which is effectively [(vector "a" 1) (vector "b" 2)]

20:04 hsuh: amalloy: that code is puzzling me a little bit because map accepts more than one collection

20:04 &(map vector ["a" "b"] [1 2])

20:04 sexpbot: ⟹ (["a" 1] ["b" 2])

20:04 hsuh: but if that works, why isnt this allowed?

20:04 &(map (fn [x] (* x 2)) [1 2 3] [4 5 6])

20:04 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (2) passed to: sandbox4138$eval6573$fn

20:04 amalloy: &(map (fn [x y] (* x y)) [1 2 3] [4 5 6])

20:04 sexpbot: ⟹ (4 10 18)

20:05 hsuh: oh, its like clojure doesnt need map2

20:05 amalloy: &(doc map)

20:05 sexpbot: ⟹ "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls ... http://gist.github.com/670171

20:06 amalloy: i don't know what map2 is, but no, we don't need it :P

20:06 &(apply map + (replicate 100 (range 10)))

20:06 sexpbot: ⟹ (0 100 200 300 400 500 600 700 800 900)

20:06 amalloy: look, a map100 :)

20:07 hsuh: i think map2 memory came from ocaml, which probably explains its need to exist

20:07 amalloy: thanks a lot

20:21 livingston: how do I type hint for a non-primitive array? e.g. I want to hit this method: [ 3] add : void (Iterable,Resource[])

20:22 amalloy: livingston: ISTR it's ^LResource or something close to that

20:23 java has weird classnames for arrays

20:23 livingston: i'll give that a shot, thanks

20:23 amalloy: livingston: &|(make-array Object 0)|&

20:23 sexpbot: ⟹ #<Object[] [Ljava.lang.Object;@b62f6>

20:24 amalloy: the [Ljava.lang.Object is the array's official classname

20:24 so you probably have to do like ^{:tag "[Ljava.lang.Object"}

20:24 anyway i'm off. good luck

20:25 livingston: amalloy: that will give me an empty array right? that's cool, that's what I happen to want (this time)

20:25 thanks

20:25 amalloy: yes it will

20:25 livingston: looks like that worked

20:33 pppaul: (ns rosettacode.24game

20:33 (:require '[clojure.string :as str]))

20:33 rosettacode.24game=> (str/capitalize "12312312")

20:33 java.lang.Exception: No such namespace: str (NO_SOURCE_FILE:83)

20:33 :(

20:34 what am i doing wrong?

20:34 ^_^

20:34 technomancy: pppaul: no need to quote require clauses inside the ns form

20:35 pppaul: ok, i copied it off of the clojure API

20:35 technomancy: I find that ... unlikely?

20:35 but if there's a typo in the official docs it should get fixed

20:35 pppaul: It is poor form to (:use clojure.string). Instead, use require

20:35 with :as to specify a prefix, e.g.

20:35 (ns your.namespace.here

20:35 (:require '[clojure.string :as str]))

20:36 works now, thanks :)

20:36 should get the official docs edited

20:36 technomancy: eep; do you have a URL for that?

20:37 pppaul: http://clojure.github.com/clojure/clojure.string-api.html

20:37 technomancy: ok, good catch. sorry I doubted you. =\

20:37 pppaul: ^_^

20:38 replaca: That whole comment doesn't even really belong there

20:38 I think it was Stuart reacting to the old (googlecode) autodoc for contrib which had use in it

20:41 pppaul: i use :use for clojure.test... is that bad?

20:41 does it make sense at all?

20:42 technomancy: I think that's acceptable

20:42 pppaul: why is :use in the language?

20:42 technomancy: nothing wrong with :use if you also have :only to limit the scope of what you bring in

20:42 it's a design bug that leaving out :only brings in everything

20:42 pppaul: i need a tutorial on ns stuff :(

20:42 Derander: can you :require :as?

20:43 technomancy: it's slated for fixing; everyone agrees it is needlessly complex

20:43 pppaul: the best thing to do is read existing code

20:43 pppaul: i find it really tricky (been having lots of problems getting my stuff to work using (ns :require) form

20:43 Derander: yes, the whole use/require/import stuff is one of my biggest sticking points as a newbie

20:43 I'm still cargo-culting it

20:44 pppaul: i use clojuredocs, but the examples for ns stuff seem a bit weak

20:44 Derander: yes

20:44 same problem

20:47 replaca: Derander: yes, you can :require :as

20:47 pppaul: ?

20:48 ns rosettacode.24game

20:48 (:require [clojure.string :as str])

20:48 (:use (clojure.test))) rosettacode.24game=> java.lang.Exception: Unable to resolve symbol: deftest in this context (NO_SOURCE_FILE:158)

20:49 so, i use :use, but deftest still isn't defined

20:50 but, i created the ns before, and then tried to fix it by adding :use

20:50 are namespaces allowed to change? or are they immutable?

20:51 tomoj: (:use clojure.test)

20:51 not (:use (clojure.test))

20:51 amalloy: pppaul: tomoj is right

20:52 symbols, vectors, and lists all behave differently in a :use entry

20:52 tomoj: vectors and list are the same, aren't they?

20:52 pppaul: from (doc ns) (ns foo.bar

20:52 (:refer-clojure :exclude [ancestors printf])

20:52 (:require (clojure.contrib sql sql.tests))

20:52 (:use (my.lib this that))

20:52 (:import (java.util Date Timer Random)

20:52 (java.sql Connection Statement)))

20:52 tomoj: I mean, they're seqs

20:52 (my.lib this that) means both my.lib.this and my.lib.that

20:52 amalloy: &(map class () [])

20:52 sexpbot: ⟹ ()

20:53 technomancy: ugh; that's awful. one more thing to be fixed in CLJ-272 I guess.

20:53 amalloy: ,(map class () [])

20:53 clojurebot: ()

20:53 amalloy: oh hah

20:53 &(map class [() []])

20:53 sexpbot: ⟹ (clojure.lang.PersistentList$EmptyList clojure.lang.PersistentVector)

20:53 pppaul: wooo

20:53 amalloy: tomoj: maybe you're right. namespaces still confuse me :P

20:54 &(macroexpand (ns foo (:require [clojure.contrib math] (clojure.contrib math))))

20:54 sexpbot: java.io.FileNotFoundException: Could not locate clojure/contrib/math__init.class or clojure/contrib/math.clj on classpath:

20:54 amalloy: &(macroexpand '(ns foo (:require [clojure.contrib math] (clojure.contrib math))))

20:54 pppaul: works now :D

20:54 sexpbot: ⟹ (do (clojure.core/in-ns (quote foo)) ((fn* loading__4410__auto__ ([] (dot clojure.lang.Var (clojure.core/pushThreadBindings {clojure.lang.Compiler/LOADER (dot (dot loading__4410__auto__ getClass) getClassLoader)})) (try (clojure.core/refer (quote clojure.core)) (clojure.core/require (quote [clojure.... http://gist.github.com/670215

20:57 amalloy: tomoj: yeah, okay, [] and () are the same in ns. another of my delusions spoiled

20:57 pppaul: i would assume that [] gets converted to a seq

20:58 it would have to if any seq funcs were applied to it

20:58 amalloy: pppaul: true as far as it goes. but rich *could* check whether it's a vector or a list before doing anything to it, and then do different things depending. apparently he doesn't

20:59 pppaul: yeah... it looks like that is sorta being done, since (clojure.contrib is not an op

20:59 tomoj: a list is a list :)

20:59 pppaul: least i don't think it is

21:00 amalloy: tomoj: ?

21:00 pppaul: it's an unevaluated list, which is different from an evaluated one

21:00 tomoj: there doesn't need to be any special handling to avoid treating clojure.contrib as an op

21:00 it's just a list

21:01 pppaul: wouldn't the special handling be in the macro?

21:01 amalloy: pppaul: yes, but not necessarily in the expansion

21:01 tomoj: no need for special handling in the macro either

21:01 the macro just receives a list and can process it like a seq

21:01 pppaul: the macro doesn't say to not evaluate the list?

21:02 amalloy: tomoj: i know. (i think) we're discussing the hypothetical situation where rich wants to treat lists and vecs differently

21:02 tomoj: yeah, hypothetical, not sorta being done

21:02 pppaul: anyway, it doesn't matter much... documentation matters more now :)

21:02 newbs in trouble

21:03 amalloy: (defmacro is-list? [var] (if (list? var) () [])

21:03 (is-list? [1 2 3]) ; expands to [] with no trace of the list/vec check

22:33 tomoj: &(keys [1 2 3])

22:33 sexpbot: java.lang.ClassCastException

22:33 tomoj: try that in a plain repl

22:34 oh, nevermind

22:34 I was trying to figure out why it prints a single '(', but that's seqiness

22:34 for some reason, though, (keys [1 2 3]) causes slime to error

22:34 something strange about the exception I guess?

22:45 amalloy: tomoj: keys is lazy

22:45 &(let [x (keys [1 2 3])] 1)

22:45 sexpbot: ⟹ 1

22:46 Raynes: ,(.replace (.replace "x" "x" "y") "y" "x" "x")

22:46 clojurebot: java.lang.IllegalArgumentException: No matching method found: replace for class java.lang.String

22:46 amalloy: so (keys [1 2 3]) completes without error, and then when the repl tries to show it to you the exception finally comes up

22:46 tomoj: right

22:46 * Raynes smiles.

22:46 amalloy: Raynes: ?

22:47 Raynes: Too many arguments.

22:47 Weird error message.

Logging service provided by n01se.net