#clojure log - Mar 28 2011

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

0:01 joshua__: findfn \a "a"

0:01 brehaut: char

0:01 joshua__: &findfn \a "a"

0:01 sexpbot: java.lang.Exception: Unable to resolve symbol: findfn in this context

0:01 brehaut: str

0:01 joshua__: brehaut, it has to work for both \a and `(\a \b \c) etc

0:01 I was using (reduce str letters)

0:01 brehaut: apply works ?

0:02 joshua__: .. probably.. one second testing it ;p

0:02 brehaut, thank you.

0:03 brehaut, I didn't know that findfn worked as well as it does o.o

0:03 brehaut: $findfn \a "a"

0:03 sexpbot: [clojure.string/trim clojure.string/lower-case clojure.core/munge clojure.core/print-str clojure.core/str clojure.core/namespace-munge clojure.contrib.string/as-str]

0:03 joshua__: brehaut, I meant you ;p

0:03 brehaut: amalloy (apply (fn [s a] ((a 599) (fn [& r] ((a 599) ((a 477) r) ((a 606) r))) (((a 599) (a 681) ((a 297) (fn [length] ((a 440) (a 68) #((a 441) % length))) [20 12])) ((a 356) ((a 440) ((a 438) ((a 245) (((a 440) (a 567) (a 205)) ((a 640) ((a 706) ((a 640) ((a 465) (a 164) ((a 297) ((a 440) ((a 560) (a 599) (a 472)) ((a 560) (a 297) (a 567))) '((77 97 116 104) (112 111 119))))) 2 6)) 1))) (a 186) (a 374) (a ((a 180) 123 342 12))) s)))) (((

0:03 (a 503) ((a 440) ((a 560) (a 392) {}) (partial map-indexed (fn [n [_ v]] [n v])))) (seq (ns-map (the-ns 'clojure.core)))))

0:03 perfected

0:05 amalloy: quick, someone saw brehaut's broadband connection in half. it's time for an intervention

0:05 joshua__: What are we trying to do?

0:05 Hide false?

0:05 brehaut: joshua__: obfuscate false

0:06 joshua__: (def true false) ?

0:06 brehaut: the down side is i think it only works in clj 1.2.0

0:07 i dont think true and false are symbols, so they probably cant be rebound

0:07 amalloy: &(let [true 1] true)

0:07 sexpbot: java.lang.Exception: Unsupported binding form: true

0:12 brehaut: the heart of that big old blob is ##(seq? neg?) (or similar)

0:12 sexpbot: ⟹ false

0:21 johnmn3: is there a simple tutorial on how to build an accumulator function?

0:21 I keep overflowing the stack

0:21 tomoj: amalloy: filthy habit?

0:22 amalloy: tomoj: poorly stated, sorry. i meant: if you do that you'll often be confused

0:22 tomoj: ah, yes

0:22 it was just so nice to find an explanation for the abomination

0:23 amalloy: &((fn ! [n acc] (if (zero? n) acc (recur (dec n) (* acc n)))) 5 1)

0:23 sexpbot: ⟹ 120

0:23 johnmn3: Basically, I want to un-interleave a collection, like: [0 1 0 1 1 0 0 1] -> [[0 0 1 0] [1 1 0 1]]

0:24 amalloy: johnmn3: ^ is obviously not a tutorial, but maybe helpful. look at it, let me know what parts didn't "stick", maybe?

0:24 johnmn3: ok

0:24 tomoj: how do you get from "un-interleave" to "accumulator function"?

0:24 johnmn3: I was calling the defining function

0:25 amalloy: tomoj: when i was learning CL, i thought tail-recursion was the only way to do anything interesting; he's probably similar

0:25 brehaut: amalloy: and then you learnt about the point free trifecta?

0:25 amalloy: brehaut: comp, partial, and...apply?

0:26 brehaut: juxt!

0:26 amalloy: damn. second guess

0:26 juxt is just a special case of map

0:26 brehaut: (juxt (partial take-nth 2) (comp (partial take-nth 2) (partial drop 1)))

0:26 maps just a special case of reduce but its still useful to call it map :P

0:26 tomoj: reduce?

0:27 amalloy: tomoj: sure

0:27 tomoj: I could maybe imagine definining maps in terms of reductions

0:27 .. map

0:27 brehaut: map the function, not map the structure sorry

0:27 tomoj: indeed

0:28 amalloy: tomoj: clojure's reduce isn't lazy so it's harder, but i imagine in haskell it's not hard to define map in terms of reduce

0:28 pdk: and then you'd have...

0:29 a mapreduce

0:29 tomoj: ah, that was my confusion

0:29 ba dum ching

0:29 brehaut: yeah it helps to have left and right folds as well as lazy and strict ones

0:30 johnmn3: you hung my repl :|

0:31 amalloy: johnmn3: i did?

0:31 johnmn3: just kidding :) I just did it wrong or something

0:31 amalloy: *chuckle*

0:31 brehaut: tomoj: assuming a appropriate folds in place of reduce: ##((fn [f s] (reduce (fn [l v] (conj l (f v))) [] s)) inc [1 2 3])

0:31 sexpbot: ⟹ [2 3 4]

0:32 johnmn3: (defn unzip [asq acum bcum]

0:32 (if (nil? asq) [acum bcum] (recur (rest (rest asq)) (conj acum x) (conj bcum y)))))

0:32 shouldn't that reach a nil?

0:32 amalloy: no

0:33 rest is lazy, and an empty seq isn't false

0:33 &((juxt rest next) [1])

0:33 sexpbot: ⟹ [() nil]

0:33 brehaut: tomoj: of course in haskell its probably not implemented in terms of a fold because its heavily optimized and the rewrite rules perform a lot of fusion on folds and maps

0:34 johnmn3: an empty seq doesn't return nil?

0:34 amalloy: johnmn3: see abone

0:34 above

0:35 johnmn3: what does juxt do again?

0:35 amalloy: (next [1]) is nil because it's (seq (rest [1])), but (rest [1]) is a lazy seq that's not sure if it's empty yet

0:35 tomoj: the funny thing to me is that rest appears to be implemented using next

0:35

0:35 amalloy: tomoj: i think it uses RT.next?

0:36 $source rest

0:36 sexpbot: rest is http://is.gd/kSLdsP

0:36 johnmn3: so I just need to add a seq

0:36 tomoj: yeah, not next the function

0:36 every time I see "rest" I think "that should be 'next'"

0:36 amalloy: johnmn3: or just use next to begine with

0:37 tomoj: I imagine that there is some reason for rest to still be around but I have never found one

0:37 amalloy: tomoj: there are like a hundred. i rarely use next

0:37 tomoj: oh, laziness stuff?

0:38 amalloy: yes

0:39 johnmn3: man 1, computer 0

0:39 thats a lie

0:44 tomoj: but if rest is implemented with next, how can it be more lazy?

0:44 johnmn3: https://gist.github.com/890019

0:44 tomoj: I guess the piece of next that it uses is lazy and next does something extra

0:45 johnmn3: maybe the bot should post summaries of gists that are posted

0:46 amalloy: johnmn3: i'd try to implement it with keep-indexed

0:47 &(keep-indexed (fn [idx val] (when (even? idx) val))) [0 1 0 1 0 1])

0:47 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$keep-indexed

0:48 amalloy: &(keep-indexed (fn [idx val] (when (even? idx) val)) [0 1 0 1 0 1])

0:48 sexpbot: ⟹ (0 0 0)

0:48 amalloy: do that for even? and odd? and you're all set

0:48 tomoj: why that over take-nth?

0:48 amalloy: tomoj: no particular reason

0:48 i guess take-nth is better

0:48 but now he's learned about *two* useful functions :)

0:49 johnmn3: so take-nth on the even and odd ranges?

0:49 brehaut: ,(take-nth 2 [1 2 3 4 5 6])

0:49 clojurebot: (1 3 5)

0:49 brehaut: ,(take-nth 2 (rest [1 2 3 4 5 6]))

0:49 johnmn3: oh, I was thinking of nth

0:49 clojurebot: (2 4 6)

0:50 dr0id: hmm

0:52 johnmn3: (defn uninterleave [asq]

0:52 [(take-nth 2 asq) (take-nth 2 (rest asq))])

0:52 better

0:53 amalloy: (map (partial take-nth 2) ((juxt identity rest) asq))?

0:53 as sorta an alternative way of looking at it

0:56 johnmn3: oh I see

0:56 so juxt will let you create two colls out of one, among other things

0:56 amalloy: johnmn3: it calls two functions on the same arms

0:56 args

0:57 &((juxt inc dec) 1)

0:57 sexpbot: ⟹ [2 0]

0:57 johnmn3: or more

0:57 amalloy: sure

0:57 johnmn3: &((juxt inc dec inc) 1)

0:57 sexpbot: ⟹ [2 0 2]

0:57 johnmn3: neat beats

1:01 amalloy: i especially love (juxt identity blah blah blah). get some information about the object, attached to the original object

1:12 mec: If I remove a function from a namespace after having run (use 'my-ns) how do I remove the binding?

1:13 From the repl namespace, without having to restart it*

1:14 no_mind: can I find logs for yesterday's discussion ? Someone replied to my question and at the same time my client crashed. I could not see the answer

1:15 amalloy: logs?

1:15 clojurebot: logs is http://clojure-log.n01se.net/

1:17 amalloy: mec: ns-unmap

1:17 or just (def myfn 0)

1:18 mec: That gives an IllegalStateException, fn already refers to my-ns/fn in namespace: user

1:18 but ns-unmap works, i was just using it wrong :D Thanks

1:19 amalloy: mec: yeah, that def probably has a lot of cases it won't work inn, now that i think about it

1:55 mec: ##(findfn '+ +)

1:55 sexpbot: java.lang.Exception: Unable to resolve symbol: findfn in this context

1:55 mec: ##(find-fn '+ +)

1:55 sexpbot: java.lang.Exception: Unable to resolve symbol: find-fn in this context

1:55 amalloy: mec: it's $findfn, but it won't find you resolve, i suspect

1:55 $findfn '+ +

1:55 sexpbot: [clojure.core/time clojure.core/dosync clojure.core/with-loading-context clojure.core/doto]

1:56 mec: weird

1:56 amalloy: mec: resolve is unsafe in an eval context so sexpbot doesn't allow it

1:56 mec: ah i see

1:56 amalloy: eg, ((resolve 'eval) '(hack the computer))

1:57 $findfn '+ #'+

1:57 sexpbot: [clojure.core/defn- clojure.core/defn clojure.core/defmacro clojure.core/declare clojure.core/defmulti]

1:57 amalloy: haha defmulti. nice one sexpbot

2:04 mec: I think I broke clojure, (+ 1 2) is giving me a NPE

2:07 tomoj: haha

2:08 amalloy: mec: (resolve '+) yields...?

2:09 mec: was still giving clojure.core/+

2:09 but I've already killed and restarted the repl

2:09 i think it was from using findfn

2:10 amalloy: mec: you used findfn locally?

2:10 nice

2:10 mec: ya its really handy, use it all the time

4:21 thorwil: is there a convention regarding * at the end of function names?

4:25 raek: thorwil: sometimes it is used when you have a function and a macro that makes it "prettier"

4:27 thorwil: like with bound-fn: (bound-fn [x] (foo x)) expands to (bound-fn* (fn [x] (foo x)))

4:27 there are other conventions as well, e.g. future and future-call

4:30 from http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards : "Don't use a macro when a function can do the job. If a macro is important for ease-of-use, expose the function version as well. (Open question: should there be a naming convention here? A lot of places use "foo" and "foo*".)"

4:30 no_mind: in enlive we have a function for set-attr which takes an attribute and its value. How can I specify the attribute dynamically ? Using keyword function is throwing error

4:57 what is the significance of % ?

4:58 ejackson: its the value of the first argument passed to anonymous function created with #( ... )

4:58 ,(map #(+ % 2) [1 2 3 4 5 6])

4:58 clojurebot: (3 4 5 6 7 8)

5:01 no_mind: k

5:01 thorwil: no_mind: you mean in something like (en/set-attr :value title) switching out :value? i guess a function symbol in that place won't be evaluated (?)

5:03 no_mind: thorwil, I tried this (en/set-attr (keyword k) v) and I get this runtime error clojure.lang.Keyword cannot be cast to java.util.Map$Entry

5:09 thorwil: no_mind: looks like you can do (en/set-attr (foo) title)

5:10 and then (defn foo [] :value) with a body that makes sense

5:15 ephcon: is there an equivalent of (member ) in clojure?

5:23 no_mind: thorwil, no I do not want to hard code :value or :id , I want these to be passed as arguments

5:23 thorwil, I tried this (html/set-attr #([] (keyword (get value (first (keys value))))) (get value (first (keys value)))) but I get eh same runtime exception

5:26 thorwil: no_mind: where/how do you decide which keyword to use?

5:27 no_mind: btw you misread what i said

5:29 no_mind: thorwil, from a db and the "value" used above is a map with one key something like {:id "hello"}

5:33 thorwil: no_mind: either bind your key and value in a let, or use functions. putting all that stuff into set-attr from is only confusing

5:35 no_mind: if your db query delivers a map, shouldn't it just be (:id query-result) to get at your "hello"?

5:35 no_mind: thorwil, any example of using let ? Say I pass a map {:id "map"} and want to set the id attribute to "map"

5:36 thorwil, I am not aware of the db query part. I am calling a function which returns me a map. That function is written by third party

5:39 thorwil: no_mind: (let [value (:id your-map)] ...code-goes-here...)

5:39 no_mind: k

5:40 thorwil, but what is the cause of the runtime exception ? from what I understand, set-attr takes a keyword as first arg

5:42 thorwil: no_mind: it does. but do you know what (keyword (get value (first (keys value))))) delivers? to me, it just looks wrong

5:42 no_mind: thorwil, it delivers clojure.lang.keyword

5:43 thorwil: no_mind: i'm pretty sure it's much more convoluted than it has to be

5:44 no_mind: how about you paste your stuff https://gist.github.com/

5:44 no_mind: thorwil, ok, I will post the version where I am sending a hardcoded map

5:46 thorwil, I have pasted it here http://pastebin.com/uGqRK91t (with hardcoded map that is similar to the result I am receiving)

5:56 thorwil: no_mind: what is [[:input]] supposed to do? (why double []?)

5:57 no_mind: thorwil, that is how I have always specified the elements. Saw it in one of the examples. It works fine else here

5:57 where*

5:59 thorwil: bad or misunderstood example, then. single like with [:div#content] works

6:01 no_mind: hows input-element defined

6:01 no_mind: thorwil, it returns a string with html input element.

6:02 thorwil, the code works fine if I use hard-coded attribute i.e (en/set-attr :id "h") works and generates the required element

6:03 thorwil: no_mind: what's the [value] after [[:input]]?

6:03 ugh, real life calling, be back in half an hour

6:03 no_mind: k

6:03 thorwil, ping me when you are back

6:28 thorwil: ping no_mind

6:29 no_mind: thorwil, pong

6:38 thorwil, any success ?

6:39 thorwil: no_mind: i still wonder about [[:input]] [value]

6:40 no_mind: hmm these are standard parts of defsnippet definition

6:43 thorwil: d'oh, just the formatting had thrown me off

6:48 * thorwil tries some destructuring in repl

7:21 thorwil: no_mind: try http://pastebin.com/MvBjZHLk

7:22 is there a way to destructure {:id "value"}, where :id could be any other key? that is, just match {key value}?

7:23 Chousuke: hm

7:24 ,(let [[k v] (seq {:key 'val})] [k v])

7:24 clojurebot: [[:key val] nil]

7:24 Chousuke: oh, I guess you need another pair of brackets

7:25 ,(let [[& [k v]] (seq {:key 'val})] [k v])

7:25 clojurebot: [[:key val] nil]

7:25 Chousuke: ,(let [[[k v]] (seq {:key 'val})] [k v])

7:25 clojurebot: [:key val]

7:25 Chousuke: there we go

7:25 kinda tricky

7:25 thorwil: thanks. maybe i will even understand it in a few minutes :)

7:26 Chousuke: possibly the (seq ...) is unnecessary

7:26 thorwil: well

7:26 ,(seq {:key 'val})

7:26 clojurebot: ([:key val])

7:26 Chousuke: you're not destructuring the map, you're destructuring the seq it becomes

7:27 and the destructuring form is [[key val]] which matches the structure of the seq

7:28 thorwil: ic

7:30 that can't be translated to work in an fn signature, i guess?

7:33 solar_sea: Hi. I'm trying to learn clojure and I'm getting a behavior I'm unable to explain. http://pastebin.com/DQiSzNsH

7:34 Why am I getting "true" for the last expression?

7:36 hoeck: solar_sea: because the second a in "0abc" matches your regex

7:37 I mean the second character, not the second a

7:38 solar_sea: shame on me, I see

7:38 thorwil: no_mind:or http://pastebin.com/biY3Gshg

9:40 chouser: So much of my code is just wrapping objects in other objects.

9:41 I live inside the expression problem.

9:41 dnolen: chouser: wrapping Java objects in Clojure types/records?

9:42 kephale00: you might want to bring it up to the emacs analyst ; )

9:42 chouser: sure that, among others. At least I can use reify for those cases, making Java objects look like Clojure maps/vectors

9:42 Also, wrapping Clojure reference types in subclasses of (usually concrete) Java types, which requires gen-class or proxy

9:43 Raynes: http://stackoverflow.com/questions/5457066/use-of-clojure-macros-for-dsls/5457754#5457754 Yikes.

9:46 dnolen: chouser: I've been impressed by the perf of the JVM in the presence of wrapping.

9:48 chouser: dnolen: wait come back, I have more inane prattle to spew on this topic!

9:48 Oh well, I guess I'll have to invest my prattle elsewhere.

9:57 gfrlog: I was just forced to use a ModelFactory to create a ModelMaker that I could use to create a model

9:58 mec: kill it with fire

9:59 joly: Nuke it from orbit; it's the only way to be sure.

9:59 chouser: gfrlog: I know, right? But it's like 6 lines of Clojure. So much less pain than Java.

10:00 gfrlog: or were you doing it in Java?

10:00 gfrlog: chouser: yeah, I think I did it in three (clojure)

10:00 chouser: at least I didn't have to type out the type of each dang object

10:00 chouser: yep

10:01 gfrlog: I have to think that the only reason it wasn't called a ModelFactoryFactory was to preserve dignity

10:01 chouser: I've got two of these right here. Set a static field to be an instance of a Factory that has a method that returns an instance of a thing that provides a method with my custom behavior.

10:02 Raynes: Hehe, that fellow called me a "little coward" for downvoting his answer.

10:02 chouser: gfrlog: heh

10:02 gfrlog: chouser: so it wants you to pass in a function, eh?

10:02 chouser: Raynes: well, I disagree with his conculsions about macros, but I find appealing to "consensus" to be rather unappealing.

10:03 gfrlog: chouser: good pun.

10:04 chouser: gfrlog: Is it any wonder high-order functions are hard for Java programmers to grasp at first? These giant stacks of classes and instances, and we're just slinging them around all over the place.

10:04 Raynes: chouser: What do you mean? nickik and friends managed to point out some of the reasons pretty nicely. I didn't think I should reiterate.

10:04 pdk: i was picturing more

10:04 "but i thought we still had to make wrapper classes with 1 function in them and pass those"

10:05 i hated that shit when i started off learning swing

10:05 cause it was ton of boilerplate just for every litttle button event handler

10:05 Raynes: And I was under the impression that what the community advocated was generally the direction one should go.

10:05 pdk: what's this post, i havent been around

10:05 i think learning to use swing was where i started going way back when

10:05 "why can't i give it the name of the function directly?"

10:06 gfrlog: chouser: it's okay, Eclipse tells you if you did it right :)

10:06 you just keep pressing auto-complete key-combinations until you get the first syntactically correct expression.

10:06 Raynes: pdk: http://stackoverflow.com/questions/5457066/use-of-clojure-macros-for-dsls/5457754#5457754 Specifically, the comments related to this post in nickik's answer.

10:07 pdk: i thought people were saying to use macros on an as-needed basis

10:07 is that basically the crux of the debate

10:07 chouser: Raynes: I agree some good reasons were pointed out. Once I saw that cgrand's talk onthe subject had been linked, I didn't think I had anything else to cntribute to the conversation.

10:08 Raynes: chouser: I was mostly pointing that out because, inevitably, new people will end up reading that, and that's how you end up with confused programmers.

10:08 Not that it matters, as this guy is determined to get the last word in.

10:08 chouser: pdk: I think the disagreement is over whether, in a situation where either a macro or a function would suffice at the moment, if you default to using a macro are you more likely later be happy or sad about it.

10:09 In my experience, I'm more likely to be sad.

10:09 Then again I'm apparently now a LISPer that knows the cost of nothing.

10:12 Raynes: I'm fairly certain, now, that this guy is a troll. Alas, everybody should have probably ignored him. He was actually getting upvotes though, which scared me, so I acted quickly.

10:12 * jao thinks chouser is right (about sadness)

10:14 Raynes: This sort of thing annoys me in general though. People who ignore common community-accepted conventions just for the hell of it. That Miki fellow who wrote fs is strongly in favor of single-segment namespaces. When my persuasion could do no good, I created a joke version of his project with a comical README and those things that seemed wrong fixed. I'm happy to report that he found it funny as well though.

10:19 pdk: i recall reading a couple months ago this long giant article

10:19 the short of it was just it was your typcial fighting over lisp indentation and the author thought he was dropping a bombshell going "guys... why don't we use block indendation and put )'s each on their own line?!"

10:19 Raynes: I remember that.

10:20 That irked me.

10:20 pdk: hell now i wanna find it again

10:20 gfrlog: we hate him

10:20 pdk: did he write any other "choice" stuff like that

10:20 chouser: Someone is wrong on the internet. But we're working on it, making progress, and soon people will only be right.

10:20 mec: we could always switch to using m-expressions as god intended :D

10:21 Raynes: http://gregslepak.posterous.com/on-lisps-readability

10:23 Looks like he got rid of the comments after-the-fact.

10:23 mec: Thats not any more readable, the extra ) dont help you line up. What he really wants is an editor that shows indent lines

10:23 semperos: say I have a running Jetty instance (using ring.adapter.jetty); how can I write a function which sends a request to my server app running on Jetty, gets a response, and then causes the server to shutdown after the response has been sent?

10:24 Raynes: When I start seeing that post referenced by people on his side of the argument, I vow to jump off my roof into a glass of water.

10:26 semperos: to be more precise, how do I write a server-side function that will return a response and then shut down the server

10:27 a somewhat hackish solution seems to spawn a new thread, wait X seconds and then call (.stop)

10:27 but I was wondering if folks could think of something more robust

10:38 Fossi: let is defined as let*. where's that defined?

10:39 devn_: M-. ;)

10:41 Fossi: won't tell me

10:41 :/

10:41 neither did repl-utils

10:44 gfrlog: Fossi: some grepping turns up src/jvm/clojure/lang/Compiler.java

10:45 Fossi: so it's probably bootstrapped in Java

10:45 Netfeed: Raynes: i think that his way is more readable right now, but i started with clojure yesterday so that thought might change quiet fast :)

10:45 Fossi: ah

10:47 gfrlog: Fossi: let is a 'special form', which I believe means it's more fundamental than a fn or macro

10:47 pdk: special forms are the builtins that come hardcoded into the implementation

10:47 gfrlog: ,#'let

10:47 clojurebot: #'clojure.core/let

10:48 gfrlog: 'let

10:48 ,let

10:48 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/let

10:48 gfrlog: eh what do I know

10:48 Fossi: the real question was whether let binds a var

10:48 gfrlog: Fossi: I doubt it

10:48 Fossi: ie whether you can pass the result with #'something

10:49 gfrlog: I'm not sure why let would have to be a special form actually. Maybe for performance. I think you could write a let macro that translates everything to fns

10:49 (let [x 12] (+ x (* x x))) => ((fn [x] (+ x (* x x))) 12)

10:53 ,((fn [x] #'x) "foo")

10:53 clojurebot: java.lang.Exception: Unable to resolve var: x in this context

10:53 gfrlog: ,(let [x "foo"] #'x)

10:53 clojurebot: java.lang.Exception: Unable to resolve var: x in this context

10:54 malbertife: gfrlog: sure you could, see sicp chapter 1

10:54 gfrlog: section 1.3.2, shows how let is syntactic sugar for lambda expressions

10:54 gfrlog: malbertife: I believe it

10:55 malbertife: which would mean it doesn't have to be a special form in clojure

10:55 malbertife: but probably all the fn calls are expensive compared to creating local variables in the bytecode

10:56 malbertife: integers could be sugar for lambda expressions as well ;-)

10:56 malbertife: gfrlog: i see your point

11:01 gfrlog: man this class has an #as(clazz) method, and then a #canAs(clazz) method to go with it

11:02 makes me think of middle school and wrestling

11:08 chouser: oh crap now I need to pass the model-maker back to another createModel method on the original ModelFactory

11:09 kephale00: Is there a prettier way of converting a nested seq to a string than a recursive (if (seq? coll) (map nest-to-str coll) (str coll))?

11:12 chouser: gfrlog: yes, let as a special form is almost certainly for performance, in a couple differenct directions.

11:13 fn calls are more expensive than let, and every fn is a class which already stresses the JVM in a direction it wasn't really designed for.

11:13 let and fn locals have nothing to do with the Var reference type

11:14 kephale00: nested exactly one level deep, like [["a" "b"] ["c" d"]]? Or sometimes deeper?

11:14 & (apply str (flatten [["a" "b"] ["c" "d"]]))

11:14 sexpbot: ⟹ "abcd"

11:19 kephale00: chouser: almost always deeper, and I am attaching '(' ')' on either side, so the snippet I sent wasn't exactly what I'm doing

11:19 oh duh

11:19 print-str

11:20 thanks!

11:23 & (clojure.contrib.str-utils2/replace (print-str '((E (C) (F I) F) (A A) H ((G) B) ((E G (I (I I A)) H I) (B) (A) C (D (H))) (F C C))) #" " "")

11:23 sexpbot: java.lang.ClassNotFoundException: clojure.contrib.str-utils2

11:23 kephale00: heh

11:25 gfrlog_: kephale00: so you want a nested seq of strings to be returned?

11:26 kephale00: gfrlog_: yes, and that expression worked in my repl

11:28 gfrlog_: kephale00: I'm not too familiar with the clojure.walk namespace, but I think that has something

11:28 kephale00: particularly the post-walk function?

11:28 chouser: & clojure.string/replace

11:28 sexpbot: ⟹ #<string$replace clojure.string$replace@18d68a9>

11:29 kephale00: gfrlog_: yeah, walk did seem like a reasonable alternative

11:29 ah I guess I might use str-utils2 too much : P

11:30 chouser: kephale00: no it's fine, it's just been superceded by clojure.string

11:30 AWizzArd: Is there a good example for the use of 'ensure'?

11:30 kephale00: & (clojure.string/replace (print-str '((E (C) (F  F) (A A) H ((G) B) ((E G (I (I I A)) H  (B)  C (D (H))) (F C C))) irc://irc.freenode.net:6667/#" " "")

11:30 sexpbot: java.lang.Exception: EOF while reading

11:30 kephale00: upps

11:31 & (clojure.string/replace (print-str '((E (C) (F F) (A A) H ((G) B) ((E G (I (I I A)) H (B) C (D (H))) (F C C))))) #" " "")

11:31 sexpbot: ⟹ "((E(C)(FF)(AA)H((G)B)((EG(I(IIA))H(B)C(D(H)))(FCC))))"

11:31 kephale00: yeah that

11:31 chouser: good to know

11:32 Raynes: &(clojure.walk/postwalk #(if (coll? %) % (str %)) '((E (C) (F I) F) (A A) H ((G) B) ((E G (I (I I A)) H I) (B) (A) C (D (H))) (F C C)))

11:32 sexpbot: ⟹ (("E" ("C") ("F" "I") "F") ("A" "A") "H" (("G") "B") (("E" "G" ("I" ("I" "I" "A")) "H" "I") ("B") ("A") "C" ("D" ("H"))) ("F" "C" "C"))

11:32 Raynes: That was fun.

11:32 gfrlog_: Raynes: does it not have a version that only applies to leaf-nodes?

11:32 Raynes: gfrlog_: Not sure. Didn't bother checking.

11:33 chouser: & (-> '((E (C) (F I) F) (A A) H ((G) B) ((E G (I (I I A)) H I) (B) (A) C (D (H))) (F C C)) pr-str (clojure.string/replace " " ""))

11:33 sexpbot: ⟹ "((E(C)(FI)F)(AA)H((G)B)((EG(I(IIA))HI)(B)(A)C(D(H)))(FCC))"

11:34 Raynes: gfrlog_: Doesn't look like it.

11:34 * Raynes didn't realize he wanted the whole thing as a string. Thought he wanted the individual elements to be strings.

11:35 * Raynes shuffles off with his head down.

11:35 gfrlog_: Raynes: I understood it that way too, as that's what I thought he told me.

11:35 Raynes: see exchange at 11:22

11:35 Raynes: Well, there she blows, for future reference. :D

11:36 kephale00: Raynes: nono, you answered what i originally asked

11:36 i just asked the wrong thing

11:36 Raynes: Understood.

11:36 gfrlog_: now this story has come to a satisfying conclusion

11:39 chouser: &((fn f [s] (str \( (apply str (map #(if (list? %) (f %) %) s)) \))) '((E (C) (F I) F) (A A) H ((G) B) ((E G (I (I I A)) H I) (B) (A) C (D (H))) (F C C)))

11:39 sexpbot: ⟹ "((E(C)(FI)F)(AA)H((G)B)((EG(I(IIA))HI)(B)(A)C(D(H)))(FCC))"

11:39 AWizzArd: Why can refs change in other transactions when I don't (ensure them)?

11:39 chouser: I guess that was the original "bad" solution?

11:40 AWizzArd: Refs can change in other transactions regardless of whether you ensure them.

11:40 kephale00: not bad persay, but I'm going to be running the function on the order of millions of times

11:41 chouser: kephale00: might be more efficient recursing directly like than than pr-str+replce

11:41 kephale00: or maybe not -- would be interesting to find out

11:41 kephale00: chouser: hrm… i'll do some speed tests

11:41 chouser: of course millions of times still might not be enough to matter.

11:43 kephale00: incidentally, is there a simple way of doing speed tests? I have been doing such tests with nanoTime inside a let

11:44 chouser: (doc time)

11:44 clojurebot: "([expr]); Evaluates expr and prints the time it took. Returns the value of expr."

11:45 gfrlog_: ,(time (doc time))

11:45 clojurebot: "Elapsed time: 0.48 msecs"

11:45 "([expr]); Evaluates expr and prints the time it took. Returns the value of expr."

11:45 kephale00: ah… *forehead smack*

11:45 chouser: but you still have to be very careful about Hotspot warmup, etc.

11:45 mduerksen: chouser: "Refs can change in other transactions regardless of whether you ensure them". really? from what i understood from the docs, it should not happen. did i miss something?

11:45 gfrlog_: if (time) had a version that returned the time, that would make it convenient to time 10000 runs and average them

11:47 mec: (defmacro new-time [expr] `(let [start# (System/nanoTime) ret# ~expr] [(/ (double (- (. System (nanoTime)) start#)) 1000000.0) ret))

11:47 (defmacro new-time [expr] `(let [start# (System/nanoTime) ret# ~expr] [(/ (double (- (. System (nanoTime)) start#)) 1000000.0) ret]))

11:48 chouser: mduerksen: We're using sloppy language here, I'm afraid. The same Ref can change, independently of each other in two separate transactions at the same time, but if both try to commit it has to be resolved somehow.

11:49 alter and commute resolve such a conflict in different ways.

11:49 mduerksen: chouser: ah, thanks for the clarification, my world view makes sense again ^^

11:49 chouser: oh, good. :-)

11:50 I'm not quite sure what AWizzArd meant.

11:54 raek: maybe he was referring to "write skew" (http://java.ociweb.com/mark/stm/article.html#write-skew)

11:55 mduerksen: AWizzArd: do you mean this: why do i have to ensure a ref when "alter" will take care of consistency? in that case, consider the skew anomaly

11:56 oops, raek was faster

11:58 AWizzArd: I will look up that link.

11:59 I just thought that as soon a ref is touched via deref or alter, then a consistent view is guaranteed.

11:59 So, "why ensure"? I will now check that link.

12:00 mduerksen: AWizzArd: deref does not touch, thats exactly what ensure does

12:01 but while we're at that topic: i observed that when an ensured ref is altered by a competing thread to *the same value*, neither of the transactions will fail. did i observe correctly, and is this what is meant by "allows for more concurrency than (ref-set r @r) ?

12:03 raek: that link is great, btw

12:12 Dantas: Best wishes from Brasil( Brazil ) :P

12:12 im wondering : how could i know the market rate for clojure/scala jobs ?

12:19 technomancy: Dantas: there aren't really enough of them yet to generalize about

12:21 Dantas: technomancy: yes , that is my conclusion after a quickly search in google

12:21 technomancy: thnx

12:37 thorwil: (def article-atts '[title, body, created-t, updated-t])

12:37 (ds/defentity Article (vec (concat [^:key slug] article-atts)))

12:38 fails with: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

12:38 any way around that?

12:39 amalloy: um. i bet defentity is a macro

12:39 in which case, like all macros, it can't do compile-time stuff (define an entity) with data that exists only at runtime (article-atts)

12:40 to get this basic effect, you would need to define a macro that expands into a call to defentity with a *literal* argument, because macros love literals

12:41 thorwil: *bulb-lights-up*

12:46 amalloy: thorwil: well i'm glad you got the idea, because i can't find any of my code that actually does this at the moment

12:46 i guess my article http://hubpages.com/hub/Clojure-macro-writing-macros has an example. it's kinda ugly and not targeted right at what you're doing, but it's in the ballpark and you would probably find it educational

12:47 thorwil: amalloy: i will see if i really got the idea after dinner. but just really getting that i sometimes have to know if i deal with a macro or a function is a step forward :)

12:55 cgray: hi, what's the inverse of `name'?

12:55 amalloy: cgray: name is a many-to-one mapping; it has no strict inverse. but keyword is probably what you meant

12:55 cgray: amalloy: thanks

13:01 Dantas: Atoms doesn´t need to be inside a transaction, right ? and atoms are shared for all threads. How coordinate this kind of shared state ?

13:02 chouser: Dantas: an atom's value is changed using 'swap!', only one of which can happen at a time.

13:03 Dantas: chouser: so , the update-function is atomic

13:03 chouser: right ? thx in advance

13:04 raek: the atomicity is handled automatically (but requires the update funtion to be free of side-effects)

13:07 basically, what swap! does is something like (defn swap! [a f & args] (loop [] (let [old-val @a, new-val (apply f old-val args)] (if (compare-and-set! a old-val new-val) new-val (recur)))))

13:08 fliebel: and it calls the watch fns ;)

13:10 * fliebel isn't a contributor still :(

13:14 elb0w: What function do you guys see clojure serving now (5 years from now)? Im trying to decide if its something I should pick up as a primary/secondary language. Always good to hear from people who use it Day to Day imo

13:15 chouser: In 5 years many key concepts from Clojure will have been adopted by several existing languages as well as new ones.

13:16 Clojure itself by then may have acheived maximum mindshare that a LISP can (that is, somewhat less than, say, ruby has today)

13:17 Most academic papers will continue to use either Haskell or Java for their examples.

13:17 elb0w: How's that for a stab in the dark? :-)

13:18 TimMc: elb0w: Pick it up if only to learn some of the concepts it is based on. THere's some really neat stuff in there.

13:18 elb0w: hmm

13:18 Is it a either or thing with haskell?

13:19 Or can you see a benefit to both?

13:19 most people I speak with compare it to haskell

13:19 chouser: elb0w: I don't know haskell as well as I intend to, but I think each will give you unique insight.

13:20 elb0w: ok cool, can you suggest any good entry books to it? I have a 6hr plane ride im trying to get some material together :P

13:21 cemerick: chouser: I think it's got more upside potential than Ruby had back in the day, mostly due to far lower switching costs re: the JVM.

13:21 chouser: elb0w: start with any of Programming Clojure, Practical Clojure, or Clojure in Action, and follow up with Joy of Clojure. [I've only read the first and last of those]

13:21 lucian: that depends a lot on what platform you're already using

13:21 but yeah, clojure's great. i think it's likely the best lisp ever, perhaps better than racket

13:21 learn it

13:22 * lucian should follow lucian's own advice

13:22 chouser: cemerick: I do think the syntax will continue to be an impediment to maximal adoption.

13:22 TimMc: elb0w: If you haven't used software transactional memory before, you need to try Clojure. :-)

13:23 chouser: It has already grown the LISP base (if you will) in some directions, but there's a lot of people who I think will continue to reject it on syntax alone.

13:23 fliebel: chouser: Someone suggested a whitepsace absed syntax for Clojure, as a pre-processor :)

13:24 * technomancy wasn't too impressed with early clojure in action drafts

13:24 chouser: fliebel: Pleajure, iirc

13:24 lucian: well, if it went farther in replacing lists with more appropriate data structures, the syntax might not be a big issue anymore

13:24 fliebel: i'd love that

13:24 cemerick: fliebel: the CL'ers went through that years and years ago. Doesn't seem to have panned out so well.

13:24 lucian: cemerick: i think they just did it wrong

13:24 chouser: https://github.com/apatil/pleajure

13:25 TimMc: elb0w: Just beware of the syntax in older Clojure books -- some trivial changes (like #^ -> ^) have occurred that will confuse you if you are unaware.

13:25 lucian: there's http://portal.acm.org/citation.cfm?id=1566481

13:25 fliebel: You know, basically it's just a yaml parser… :)

13:25 lucian: i think it comes close to having nice syntax

13:28 fliebel: lol @ pleajure (defn zip "Like Python's zip" …)

13:28 lucian: pleajure is a bit wrong

13:29 fliebel: yea, he seems to use 4 spaces as well.

13:29 lucian: 4 spaces is fine

13:29 but if it's a preprocessor, it's failed already

13:29 fliebel: lucian: Why?

13:29 lucian: it has to be either official or a reader macro (which clojure doesn't have) to succeed at all

13:30 pdk: (doc zip)

13:30 clojurebot: It's greek to me.

13:30 fliebel: pdk: zip is like (map vector list list2)

13:31 lucian: http://docs.python.org/library/functions.html#zip

13:32 dnolen: chouser: cemerick: I think people deeply familiar with FP have little problems with with the parens. As FP becomes more mainstream, I think the ceiling on Clojure adoption gets much higher.

13:33 lucian: dnolen: they're just redundant

13:33 i wish more people realised that

13:33 cemerick: lucian has never seen cemerick's code ;-)

13:34 lucian: cemerick: i take it you misindent your code?

13:34 cemerick: lucian: no, but it's not a 1:1 correspondence between lines and sexprs

13:34 amalloy: redundant?

13:34 opqdonut: dnolen: FP is not the same as lisp syntax

13:35 lucian: cemerick: lines aren't they only whitespace, and whitespace doesn't have to be the only delimiter

13:35 cemerick: dnolen: I'd generally agree, but I'd go a little further. The stigma surrounding sexprs seems to have been dwindling for quite a while. A generational thing, perhaps.

13:35 lucian: sounds like you have something in mind that is *way* more complicated than I'd like to consider.

13:35 amalloy: lucian: reduce partial apply + 2 range 10

13:35 lucian: cemerick: i don't have something particular in mind

13:36 i do however know that python is very, very readable

13:36 amalloy: that needs parens to make any sense; putting it on like five lines would be a mess

13:36 dnolen: opqdonut: most interesting FP papers are in, SML, Scheme, Haskell, Oz, Erlang. Point is, FP languages have many approaches to syntax. For FPers, syntax sits on equal footing with semantics.

13:36 fliebel: amalloy: Your unicode is all wrong there, that second space should be a nbsp, and the last one should be a zwj.

13:36 lucian: amalloy: i never suggested that

13:36 amalloy: one line? put the parens in

13:36 opqdonut: dnolen: yeah sure

13:36 amalloy: lucian: my point is you said parens are redundant

13:37 lucian: amalloy: most of them, yes

13:37 opqdonut: dnolen: I guess I misinterpreted your earlier comment :)

13:37 lucian: no no, you must mean that indentation is redundant!

13:37 lucian: i'd say all of them, if lisp didn't insist on only using lists

13:37 fliebel: lucian: Not that Python has some additional and very important hinst about what is a block.

13:38 Chousuke: lucian: Clojure doesn't only use lists.

13:38 amalloy: lucian: python is fine to read, but it gets away with a lot because it's imperative and large "expressions" can easily be split up by newlines

13:38 lucian: fliebel: yes, of course. which is part of why i think lisp failed when it comes to syntax

13:38 amalloy: that's irrelevant. the syntax is awesome

13:38 Chousuke: barely

13:38 Chousuke: lucian: no

13:38 amalloy: *sob* srsly lucian

13:38 Chousuke: lucian: vectors are pretty common

13:38 lucian: Chousuke: it uses a few vectors, that's it

13:38 hiredman: lucian: I disagree

13:38 clojurebot: python

13:38 clojurebot: python is ugly

13:39 Chousuke: lists are common in code because most of the time you're calling functions or other operators

13:39 lucian: Chousuke: and that's a failure of lisp if you ask me

13:39 Chousuke: lucian: what, calling functions? :P

13:39 lucian: it may be relatively nice as a language, but its syntax sucks, because its ast sucks

13:39 fliebel: lucian: What is the difference between somthing(args arg) or (something args arg)?

13:39 lucian: Chousuke: no, using lists for everything

13:39 fliebel: that's not what i'm arguing about

13:40 fliebel: that's absolutely fine

13:40 fliebel: but parents + newlines is redundant

13:40 zakwilson: No modern lisp uses lists for everything.

13:40 Chousuke: lucian: lists are pretty much exclusively used for operator calls in Clojure

13:40 zakwilson: Or do you mean syntax?

13:40 lucian: zakwilson: yes

13:40 Chousuke: even in syntax.

13:40 * lucian brb

13:40 zakwilson: I'd say most of them do use lists for almost everything in syntax, and that's where Clojure differs.

13:41 hiredman: lucian: conflating the datastructures generated by the reader is a common mistake, but it is a mistake, so please stop doing it

13:41 Chousuke: zakwilson: that's true.

13:41 pdk: having [] #{} {} is helpful in some spots

13:41 hiredman: lucian: conflating with an ast

13:41 pdk: if you think about it works well for delimiting stuff like argument lists in fns/binding lists in let

13:41 to visually separate them from the following bodies

13:42 zakwilson: Clojure uses lists and vectors heavily in its syntax, maps less so. I haven't seen sets used as part of the syntax.

13:42 pdk: clearly we need to fork it

13:42 Chousuke: map syntax is pretty much only used in destructuring

13:42 pdk: and make it more set based!

13:42 picture it

13:42 function bodies can be sets of forms

13:42 Chousuke: But people have tried to "fix" Lisp syntax many times before

13:42 pdk: "yeah just execute these in any order you like"

13:42 clojurebot: Excuse me?

13:42 Chousuke: they've always failed

13:43 opqdonut: yep

13:43 it

13:43 's always some newcomer

13:43 who doesn't want to believe that yes, yo do get used to the parens

13:43 quite quickly in fact if you just stop hating them

13:44 Chousuke: I don't know why you'd hate them in the first place.

13:44 opqdonut: many do, I've found

13:44 amalloy: i liked this weekend's tweet: lisp is the most-hated language among people who've never used lisp

13:44 fliebel: Has anyone seen Io? They claim it's like lisp without the Syntax. It;s pretty uniform at least, with code blocks implemented as methods and all.

13:44 opqdonut: amalloy: indeed.

13:44 minimal syntax is nice, I think lua succeeds at this too

13:44 pdk: io is pretty neat conceptually though i don't know of anything serious using it yet

13:45 amalloy: i found the parens a stumbling block too. it's just very different from what we learned in school for both math and programming

13:45 zakwilson: I've seen attempts by Lisp experts to overlay a syntax on top of Lisp, but it's always for the purpose of making the language more attractive to beginners.

13:45 Chousuke: any attempt to do away with the parentheses will just obscure the fact that lisp code is data

13:45 fliebel: I wonder what message passing and prototype based inheritance would do to functional programming. :P

13:45 amalloy: the important thing is to man up and get over the language's *punctuation* and look at the language. then you find out the punctuation is there for a reason

13:45 dnolen: fliebel: Clojure already has a form of protoype inheritance.

13:46 fliebel: dnolen: Yea, multimethods, right?

13:46 Chousuke: if you can find a better and more succinct notation for lists than (foo bar) I'd like to see it :)

13:46 dnolen: fliebel: yes.

13:46 Chousuke: because if the lisp code you write does not correspond directly to a lists and other data elements, then it's not lisp code :/

13:46 -a

13:46 amalloy: Chousuke: haskellers would suggest just "foo bar", i suspect

13:47 zakwilson: Haskell lists are [foo, bar]

13:47 lucian: Chousuke: yes, code is data. but the wrong kind

13:47 Chousuke: amalloy: hmm, but how do you do (foo (bar zonk)) then?

13:47 lucian: what sort of data should it be then?

13:47 lucian: Chousuke: yaml

13:47 amalloy: zakwilson: Chousuke is talking about code lists: calling functions

13:47 fliebel: stack based programming to the rescue… maybe

13:47 opqdonut: hahahahah yaml

13:47 oh my

13:47 lucian: meh, not literally

13:47 Chousuke: lucian: you mean maps?

13:48 zakwilson: haskell nested function calls are foo (bar baz)

13:48 lucian: Chousuke: no, i mean non-redundant data structures

13:48 amalloy: Chousuke: foo and bar know how many arguments they expect. i think the syntax is foo $ bar zonk, or foo (bar zonk)

13:48 Raynes: I think I'd rather Clojure never see a new user than for it to adopt a Python-like syntax because people don't 'get' s-expressions.

13:48 Chousuke: lucian: and in which way are lisp data structures redundant?

13:48 lucian: Raynes: i "get" s-expressions, i just know they're uselessly redundant

13:48 Chousuke: they're indented *and* paren-separated

13:48 Raynes: "You're so wrong, you're visible from satellite."

13:49 Chousuke: lucian: eh, that's not lisp code.

13:49 TimMc: heh

13:49 Chousuke: lucian: that's text.

13:49 Raynes: amalloy: Is that good enough?

13:49 opqdonut: lucian: most other languages have punctuation + indentation

13:49 like for example jagva

13:49 -g

13:49 lucian: opqdonut: that's also wrong

13:49 Raynes: It doesn't make a lot of sense, but it's along the lines of what I used before.

13:49 opqdonut: python is about the only exception I know of

13:49 lucian: opqdonut: python, haskell, a few others

13:49 TimMc: lucian: A little well-placed redundancy aids readability.

13:49 Chousuke: lucian: the problem is that if the *text* does not map trivially to code, using features like macros becomes difficult.

13:50 TimMc: That's why most languages are written with capital initial letters.

13:50 opqdonut: okay yeah Haskell's layout rules too

13:50 lucian: TimMc: i disagree with that. again, look at python

13:50 TimMc: *natural languages

13:50 fliebel: lucian: So you want to replace : with ( and \n\n with )?

13:50 lucian: Chousuke: not text, other datastructures

13:50 fliebel: dunno, maybe

13:50 sweet-expressions is close

13:50 Chousuke: lucian: what data structures? I honestly don't understand you

13:50 lucian: if you talk about indentation and parens, that's text.

13:50 lucian: Chousuke: yaml represents data structures, right?

13:51 Chousuke: forget about s-exps

13:51 zakwilson: I tihnk that Clojure is just not for lucian, and that's why it's a good thing we have thousands of languages to choose from.

13:51 Raynes: Are we currently using Python as an example of perfect syntax here?

13:51 lucian: Raynes: I am. but not perfect, just very, very good

13:51 * Raynes facepalms

13:51 lucian: zakwilson: i like clojure very much, just not its concrete syntax

13:51 joly: Indention in Clojure is for readability, not syntax or symantics

13:51 * lucian facepalms at Raynes

13:53 zakwilson: lucian: you could write your own parser or borrow jython's and hook it up to Clojure's data structures and standard library.

13:53 lucian: zakwilson: sure

13:53 Chousuke: lucian: I don't know why yaml would be better for code than Clojure's version of s-expressions

13:53 dnolen: lucian: present a good macro system w/o sexpr syntax. Dylan tried and failed.

13:53 Chousuke: that too

13:53 lucian: dnolen: the problem is no one else tried

13:53 fliebel: lucian: So it's not that parens are redundant, you are just proposing an alternate syntax for lists that is more liek yaml.

13:53 lucian: clojure tried a little, with vectors

13:53 pdk: #ifdef!

13:53 lucian: fliebel: sure, that'd be a start

13:54 Chousuke: if your syntax is dependent on whitespace or indentation, it's pretty difficult to beat syntax/quasiquote

13:54 pdk: yea baby

13:54 zakwilson: Nemerle, Ioke and Mirah also have macro systems without sexp syntax. I looked at Nemerle's and it seemed much harder to use than Lisp's.

13:55 Raynes: It's only natural that it be harder to use. When your syntax is unnecessarily complex, so is your macros.

13:55 are*

13:55 zakwilson: I should note that I did not actually use it; I just read example code.

13:55 * lucian throws his hands in the air in despair

13:56 * Raynes throws his fist in the are in revolt

13:56 Raynes: air*

13:56 * Raynes gives up.

13:56 dnolen: lucian: many people have tried. Template Haskell, camlp4. Those are serious systems. But go ahead, give a shot as well.

13:56 lucian: i'm not very worried about macros being easy

13:56 i'm much more worried about readable syntax

13:57 Raynes: I certainly am. That's one of the greatest things about Lisp.

13:57 * Raynes can read it just fine! :>

13:57 lucian: Raynes: well, lisp fails at macros anyway :)

13:57 * lucian ducks

13:57 Chousuke: lucian: You're still simply asserting that lisp is not readable.

13:57 Frankly, I think you're wrong.

13:57 lucian: scheme gets macros a little better, but still not quite perfect

13:57 Chousuke: it's not, at all

13:57 it's much more readable than, say, java

13:57 fliebel: rainbow parens to the rescue :)

13:57 opqdonut: lucian: have you tried racket's macros?

13:57 lucian: but nowhere near lisp

13:57 opqdonut: yes, they're very close to being perfect

13:57 zakwilson: lucian: you're trying to convince a bunch of lispers that some other syntax is better.

13:58 lucian: zakwilson: yes, i see the folly of my ways

13:58 Chousuke: Nowadays I find Clojure more readable than python honestly

13:58 lucian: s/but nowhere near lisp/but nowhere near python/

13:58 Chousuke: CL is a bit iffy because they really do use lists for everything

13:58 joly: hard to make a general "more readable" declaration when it depends so much on the person doing the reading

13:58 dnolen: lucian: no Scheme messed up macros royally, and it's taken 20 years to fix it. clearly you haven't seen at the monstrous macros in CPS style hacks.

13:58 Chousuke: but Clojure code is nice.

13:59 lucian: dnolen: that's not the point, they're better because they happen later in the compilation process

13:59 zakwilson: The thing that I always have trouble with in other languages is seeing where the scope of a variable ends.

13:59 Raynes: lucian: You're filled from your toes to your eyeballs with "better", but you have no implementations. You sound like the kind of person that should create their own programming language! Maybe us primitive Lispers will understand better if we actually see a successful implementation of your ideas.

13:59 fliebel: Man, I'm so going to make a yaml to clojure converter :D

14:00 Chousuke: fliebel: well, that's not too hard.

14:00 lucian: Raynes: i didn't mock you, you know

14:00 Raynes: I am dead serious.

14:00 Chousuke: fliebel: just find a yaml reader and convert its output to clojure data structures :P

14:00 fliebel: Chousuke: I'd think so, otherwise I'd not waste my time on it.

14:00 zakwilson: People with ideas about languages that other people just don't get *should* write their own language.

14:00 lucian: Raynes: when it comes to readability, lisp is "primitive". i offered no insult to other aspects of lisp or its users

14:01 the reason i don't bother to write a language is because i know i'll be the only user, forever

14:01 Chousuke: I still don't agree with that assertion

14:01 zakwilson: Lisp is primitive, or perhaps simple.

14:01 lucian: not worth the trouble

14:01 Raynes: lucian: What zakwilson just said. If we don't feel it's better, then show us it's better. Write your own language with perfect macros and great syntax.

14:01 Chousuke: and you're not doing anything to support it either :/

14:01 zakwilson: Write your own syntactic overlay for Clojure then. I bet you could get a few users.

14:02 I'd even try it, just to prove that I like Clojure's syntax better.

14:02 Raynes: zakwilson: He has asserted that an 'overlay' wouldn't be good enough, IIRC.

14:02 lucian: it just wouldn't survive

14:02 i have no urge to add to the pile of unused languages

14:03 i'll just grumble and use python and clojure

14:03 fliebel: I do… I think tree based programming is the future!

14:03 zakwilson: Of course it wouldn't. Syntactic overlays for Lisp have been tried many times, the first being from John McCarthy himself.

14:03 joly: I've used several languages I'd love to add to that pile :P

14:03 lucian: joly: heh

14:04 zakwilson: If you actually came up with the "perfect syntax", perhaps other languages would emulate it. Research/experimental languages aren't meant to be *used* but to influence the future.

14:04 amalloy: lucian: if it's a really great idea, you won't be the only user

14:04 Raynes: Precisely.

14:04 lucian: amalloy: i don't (yet) have a clear picture of what i want

14:05 zakwilson: Or what amalloy said.

14:05 lucian: i do know that i want readable syntax in a homoiconic language

14:05 amalloy: hah i was going to amend myself to "actually more like what zakwilson said"

14:05 zakwilson: Heh. Either is a possibility.

14:05 Clojure was, after all just some guy's attempt to make a better language for himself.

14:05 * Raynes showers to clean off all of the outrageous assertions.

14:05 lucian: the problem is that apparently people don't agree on what's readable

14:06 Raynes: Nobody agrees on anything. That's why we have a million different languages.

14:06 lucian: C, C#, Java, Python, PHP people all largely agree that python clearly has a readable syntax

14:06 zakwilson: lucian: are you familiar with Ioke?

14:06 lucian: zakwilson: vaguely

14:07 fliebel: cemerick: Google just threw up a log where you mentioned you are working on spatial index structures in Clojure. Do you have any of these laying around?

14:07 cemerick: lucian: Seriously, get one programmer from each camp in a room, and you'll have N+1 opinions.

14:07 Chousuke: lucian: I won't deny that Python is readable, but I don't think that it's better than Clojure, either.

14:07 dnolen: lucian: semantics and syntax are intertwined. Clojure permits new scopes via let, it discourages side effects, it's doesn't support arbitrary control flow. These are all un-Pythonic. What would a paren-less Clojure even look like?

14:07 lucian: sure, that's why ruby, clojure, python programmers can't decide which clearly has the most readable syntax

14:07 cemerick: fliebel: mm, haven't worked in that area in a while. But yeah, I did. They're done. Nothing open sourced, tho.

14:08 lucian: dnolen: well, they're not all unpythonic

14:08 zakwilson: Ioke claims to be homoiconic but has a syntax that looks more like popular scripting languages. It has macros. I think it's close to what you want.

14:08 lucian: abstract syntax is linked to semantics, yes

14:08 concrete syntax, not really

14:08 zakwilson: yes, i know. it's interesting

14:09 fliebel: cemerick: Oh, to bad… I'm in a need for some spatial indexing. R-tree would be nice for example. I'm about to cut corners and base it on java.awt.Rectangle.

14:09 dnolen: lucian: I repeat my question. Given Clojure's semantics what would a block syntax look like?

14:10 cemerick: fliebel: make sure your dataset and query types really warrant it. Brute-force search outperforms R-Trees depending on those factors, especially over smallish N's.

14:10 lucian: dnolen: i'm not sure

14:10 Raynes: zakwilson: Also, see Atomo.

14:10 cemerick: dnolen: probably something like scala, but without vars

14:10 fliebel: cemerick: What scale of N's are we talking about here? Is a couple of hundred still smalish?

14:10 * cemerick is ignoring macros

14:11 zakwilson: Atomo is in my browser history. I don't remember it though.

14:11 lucian: dnolen: close to http://www.dwheeler.com/readable/ perhaps

14:11 or ginger

14:11 cemerick: fliebel: yes -- just a couple of helper fns and filter will do you just fine there

14:11 fliebel: cemerick: Okay, I wrote overlaps? and contains? already...

14:12 cemerick: fliebel: right; (filter (partial overlaps? query-region) data), etc. You need many thousands of rects to make indexing worthwhile.

14:12 lucian: dnolen: but without the infix bit, i don't think that's very useful

14:12 cemerick: (at least for typical queries)

14:12 amalloy: lucian: people make the same assertions about python's whitespace that they do about lisp's parens. i don't know how you can claim that programmers from every language claim python is readable

14:13 zakwilson: For something on-topic: do we have a roadmap for 1.3's release yet?

14:13 lucian: amalloy: not every, just several

14:13 Raynes: http://amplicate.com/users/15168213/anthony-simpson-iorayne

14:13 Er, wrong window.

14:13 fliebel: cemerick: Yea, just collision detection mostly. A intermediate shortcut would be a flat grid.

14:13 lucian: amalloy: as i said, other sets of programmers don't

14:13 amalloy: i disagree with you about every language on your list except for python

14:14 having written in all of them but C# myself for at least a year each. i'm sure if i wrote python it would look readable to me, but it doesn't really yet. the same goes for any C programmer who's never written python

14:15 cemerick: fliebel: If you're really interested in digging into the field, start here: http://www.amazon.com/gp/product/0123694469/ref=as_li_ss_tl?ie=UTF8&tag=httpcemericom-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0123694469

14:16 lucian: amalloy: my data is mostly anecdotal, so of course i'm not certain. but an overwhelming majority of programmers who's language of choice was one in that list agreed

14:16 (the small subset that i asked, of course)

14:17 Raynes: 6 out of 10 programmers agree that programming languages are microwaves.

14:17 fliebel: cemerick: I'm not *that* interested, but I like to implement and understand algorithms and data structures from time to time.

14:18 cemerick: What where you using these R-trees for?

14:19 cemerick: fliebel: Still being used. In the bowels of docuharvest, the next rev of PDFTextStream, and other places.

14:19 fliebel: see, you're misquoting me slightly :-)

14:19 mattmitchell: i have a lein project which uses sdb and mysql. I'd like to create tests that actually prove the data is getting inserted into mysql, and not just mock everything.

14:19 cemerick: I know *nothing* about collision detection per se

14:20 mattmitchell: what's the recommended approach for switching environments (use test db when running tests etc.) ?

14:20 cemerick: Especially in real-time contexts (i.e. gaming)

14:21 My most common queries over spatial indexes are nearest-neighbor, neighbor traversal (which is a sort of compound query), and windows.

14:23 If you're in a real-time environment, your biggest problem will be the update penalty: adding regions to e.g. R-Trees can be very expensive, depending on what variant and configuration parameters you're using.

14:24 fliebel: cemerick: Yea… So that is another plus for just using the way I store objects already.

14:24 cemerick: There are other structures that are more dynamic, but I'm not super familiar with them (since all my use-cases involve static datasets).

14:26 fliebel: For a sorted-map, what is the insertion cost? I currently store objects in a map, so sorting that would limit brute forcing to one axis.

14:27 cemerick: sorry, I don't keep big-O times at the tip of my tongue :-)

14:28 fliebel: no? oh, disappointment al around. ;)

14:28 I'll google it

14:28 gfrlog: O(log(log(n^(n!)))) probably

14:28 fliebel: gfrlog: Is that much?

14:29 gfrlog: fliebel: it's completely fictional; I have no idea

14:29 zerokarmaleft: that reduces to O(log(n)) so no

14:29 gfrlog: zerokarmaleft: does it?

14:30 amalloy: fliebel: logn insertion to sorted map is right in imperative/mutable context. i don't see a reason it would be different here but it could be

14:30 raek: has Clojure 1.2.1 been announced yet?

14:31 amalloy: zerokarmaleft: that does not reduce to logn. it reduces to "holy crap that's a lot"

14:32 Raynes: raek: It's already out, iirc.

14:32 amalloy: Raynes: but not "announced"

14:32 Raynes: Why would you expect it to be announced 3 weeks after it was released?

14:33 I gave up on that.

14:36 zakwilson: Raynes: the download link on clojure.org is 1.2.0

14:36 zerokarmaleft: amalloy: n^n! is huge sure, but the outer functions are logarithms...as a generalized growth rate, it's still small relative to O(n!) by itself

14:37 Raynes: zakwilson: It's on maven though. Leiningen uses it by default in new projects.

14:37 Cake probably would to if anybody cared to release a new version just for that.

14:37 zakwilson: Raynes: I see 1.2.1 on github too. I wonder why the link on the main site hasn't been updated.

14:38 amalloy: zerokarmaleft: even if log(n^n!) were n! (which i don't believe it is but it's been some time), log(n!) is clearly much larger than log(n)

14:39 and you proposed that log(log(n^n!)) was the same as log(n), big-O wise

14:40 zerokarmaleft: yea, now that i've said that i can't remember for sure...i pulled O(n log n) = O(log n!) out of that fuzzy place

14:41 thorwil: amalloy: i guess this is not quite what you meant, as indicated by the fact that it doesn't work: https://gist.github.com/890995 :)

14:41 amalloy: thorwil: nope, definitely not what i meant

14:41 zerokarmaleft: at any rate, my point was stick to ^ and ! if you're pulling fictionally ginormous big-oh functions out of thin air

14:44 joshua__: ended up writing my own html-to-markdown thingy for Clojure..

14:44 amalloy: (defmacro def-entity-and-attrs [entity-name slug attrs attr-name] `(do (def ~attr-name ~attrs) (defentity ~entity-name ~(vec (concat [slug] attrs))))) or something like that

14:44 joshua__: here is what it looks like having been run back and forth =) http://notepag.es/serG8H

14:46 fliebel: There is really no way you can sort a map by its values without having a reference to the map you're sorting, right? Which means that you need to re-sort the whole thing every time basically.

14:47 amalloy: fliebel: what?

14:47 oh, by its values

14:47 fliebel: amalloy: ##(doc sort-map-by) takes only keys, so to sort by the values, you need to get them from the map.

14:47 sexpbot: java.lang.Exception: Unable to resolve var: sort-map-by in this context

14:48 amalloy: fliebel: you can't really maintain a map sorted by value, no. that's an abomination

14:49 zakwilson: I use a function that gives you a vector of mapentries sorted by value. It's also possible to maintain an arraymap sorted by value, but not a very good idea.

14:50 amalloy: the reason maps are efficient is because you can do fast lookups by key. if you sort them according to value only, you either have a non-map that's slow to look up by key (not the worst thing ever) or a map that you can insert into slowly and look up by key quickly, but it doesn't matter because you seem to prefer lookup by value anyway?

14:50 kephale00: is unify in clojure 1.2.1?

14:50 Netfeed: unless you cheat and have something like [[:c 1] [:a 2] [:b 3]] :)

14:50 thorwil: amalloy: thanks! i suspect the critical part is (def ~attr-name ~attrs) to get around the runtime vs compile-time thing?

14:51 fliebel: amalloy: Maybe you are right… Maybe I can use a vector instead… ##(doc disj)

14:51 sexpbot: ⟹ "([set] [set key] [set key & ks]); disj[oin]. Returns a new set of the same (hashed/sorted) type, that does not contain key(s)."

14:51 amalloy: fliebel: can't disj in the middle of a vector

14:52 thorwil: no actually. that's just for your convenience so you can reuse the name later

14:52 the defentity still needs to use the literal that was passed in as a macro arg

14:52 fliebel: amalloy: sorted-set then… Something that can do this stuff but hasn't the keys

14:53 duncanm: i started enabling *warn-on-reflection*, but now I don't know how to hint an array of java.awt.Points

14:53 amalloy: chouser: these "manning" people are sending me a book, for some reason

14:53 ^"[Ljava.awt.Point" I think

14:53 tufflax: fliebel: maybe this interests you, i dunno http://clojure.github.com/clojure-contrib/branch-master/priority-map-api.html

14:53 amalloy: i think there's a more convenient way but that's the one i remember

14:53 duncanm: i have (let [points (into-array Point [(Point. 0 0) (Point. 0 w) (Point. h 0) (Point. h w)])] ...), I'd thought that'd be sufficient

14:54 fliebel: tufflax: Interesting, but I think I can get away with a set instead.

14:54 raek: kephale00: I think it's a separate project: https://github.com/clojure/core.unify

14:55 duncanm: [Ljava/awt/Point [Thrown class java.lang.ClassNotFoundException]

14:55 boo

14:56 oh, semicolon

14:58 fliebel: &(type (make-array java.awt.Point 3))

14:58 sexpbot: ⟹ [Ljava.awt.Point;

14:58 duncanm: fliebel: what does that mean?

14:59 fliebel: if it knows the type already, why do i get a reflection warning?

14:59 fliebel: duncanm: I think that code reflects, but than tells you what it found.

14:59 duncanm: ahh

15:00 kephale00: raek: ah, i was confused by the naming...

15:01 fliebel: But that isn't a readable type, clojure waits for me to typ the closing brackot for the vector

15:07 chouser: amalloy_: cool!

15:21 fliebel: How would I "XOR" a set? i.e. get the elements that are in one but not both sets. The best I can do is (union (difference 1 2) (difference 2 1))

15:26 amalloy: fliebel: (difference (union a b) (intersect a b)) seems clearer

15:27 * fliebel grinds gears

15:27 fliebel: yea

15:29 choffstein: hey all! quick question -- is there an easy way to use lein with rich hickey's sdb library?

15:29 if it is on clojars, it should be good, right?

15:30 dakrone: choffstein: https://github.com/richhickey/sdb/network

15:30 a few of the forks have work added to make them lein projects

15:30 take your pick

15:31 choffstein: awesome. thanks.

15:34 what is the best way to manage java libraries? For example, when I download the java sdk for amazon AWS, I just get a bunch of jars. Where is the best place to put them? (I'm on OSX)

15:36 gfrlog: my wife keeps her jars in the pantry

15:37 * gfrlog is immediately ashamed he said anything

15:37 fliebel: choffstein: Probably in your local maven repo

15:37 Raynes: I put all my jars in the cupboard.

15:37 choffstein: okay

15:37 fliebel: choffstein: That way you can use them as deps in lein and cake

15:38 TimMc: fliebel: Alternatively, (union (difference a b) (difference b a))

15:38 wait, nvm, you wrote that

15:38 choffstein: love clojure ... hate the old library dependency scheme from the C days

15:39 TimMc: choffstein: What would you have instead?

15:39 choffstein: A uniform package manager. Can't do it with the java dependency though.

15:39 Maven sort of works.

15:39 I just got spoiled by python's eggs and ruby's gems.

15:39 cemerick: choffstein: the AWS SDK is always in maven central

15:40 The problem with eggs and gems is that they require something like rvm or virtualenv

15:40 choffstein: cemerick: yep, they do.

15:40 cemerick: is it really? I just tried adding the sdb library to my lein project file and it couldn't find the AWS dep.

15:41 cemerick: which sdb library?

15:41 choffstein: org.clojars.bapehbe/sdb

15:41 cemerick: That's bizarre.

15:41 TimMc: I don't understand the security model with Maven. Is there one?

15:42 gfrlog: is it weird that ruby requires three separate components to manage dependencies well? RubyGems, RVM, & Bundler

15:42 I hadn't thought about it before

15:42 amalloy: TimMc: security?

15:42 cemerick: choffstein: FWIW, I forked that a while ago -- Rich's original sdb lib was a good spike, but there were some holes to be plugged IMO. https://github.com/cemerick/rummage

15:42 choffstein: gfrlog: Well, I think that only really happened when ruby 1.9 started rolling out

15:43 never really occurred in the days of Ruby 1.8

15:43 cemerick: </selfPromotion>

15:43 gfrlog: choffstein: what changed with 1.9?

15:43 amalloy: like, preventing someone sending you a different jar than you want?

15:43 TimMc: amalloy: If I upload com.microsoft/blarg to clojars...

15:43 amalloy: TimMc: clojars is a free for all

15:43 maven central is not

15:43 * gfrlog didn't know Microsoft had released a blarg library already

15:43 amalloy: gfrlog: you've never said "blarg" when you look at their code?

15:43 choffstein: gfrlog: basically, people had 1.8 projects and 1.9 projects. the code was different enough that if you were stuck on legacy, you needed gems that were 1.8 compatible -- so all of a sudden you needed different gem sets

15:43 TimMc: amalloy: You have to prove domain ownership?

15:43 cemerick: TimMc: The security model is that you want to ensure you're consuming signed jars and not pulling stuff from untrusted repos (like clojars).

15:44 gfrlog: amalloy: never looked at it ;-)

15:44 TimMc: Yeah, signing, that's the other thing.

15:44 gfrlog: choffstein: ah, that's sensible

15:44 TimMc: Does it work using SSL certs or something?

15:44 choffstein: gfrlog: then you had the different VMs coming out -- MacRuby, JRuby, Rubinius -- so you needed a different gemset depending on the VM you wanted to run

15:44 amalloy: TimMc: yes, that's how signing works

15:44 cemerick: TimMc: it grounds out against PGP keys

15:44 choffstein: cemerick: okay, i'll check out rummage. Thanks ;)

15:44 amalloy: cemerick: signed jars aren't that interesting if you're pulling the signature from the same place, at the same time, as the jars. right?

15:45 whoever spoofs the jars will spoof the signatures, and you don't have a more-trusted channel to verify against

15:45 gfrlog: amalloy: are you talking about the signature itself or the identity (public key) of the signature?

15:45 cemerick: amalloy: Yeah, if you care enough, you'll want to be checking things against a keystore backed by e.g. MIT or whereever else public PGP keys are held.

15:45 choffstein: cemerick: still getting an artifact missing for Java AWS library...

15:46 gfrlog: choffstein: u can haz good explinayshun

15:46 amalloy: gfrlog: either. if you don't check against a public keystore like cemerick says you're not getting any real security

15:46 pjstadig: well people can publish fake pgp keys to MIT or whereever else too

15:46 cemerick: choffstein: Odd. It's in maven central: http://mavencentral.sonatype.com/#artifactdetails|com.amazonaws|aws-java-sdk|1.1.5

15:46 gfrlog: amalloy: if you already have the public key, then getting the signature at the same time as the jar isn't a concern

15:47 pjstadig: the idea is to have a web of trust

15:47 gfrlog: i.e., isn't risky

15:47 pjstadig: have people who you trust to have signed the key used for the signature

15:47 and so forth

15:47 amalloy: gfrlog: do you have the public key for org.clojure handy?

15:47 gfrlog: amalloy: nope

15:48 amalloy: pjstadig: i'm aware of the "idea", but maven most of the time just fetches from maven central and hopes for the best. you need another channel if you actually worry about security (i don't, especially)

15:48 or you could have maven use https to do the fetching, and verify that it's coming from maven central. maybe it does that and i don't know

15:48 cemerick: There's two sensible paths: either only pull in artifacts from trusted repos (central, jboss, apache, etc), or never pull artifacts from the public internet, restricting artifacts to those available from your local/private maven repo.

15:49 The former is a sane balance IMO. The latter is done in a lot of security-conscious orgs, but can be a PITA.

15:49 gfrlog: "People for the Inethical Treatment of Animals"

15:49 amalloy: cemerick: or pull artifacts from anywhere and don't worry about security, which is what most do

15:50 cemerick: sure

15:50 Usually, it's obvious when you need to start being paranoid.

15:50 amalloy: i notice that cake deps fetches from an http:// url, not https://, so out of th ebox it's not really secure

15:51 cemerick: That's not where the worst trouble would come from.

15:51 amalloy: cemerick: it's one way

15:52 cemerick: Sure. Not as easy as having a spoofed (but functional) database library that ships all records retrieved to Uzbekistan.

15:52 amalloy: someone walks in and pretends to be maven central. they send me poisoned jars, whose signatures i don't really check against public keys because hey, they're from maven

15:52 cemerick: It's the random-repo-hosted-on-Google-Code that I'd really worry about.

15:53 amalloy: sure

15:53 cemerick: (this coming from the guy that blogged about hosting random repos on github) :-P

15:53 amalloy: hah

15:53 well, i added sun's repo to one of my projects. i hope i'm not going to hell

15:53 fliebel: Is there anything like deref that would do (deref 1) -> 1

15:54 brehaut: indentity ?

15:54 :P

15:54 amalloy: fliebel: if you don't mind using amalloy-utils, that function is called (transform-if #(instance? clojure.lang.IDeref %) deref)

15:55 fliebel: Maybe (keep identity (juxt identity deref) :D

15:55 only deref throws

15:55 amalloy: fliebel: hope you like exceptions in that case :P

15:58 choffstein: cemerick: ech. maybe I don't have maven central set up as a maven repo?

15:58 cemerick: choffstein: it's a default repo in both lein and maven

15:58 choffstein: well....crap

15:58 cemerick: can you download the artifact directly?

15:58 (i.e. click on the .jar file in the page I linked before)

15:58 choffstein: I have http://repo1.maven.org/maven2 as the only maven repo

15:59 cemerick: you don't need that, though it shouldn't hurt anything

15:59 amalloy: choffstein: are you sure that's the jar you're having trouble getting?

15:59 choffstein: Unable to resolve artifact: Missing:

15:59 ----------

15:59 amalloy: it might be failing to fetch one of its dependencies; mvn's error messages are hard to read

15:59 choffstein: 1) com.amazonaws:aws-java-sdk:jar:1.1.5

15:59 Whoops, sorry

15:59 Raynes: cemerick: And cake.

16:00 choffstein: i'll throw it in a gist

16:00 http://pastebin.com/SbZ9qdwN

16:01 cemerick: choffstein: try killing the extra central repo def?

16:02 choffstein: ?

16:02 amalloy: cemerick: extra?

16:02 cemerick: he said he had maven central mapped in, perhaps to "central"

16:02 choffstein: can you paste your project.clj?

16:02 amalloy: his gist shows exactly one central repo

16:03 choffstein: This is confusing. It is right there in the repo ... but doesn't want to be downloaded

16:05 Is it because the repo2 layout is different than what maven is expecting?

16:05 amalloy: no

16:06 plz take cemerick's advice and paste your project.clj as well just in case there's anything funky there, choffstein

16:06 choffstein: Oh, didn't see that advice. Sorry

16:06 amalloy: (too many dang cho- names in here. how can i be expected to tab-complete)

16:07 choffstein: http://pastebin.com/s850wHpj

16:07 yfinance, expojure, and smoothing are my own projects

16:07 i installed through "lein install"

16:07 cemerick: ok, so no explicit central repo, that's good

16:10 choffstein: i'm so confused.

16:11 fliebel: Can I extend-type for interfaces, or only protocols?

16:12 choffstein: ...this makes no sense what-so-ever.

16:12 amalloy: fliebel: you can extend protocols to interfaces. not sure i understand the question because i don't think that's what you're asking

16:12 cemerick: choffstein: after dropping the references to your personal projects, running lein deps here finishes without a problem.

16:13 choffstein: cemerick: oh ... let me try that

16:13 still fails for me

16:13 amalloy: fliebel: i see. that should work, yes

16:13 cemerick: I suspect there's something that's gone pear-shaped in your maven repo's metadata

16:14 choffstein: cemerick: I suspect that you are right!

16:14 amalloy: but i don't think you can extend-type for protocols at all, so maybe i still don't get it

16:14 cemerick: choffstein: try moving ~/.m2 to e.g. ~/.m3

16:14 amalloy: choffstein: rm -rf ~/.m2 maybe?

16:14 cemerick: you'll need to `lein self-install` again

16:14 choffstein: okay

16:14 heerrreeee we go

16:14 amalloy: cemerick's suggestion is better, of course, but if you never follow the advice of strangers that starts with rm -rf you're a chicken :)

16:15 choffstein: I play rm -rf roulette

16:15 really keeps work interesting

16:15 cemerick: blowing away local repos never *really* hurts, it'll just force you to redownload a bunch of stuff again

16:16 I'd always restrict it to ~/.m2/repo, so that settings.xml files and such aren't affected

16:16 choffstein: speaking of which, have you ever messed with ~/.m2/settings.xml?

16:16 choffstein: not that i'm aware of

16:16 cemerick: ok

16:16 amalloy: cemerick: maybe he downloaded a jar whose project has since been banned by the censors

16:17 fliebel: amalloy: Well, if I understand things correctly, when I define a protocol, I can use extend-type to make an implementation for an existing type. Can I do the same to interfaces?

16:18 What I want to do is make sets support assoc *evil grin*

16:18 amalloy: fliebel: no. interfaces participate in java's static inheritance hierarchy

16:18 fliebel: right

16:18 choffstein: Herm, I keep getting "bogus chunk size"

16:19 Downloading: com/amazonaws/aws-java-sdk/1.1.5/aws-java-sdk-1.1.5.jar from central

16:19 Bogus chunk size

16:19 cemerick: That's an HTTP chunked output error.

16:19 choffstein: maybe I should change my central repo for maven?

16:19 cemerick: Is your network wonky?

16:19 choffstein: cemerick: nope -- everything else downloaded fine

16:20 every other dependency was perfect

16:20 cemerick: well, you pulled a lot of other deps from central, too, it's not there just for the AWS stuff and such

16:20 amalloy: wow, it's like 1980s surfers are in charge of mvn dependencies: "whoa, gnarly. bogus chunk size, dudes"

16:21 cemerick: amalloy: that's an IOException message ;-)

16:21 amalloy: yeah i know

16:22 choffstein: cemerick: what do you mean? i know I pulled a lot of deps from central -- and they all worked fine

16:22 cemerick: choffstein: I mean that you don't want to try to mess with the mapping of the central repo, as it is the source for a lot of foundational stuff.

16:23 choffstein: cemerick: ah, gotcha. can I add another maven repo though?

16:23 cemerick: sure

16:23 choffstein: ...not that I have ANY idea how to do taht

16:23 what ... the ... hell

16:24 I don't even have a settings.xml file

16:30 * choffstein smashes his head against his keyboard

16:34 fliebel: Why! I defined hashCode on my defrecord, but it gives me a CompilerException java.lang.ClassFormatError: Duplicate method name&signature

16:35 hiredman: you have to use deftype if you want to define hashCode I believe

16:35 why would you do that though? the hashCode impl you get is perfectly fine

16:36 fliebel: hiredman: But then I lose all my dictatorship, right?

16:36 hiredman: fliebel: hmm?

16:36 * gfrlog types "huh?"

16:36 fliebel: hiredman: A deftype does not have these dict implementations.

16:36 technomancy: for the record, self-installs aren't in ~/.m2 anymore

16:37 hiredman: fliebel: correct, why do you want your own hashcode?

16:37 fliebel: hiredman: Because I want equality to mean a different thing.

16:37 gfrlog: ,(def = not=)

16:37 clojurebot: DENIED

16:38 hiredman: fliebel: but still be a map?

16:38 don't be silly

16:39 fliebel: hiredman: well, if I make it a deftype, can I do type/member?

16:40 I don't technically need all the map stuff, as long as I can get to the fields

16:41 duncanm: now that i have warn-on-reflection turned on, i noticed that clojure.pprint has a lot of unresolved calls

16:41 is it a goal for the next release to make all APIs that's part of distribution hinted so that everything can be resolved?

16:42 hiredman: duncanm: pretty printing shouldn't be done in any performance sensitive code

16:42 caring about reflection warnings implies caring about performance

16:45 choffstein: how can I add my local maven repo to lein?

16:46 dnolen: choffstein: it's already added.

16:46 choffstein: Herm. This makes no sense to me. I download the amazon aws jar sdk, install it with maven to my local maven repo, and lein still can't find it

16:50 gfrlog: ,(apply hash-map ((comp reverse flatten) {1 2 8 9 482 3 72 4}))

16:50 clojurebot: {}

16:50 gfrlog: ,(flatten {1 3})

16:50 clojurebot: ()

16:50 gfrlog: ,(apply hash-map ((comp reverse flatten seq) {1 2 8 9 482 3 72 4}))

16:50 clojurebot: {2 1, 3 482, 4 72, 9 8}

16:52 amalloy: gfrlog: clojure.walk/walk makes this fairly easy too

16:53 &(do (use 'clojure.walk) (walk (comp vec reverse) identity {1 2 8 9 482 3 72 4}))

16:53 sexpbot: ⟹ {2 1, 9 8, 3 482, 4 72}

16:53 gfrlog: woah; it walks maps?

16:53 amalloy: &(doc walk)

16:53 sexpbot: ⟹ "([inner outer form]); Traverses form, an arbitrary data structure. inner and outer are functions. Applies inner to each element of form, building up a data structure of the same type, then applies outer to the result. Recognizes all Clojure data structures except so... http://gist.github.com/891243

16:54 gfrlog: except so... except so many of them?

16:54 amalloy: *eyeroll* feel free to follow the gist link. it says sorted-foo-by

16:55 gfrlog: I know :)

16:55 amalloy: wouldn't it be great if repl languages did that with stack traces?

16:55 (the truncate-with-gist tactic)

16:55 I don't know how much of my life I've wasted scrolling up a stack trace

16:56 amalloy: i'm still a bit puzzled as to why walk is implemented as it is. it seems like it could be rewritten, and also support sorted-foo-by, to basically (outer (into (empty coll) (map inner coll)))

17:05 mec: would postwalk and prewalk still work with that?

17:06 phenom_: hey, anyone famliar with yourkit profiler ?

17:07 amalloy: mec: of course; my goal is to not change the output of walk in any noticeable way

17:07 clojurebot: anyone?

17:07 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.

17:07 mattmitchell: how do you check if a var has been bound to something?

17:08 amalloy: &(let [outer identity, inner (comp vec reverse) coll {1 2 8 9 482 3 72 4}] (outer (into (empty coll) (map inner coll))))

17:08 sexpbot: ⟹ {2 1, 9 8, 3 482, 4 72}

17:08 amalloy: mattmitchell: bound?, i think

17:09 mattmitchell: amalloy: that's it thanks :)

17:12 phenom_: argh, trying to debug but in YourKit the stack trace shows Thread.run() as 99% of CPU then the next step below is my function myns.myfunc as 33% !!!! where did tht 66% of time go !?!!?

17:13 mec: How do I truncate a number to int?

17:13 dnolen: phenom_: you can tell YourKit to ignore methods.

17:14 ,(int 4.3333)

17:14 clojurebot: 4

17:14 phenom_: dnolen: I want it to include more ... i seem to be missing functions that use up 66%, they dont show up

17:14 mec: ,(int 4023233417)

17:14 clojurebot: java.lang.ExceptionInInitializerError

17:26 krl: is there any way to have cyclical references between namespaces?

17:27 nickik: no i dont think so.

17:28 krl: is it really so strange?

17:29 nickik: I don't know of any language where it is possible, do you?

17:29 amalloy: nickik: a lot of languages

17:30 krl: common lisp

17:30 amalloy: java

17:30 phenom_: anyone know how to fix the issue I'm having with my agent pool? the wait/run cycle looks like it's not making optimum use of the pool: http://imgbin.org/index.php?page=image&id=3700

17:30 amalloy: i don't mind that clojure doesn't allow it, actually; it's a feature that can lead to messiness and wooly thinking

17:32 krl: i'm not sure if that merits banning it on non-technical grounds though. is it something in clojures design that really does not work with it, it can be fine. but yeah

17:32 i guess i'll have to see if i can break something out instead

17:32 nickik: amalloy, thx didn't no that because im avoiding it since I had the problem in C++

17:34 amalloy: nickik: works fine in c++ too. declare everything in headers, then implement it all in one big soupy mess

17:35 krl: it could be made to work, but it would have repercussions

17:40 krl: problem is that you don't really notice building circular stuff when using slime, since it seems to work fine until you try to reload the project

17:53 waxrose: ehh... I wonder why Joy of Clojure didn't get released to B&N today..

17:59 * gfrlog has always enjoyed perusing the Clojure aisle of B&N

18:01 amalloy: gfrlog: please forgive me the following pedantry: "peruse" means the opposite of "browse". it means "to study thoroughly and in depth"

18:02 waxrose: :P

18:02 gfrlog: amalloy: I cannot forgive. Only thank.

18:03 I should point out however, that my use has a plausible interpretation

18:03 amalloy: it does

18:03 gfrlog: $google wiktionary peruse

18:03 sexpbot: First out of 379 results is: peruse - Wiktionary

18:03 http://en.wiktionary.org/wiki/peruse

18:04 amalloy: in practice if i attack 100% of uses of the word peruse i have a 98% hit rate, so actually reading the usages is statistically a waste of time

18:04 gfrlog: amalloy: note wiktionary's definition #3 ;-)

18:05 what if computer languages were like human languages: misusing a function enough times changes its behavior

18:06 amalloy: gfrlog: that's because everyone on the internet is dumb :P. try something that can't be edited by some guy who realized that the "right" meaning still isn't in wiktionary

18:06 kephale00: gfrlog: thats what ai techniques are for

18:06 amalloy: i'm happy to see that a google search for "define: peruse" does very well, at least

18:06 every use but wiktionary gets it right

18:07 gfrlog: kephale00: very good

18:07 amalloy: http://www.merriam-webster.com/dictionary/peruse

18:07 1b

18:08 amalloy: sad

18:08 gfrlog: you must be a prescriptivist

18:08 amalloy: wait wtf does 2 even mean

18:08 "especially, to read attentively or leisurely"

18:08 gfrlog: it's true, i am

18:08 i sympathize with some non-prescriptive usages of things

18:09 gfrlog: amalloy: you oughta be put on an episode of "Scared Straight by Linguists"

18:13 amalloy: gfrlog: they would dig up dirt to discredit me

18:14 they would find out that i grew up saying "on accident" instead of "by accident" (by analogy with on purpose, apparently)

18:15 gfrlog: bet you don't like ending sentences prepositions with

18:15 amalloy: meh

18:16 every so often i make the effort, but there's no real reason to disallow it. unlike "using words to mean the opposite of what they mean", it doesn't hinder communication

18:16 gfrlog: :) how about 'cleave'?

18:18 amalloy: good word

18:20 gfrlog: ,(= [3] #{3})

18:20 clojurebot: false

18:20 gfrlog: ,(= [3] '(3))

18:20 clojurebot: true

18:21 gfrlog: (= #{3} '(3))

18:21 ,(= #{3} '(3))

18:21 clojurebot: false

18:21 gfrlog: I guess it makes sense

18:24 amalloy: &(map sequential? ((juxt set list* vec) [3]))

18:24 sexpbot: ⟹ (false true true)

18:32 gfrlog: (doc list*)

18:32 clojurebot: "([args] [a args] [a b args] [a b c args] [a b c d & more]); Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence."

18:32 gfrlog: couldn't bother to name that list-but-where-the-last-one-is-a-seq ?

18:34 amalloy: gfrlog: feel free to use ##(apply list [1]) instead

18:34 sexpbot: ⟹ (1)

18:34 gfrlog: list* is kind of like a general version of cons

18:34 amalloy: mhm

18:34 gfrlog: I guess the grandpa lispers would riot if the meaning of cons was changed though

18:34 amalloy: gfrlog: it already has been

18:35 gfrlog: dangit where did I put my torch?

18:35 amalloy: to what do you refer?

18:35 amalloy: (cons 1 2) is allowed in...every lisp but clojure afaik

18:35 gfrlog: ah

18:35 funny I hadn't tried that

18:36 amalloy: gfrlog: cons doesn't create pairs in clojure like in every other lisp: it creates a seq

18:36 so there's no "convention" of "a series of pairs ending in nil is a seq"

18:38 gfrlog: is the 'seq' concept particular to clojure?

18:38 brehaut: ,(type (cons 1 2))

18:38 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

18:38 brehaut: ,(type (cons 1 ())

18:38 clojurebot: EOF while reading

18:39 brehaut: ,(type (cons 1 ()))

18:39 clojurebot: clojure.lang.Cons

18:39 gfrlog: ,(type (cons 1 nil))

18:39 clojurebot: clojure.lang.PersistentList

18:40 gfrlog: \[({})]/ is the syntax for an empty finger-tree, right?

18:41 ,[({})]

18:41 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: PersistentArrayMap

18:42 gfrlog: ,[({},,\,)],

18:42 clojurebot: [nil]

18:42 gfrlog: ,[({}{})]

18:42 clojurebot: [nil]

18:44 amalloy: brehaut: you may be unaware, but sexpbot will fix mismatched parens for you :)

18:44 brehaut: amalloy: really? thats amazing!

18:45 amalloy: gfrlog: i think clojure takes it in a different direction than other lisps

18:45 brehaut: &(type (cons 1 ())

18:45 sexpbot: ⟹ clojure.lang.Cons ; Adjusted to (type (cons 1 ()))

18:45 brehaut: wow

18:45 Raynes: brehaut: You don't write code for sexpbot and then run off and use clojurebot. It's like a deal with the devil. You go back on it, and he gets your soul.

18:46 amalloy: Raynes: well, he specifically wrote *that* code, is the joke

18:46 brehaut: Raynes: its the seductive power of Arrows!

18:46 Raynes: amalloy: I got the joke.

18:46 gfrlog: Raynes: amalloy: when are either of you going to remove sexpbot's arrow so we can trampoline-quine the bots?

18:46 amalloy: Raynes: the channel as a whole probably didn't, in which case you come off sounding like a wacko zealot for real instead of as a joke

18:47 gfrlog: put that on the list of bugs to add

18:47 Raynes: amalloy: I don't have to say anything special to achieve that.

18:47 gfrlog: Nevers.

18:48 gfrlog: Raynes: okay well then hack into clojurebot and get it to respond to the arrow

18:48 Raynes: I am taking suggestions for a better arrow though. Tired of complaints about it not rendering well in people's ugly fonts.

18:48 gfrlog: Raynes: commas make good arrows

18:48 Raynes: :)

18:49 gfrlog: every time I see a comma I have to figure out what it's pointing at

18:49 it's real distracting

18:49 spewn: Raynes: What's the argument against the classic "->"?

18:49 amalloy: spewn: c'mon all the cool kids are doing unicode

18:49 brehaut: gfrlog: just FYI i was talking about arrows as per github.com/jduey/conduit

18:49 gfrlog: ,(let [-> :arrow] ->)

18:49 clojurebot: :arrow

18:50 * gfrlog not sure how he forgot that -> was already part of clojure

18:50 technomancy: clojurebot: arrows?

18:50 clojurebot: arrows is http://ro-che.info/ccc/12.html

18:50 Raynes: It's two characters and isn't unicode.

18:50 amalloy: Raynes: well. it's clearly unicode

18:50 spewn: I thought that was part of the problem ("not rendering well in people's ugly fonts").

18:51 gfrlog: presumably he thinks there is another character in unicode that renders better. Good luck finding another unicode character. I think it's just that arrow and nothing else.

18:52 amalloy: &(map char (repeatedly 4 #(rand-int 0x0800 0xefff)))

18:52 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (2) passed to: core$rand-int

18:52 Raynes: gfrlog: There are like a million unicode arrows.

18:53 Some long, some short, some wide, some thin.

18:53 This arrow is supposedly 'long', but it renders short in my font.

18:53 amalloy: We still haven't fixed the logs so that the arrow shows up properly, have we?

18:53 gfrlog: Raynes: I've actually spent an above average amount of time staring at unicode arrows. I wasn't satisfied.

18:54 Raynes: amalloy: ##(doc rand-int)

18:54 sexpbot: ⟹ "([n]); Returns a random integer between 0 (inclusive) and n (exclusive)."

18:55 * amalloy is just still annoyed it doesn't have a min argument

18:55 Raynes: Chirp.

18:55 gfrlog: &(map char (repeatedly 20 #(+ 0x0800 (rand-int (- 0xefff 0x0800)))))

18:55 sexpbot: java.lang.NullPointerException

18:56 Raynes: Oh, wow, lag.

18:56 I think I've broke my internet.

18:56 amalloy: null pointer? that's a weird one to get

18:57 __name__: I blame Oracle.

18:57 gfrlog: I don't think the unicode space is all filled in

18:58 &(map char (take 20 (filter identity (repeatedly (try (+ 0x0800 (rand-int (- 0xefff 0x0800))) (catch Exception e nil

18:58 sexpbot: java.lang.SecurityException: You tripped the alarm! catch is bad!

18:59 gfrlog: BAH

18:59 Raynes: DENIED

18:59 gfrlog: is there a built in fn for swallowing exceptions?

19:00 amalloy: gfrlog: having unicode be "not all filled in" wouldn't give an NPE

19:00 gfrlog: amalloy: then what should calling char on an invalid integer return?

19:00 amalloy: furthermore it's so filled in that it doesn't all fit in the two bytes java allocated for it

19:01 gfrlog: there is no such thing as an invalid integer. it returns a Character object representing that integer. if its name is NOT_FILLED_IN and your irc client can't render the glyph associated with it, why does java care?

19:01 &(char 0xf555)

19:01 sexpbot: ⟹ \

19:02 Cozey: Hello. If i have a vector in an atom X, which itself contains atoms Yi, is it safe to modify them with (swap! X (fn [yi] (swap! yi .... )) ? Docs say swap! functions should not have side effects, but inner swap! yi would be a side effect. am I right? Is this a job for refs and dosync?

19:02 gfrlog: amalloy: I guess it doesn't

19:02 amalloy: Cozey: uh, if you really want to do it then yes, use refs. srsly though don't put atoms inside atoms

19:03 (or refs inside refs, or refs inside atoms, or...)

19:03 gfrlog: I keep my atoms inside refs of agents

19:03 Cozey: :-)

19:03 gfrlog: ,(atom {(ref (agent)) (agent (ref))})

19:03 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$agent

19:04 gfrlog: ,(atom {(ref (agent (var agent))) (agent (ref (var ref)))})

19:04 clojurebot: #<Atom@59bb55: {#<Ref@1545a38: #<Agent@3483ec: #'clojure.core/agent>> #<Agent@1c119d5: #<Ref@86fd2f: #'clojure.core/ref>>}>

19:05 gfrlog: I encode all my data in a form of binary where 0 is represented as the empty set, and 1 is represented as that structure up there

19:05 amalloy: gfrlog: i'm starting to get the idea i should stop asking you about Best Practices

19:06 gfrlog: it's okay, I wrap it all in a try-catch

19:06 amalloy: well played

19:06 gfrlog: :)

19:07 * gfrlog should keep his thoughts to himself when people pop in for questions

19:32 choffstein: cemerick: you around? I have a question about rummage (and maybe SimpleDB)

19:44 gfrlog: &((({{}{}}{}{}){}{}){}{})

19:44 sexpbot: ⟹ {}

19:46 flying_sheep: Hi, how should I print a lazy-seq to stdout, and format it?

19:47 gfrlog: ,(prn (map inc (range 10)))

19:47 clojurebot: (1 2 3 4 5 6 7 8 9 10)

19:47 flying_sheep: I use doseq to materialize the lazy-seq, but then I don't know how to format the output

19:47 kephale00: you might want pprint too

19:47 gfrlog: yeah I was going to say that

19:47 flying_sheep: oooo shiny ...

19:53 TimMc: gfrlog: Woah, I had no idea maps had an arity-2 invoke as well!

19:53 pdk: ({1 2} 3 :hi)

19:53 ,({1 2} 3 :hi)

19:53 clojurebot: :hi

19:53 pdk: BRILLIANT

19:54 TimMc: THIS CHANGES EVERYTHING

19:54 pdk: ,(#{1 2} 3)

19:54 clojurebot: nil

19:54 pdk: ,(#{1 2} 3 :hi)

19:54 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (2) passed to: PersistentHashSet

19:54 pdk: sets gotta spoil all the fun

19:55 TimMc: ,({5 nil} 5 6)

19:55 clojurebot: nil

19:55 TimMc: excellent

19:55 ,({5 nil} 'a)

19:55 clojurebot: nil

19:56 pdk: actually yknow

19:56 i never looked into whether vecs have a getter syntax like this

19:56 ,([1 2 3] 1)

19:56 clojurebot: 2

19:56 pdk: \o/

19:56 i'll assume () lists don't

19:57 though either way

19:57 i don't see why sets wouldn't

19:58 TimMc: ,([0 1 2] 3 7)

19:58 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (2) passed to: PersistentVector

19:59 pdk: conclusion

19:59 maps = daddy's favorite collections!

20:05 amalloy: pdk: keywords and symbols too

20:05 &(:foo {:bar 10} 20)

20:05 sexpbot: ⟹ 20

20:05 amalloy: &(:foo #{:bar 10} 20)

20:05 sexpbot: ⟹ 20

20:05 pdk: what do we make of the keyword/symbol examples

20:05 amalloy: so you don't need the set one :P

20:05 pdk: oh yeah

20:06 poor sets don't get to be at the front of forms

20:06 ,([1 2 3 #{4}] #{4})

20:06 clojurebot: java.lang.IllegalArgumentException: Key must be integer

20:06 pdk: wait no

20:06 ,({1 2 3 #{4}} #{4})

20:06 clojurebot: nil

20:06 amalloy: still not a set at the front :P

20:07 pdk: ,(#{1 2 3 #{4}} #{4})

20:07 clojurebot: #{4}

20:07 pdk: ,(#{4} #{1 2 3 #{4}})

20:07 clojurebot: nil

20:07 pdk: welp

20:10 amalloy: &(instance? clojure.lang.IAssoc #{})

20:10 sexpbot: java.lang.ClassNotFoundException: clojure.lang.IAssoc

20:10 amalloy: &(instance? clojure.lang.ILookup #{})

20:10 sexpbot: ⟹ false

20:10 clojurebot: I don't understand.

20:25 mec: How could I do a variable partition such that: (partition [1 2 3 4 5 6 7 8 9] [1 2 3 2 1]) -> [[1] [2 3] [4 5 6] [7 8] [9])

20:26 brehaut: mec the second vector describes the partition sizes?

20:26 mec: brehaut: correct

20:27 brehaut: that should be the first argument i think

20:27 (the rest of the partition family (like all the seq fns) take the sequence as the last argument

20:27 mec: ok

20:28 I'm thinking some way to iterate split-at would work, but im not sure how to do that

20:29 brehaut: unfold would be perfect

20:33 tomoj: would it?

20:34 with a fn of type ([a], [Int]) -> Maybe ([a], [Int])?

20:34 er

20:34 brehaut: yes

20:34 mec: https://gist.github.com/891606

20:34 tomoj: ([a], [Int]) -> Maybe ([a], ([a], [Int]))

20:34 mec: hows that look?

20:35 tomoj: too eager

20:36 mec: hmm

20:37 brehaut: TBH i think i would write it wilth lazy-seq and recur

20:37 hiredman: recur?

20:38 brehaut: tail recursive function?

20:38 hiredman: mixing recur and lazy-seq just strikes as odd

20:38 brehaut: oh yeah. duh. excuse my brain failure

20:38 mec: ok i think i got it

20:39 https://gist.github.com/891606 thats almost beautiful

20:40 hmm I should probably limit it on both of them

20:41 is there a better way than using 2 when-lets?

20:42 brehaut: maybe-m or -?> ?

20:43 im not convinced they payoff till you hit 3 or 4 when-lets though

20:43 mec: so just use 2?

20:43 brehaut: yeah

20:43 tomoj: :/ ##(->> [1 2 3 2 1] (reductions (fn [[_ coll] part] (split-at part coll)) [nil (range 10)]) next (map first) (take-while identity))

20:43 sexpbot: ⟹ ((0) (1 2) (3 4 5) (6 7) (8))

20:44 tomoj: should be (take-while seq)

20:44 brehaut: ,'do-monad

20:44 clojurebot: do-monad

20:44 brehaut: not what i meant

20:44 ,#'do-monad

20:44 clojurebot: java.lang.Exception: Unable to resolve var: do-monad in this context

20:45 brehaut: ,#'domonad

20:45 clojurebot: java.lang.Exception: Unable to resolve var: domonad in this context

20:45 brehaut: ,(use 'clojure.contrib.monads)

20:45 clojurebot: nil

20:45 brehaut: the following is why maybe-m is overkill:

20:45 ,(macroexpand '(domonad maybe-m [a (when true 1) b (inc a)] (inc b)))

20:46 clojurebot: (let* [name__2462__auto__ maybe-m m-bind (:m-bind name__2462__auto__) m-result (:m-result name__2462__auto__) m-zero (:m-zero name__2462__auto__) m-plus (:m-plus name__2462__auto__)] (clojure.contrib.macro-utils/with-symbol-macros (m-bind (when true 1) (fn [a] (m-bind # #)))))

20:47 brehaut: mec: ie it explodes in complexity and nested calls

20:47 waxrose: -_-

20:47 mec: ya im just using a let and a when :D

20:48 tomoj: oh i completely forgot about reductions

20:50 tomoj: brehaut: is that just an ugly version of unfold?

20:51 kind of interesting if unfold is the intermediate steps of a fold

20:51 clojurebot: Ik begrijp

20:51 mec: tomoj: maybe-m is like nil safe threading

20:51 tomoj: I meant my reductions thing above

20:53 mec: I believe so

20:58 ok which looks best https://gist.github.com/891606

21:00 amalloy: mec: i like the second, but it's not lazy

21:01 brehaut: tomoj: sorry, is what the ugly version of unfold?

21:03 tomoj: oh right. yeah roughly

21:09 amalloy: tomoj: https://gist.github.com/805583 is my unfold, if you'd like to compare

21:18 mec: I cant get partitions to work using unfold

21:23 gfrlog: $findfn #{3 4} 4 #{3}

21:23 sexpbot: [clojure.core/disj]

21:23 gfrlog: $findfn [3 4] 4 [3]

21:23 sexpbot: []

21:24 gfrlog: conj has no inverse

21:24 mec: oh whats the complement of every?

21:24 gfrlog: not-any?

21:24 amalloy: not-any?

21:24 gfrlog: $findfn [3 4] [3]

21:24 sexpbot: [clojure.core/butlast clojure.core/drop-last clojure.core/pop]

21:25 mec: amalloy: using your fold, this is only returning the first 4: https://gist.github.com/891606

21:26 amalloy: what do you mean, the first four?

21:27 mec: ((1) (2 3) (4 5 6) (7 8)) instead of ((1) (2 3) (4 5 6) (7 8) (9))

21:28 amalloy: hm, my version is doing that too, now that i've stopped writing it stupidly

21:29 gfrlog: (group-by #(apply + %) '((1) (2 3) (4 5 6) (7 8) (9)))

21:29 brehaut: mec, you can define partitions as (comp (partial unfold ...) vector) ;)

21:29 amalloy: likewise

21:30 mec: huh?

21:30 amalloy: he thinks it's undignified to build vectors by hand. don't listen to him

21:30 mec: ah i see

21:30 brehaut: (def partitions (comp (partial unfold (fn [[[n & sizes] coll]] [(take n coll) [sizes (drop n coll)]]) (partial not-any? seq)) vector))

21:31 mec: still truncates the last value :D

21:31 brehaut: mec yeah it does :(

21:31 mec: I think that has to do with the test

21:32 amalloy: i wrote my test as (comp empty? second)

21:32 same problem

21:32 (cause i have mine in the other order)

21:35 mec: confirmed it's either a problem with unfold or with the test, though; using (constantly false) as the done? test and then taking 5 works

21:36 mec: thats what I was thinking would have to be done

21:36 amalloy: mec: it looks like a problem with my unfold, now that i look at it

21:37 mec: It's weird, because I've used your unfold perfectly fine before

21:38 amalloy: mec: i think the issue is that (next the-seed) returns a pair, [data new-seed], okay? then the take-while checks to see that new-seed has no more data, so it doesn't include even that data element

21:38 i think i should just rewrite unfold with raw lazy-seq; it'll probably be more readable as well as more reliable

21:39 mec: true, I do like the partitions with lazy-seq the best

21:39 It's easiest to understand, tho I'm working on a when-lets macro for it :D

21:41 cgray: hi, in compojure, how does one alter the session? do you treat it like a ref?

21:41 amalloy: mec: the lazy-seq version of unfold, predictably, was trivial to write and works properly

21:41 one sec and i'll amend the gist

21:43 https://gist.github.com/805583 has a more-working unfold now

21:44 mec: very nice. How do you determine where lazy-seq should go?

21:48 amalloy: mec: pretty much always as far in-front as you can fit it

21:51 mec: basically when i'm writing a lazy-seq function it usually looks like (defn foo [foo bar baz] ((fn foo* [arg more-args] (lazy-seq ...)) (some intitial args from foo bar baz)))

21:51 mec: ok

21:55 tomoj: ah, i

21:55 er. I wouldn't have guessed unfold would need the extra param

21:55 amalloy: tomoj: which extra param?

21:55 tomoj: next and done? because no Maybe

21:56 amalloy: yeah

21:56 tomoj: never thought much about how type clutter can reduce code clutter

22:05 cgray: anyone use ring's session middleware with compojure? I'm having trouble figuring it out...

22:05 mec: how does this look: when-lets https://gist.github.com/891691

22:08 amalloy: mec: when-lets looks like it should be implemented using reduce

22:08 kumarshantanu: hi, given a vector [:a :b :c :d :e] how can i replace 2nd element with :Z so that the result becomes [:a :Z :c :d :e] ?

22:08 mec: I'm a total noob at macros, I'm amazed I got it working at all, I'm not sure how to do that

22:09 amalloy: &(assoc [1 2 3 4] 1 :Z)

22:09 sexpbot: ⟹ [1 :Z 3 4]

22:09 kumarshantanu: amalloy: thanks!

22:11 mec: amalloy: ok I think I have an idea

22:11 amalloy: (reduce (fn [acc tstform] `(when-let ~tstform ~acc)) (reverse bindings)) looks like a good sketch

22:13 no_mind: I am confused about use of apply , when should one use apply and when should you rely on looping constructs ?

22:14 mec: use apply when the function supports it

22:15 amalloy: no_mind: yeah, they're different things entirely

22:15 mec: https://gist.github.com/891697

22:16 no_mind: amalloy, ok, someone explain me apply then

22:16 amalloy: no_mind: more specifically, apply is for calling functions when you have an argument list instead of a bunch of arguments

22:16 map is a looping-like function for calling some function on each element of a sequence

22:16 mec: your version may actually be easier to follow and/or better

22:17 but it seemed like basically a reduce so i wrote it up as one

22:17 mec: how about this one https://gist.github.com/891691

22:18 amalloy: ugh do not use 'when-let in a macro. the user might have excluded clojure.core from his refers, or given it a different alias

22:18 syntax-quote takes care of it for you

22:18 at least use `when-let

22:19 (it's safe with 'do, because that's a special form, but maybe i shouldn't anyway)

22:20 but otherwise sure, looks like a good way to expand, haha, your macro experience

22:20 mec: oh ok, would (fn [acc formtst] `(when-let ~formtst ~@acc)) work

22:21 amalloy: mec: it would, but then you need to turn formtst into a vector, which is why mine has map vec

22:21 mec: ya I did that initially

22:21 amalloy: maybe `(when-let ~(vec formtst))

22:23 mec: https://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils/macro.clj has some stuff like this

22:24 mec: amalloy: thanks

22:25 amalloy: i guess i should promote unfold into amalloy-utils now that amalloy-utils exists :P

22:26 gfrlog: amalloy: short name: auts

22:26 amalloy: what, and risk letting people forget my name?

22:26 gfrlog: yollama

22:27 ah that's where you got it from

22:27 no_mind: amalloy, I have an argument list (a map) and I want to call a function on the whole list but one element (a map key) How do I do it. To be more precise I am calling function like (apply set-attr (apply concat value)) where value is a map. For a given requirement, I want to pass all but one keys of the map can I do this without removing the key from map ?

22:28 gfrlog: no_mind: maps are immutable, so it's okay to remove something from them

22:29 mec: (apply set-attr (apply concat (dissoc value bad-key))

22:30 gfrlog: yep

22:30 (the original map still has the key in it)

22:53 pdk: no_mind clojure's basic data types/collections are all immutable and persistent

22:54 if you do an operation on them you just get a copy with the changes applied, the original is still there as long as you have a reference to it

22:58 amalloy: brehaut: i've found myself wanting foldr twice in the last week or two. never thought i'd want a fold that could blow the stack, but for use in creating macroexpansions it's not such a big deal

23:03 chouser: amalloy: that's really interesting.

23:05 amalloy: you've written foldr?

23:11 I'd be awfully tempted to pour the data into a vector first.

23:14 Hm, I suppose 'reverse' would be sufficient.

23:23 Guest51360: I want to destructure a value of a map within a map.. so I tried this in a let: {name :name, unit #(:unit (:quantity %))} but that doesn't seem to work (I thought maybe the destructuring bind was expecting a function of a single argument). Any thought on that ?

23:24 brehaut: Guest51360: the LHS of a destructuring expression has to be all literals

23:25 you'd need to break out the computation into a separate binding in the let.

23:25 dnolen: ,(let [{{bar :bar} :foo} {:foo {:bar 'baz}}] bar)

23:25 clojurebot: baz

23:26 waxrose: eeh

23:27 chouser: & user=> (let [{name :name, {unit :unit} :quantity} {:name "foo", :quantity {:unit "meters"}}] [name unit])

23:27 sexpbot: java.lang.Exception: Unable to resolve symbol: user=> in this context

23:27 chouser: sorry. ## (let [{name :name, {unit :unit} :quantity} {:name "foo", :quantity {:unit "meters"}}] [name unit])

23:27 sexpbot: ⟹ ["foo" "meters"]

23:27 chouser: just like dnolen said. :-)

23:28 Guest51360: nice, thanks all

23:37 simard: what is the idiomatic way of naming function arguments that expect a struct of some kind ?

23:38 amalloy: simard: name them something that describes what they're used for, like anything else :P

23:39 or if you want to be explicit about what keys they'll have, destructure them in the arglists directly: (fn [{:keys [year month date]}] ...)

23:48 jweiss_: is there a way to do "if f throws Exception return x otherwise return whatever f returns" without using an atom?

23:49 or i suppose just a plain elegant way

23:50 amalloy: well, not an especially elegant way

23:50 brehaut: jweiss: ##[(try (/ 1 1) (catch Exception e :boom)) (try (/ 1 0) (catch Exception e :boom))]

23:50 sexpbot: java.lang.SecurityException: You tripped the alarm! catch is bad!

23:50 brehaut: le sigh

23:51 ,(try (/ 1 0) (catch Exception e :boom))

23:51 clojurebot: brehaut: excusez-moi

23:51 amalloy: brehaut: they don't like catch, for good reason

23:51 brehaut: really?

23:51 why?

23:51 clojurebot: http://clojure.org/rationale

23:51 brehaut: thanks clojurebot

23:51 jweiss_: lol

23:51 amalloy: brehaut: imagine they caught the timeout/interruption exception

23:51 &(loop [] (recur))

23:52 inside of that loop

23:52 brehaut: i hadnt realised that would have come from within the evaluated expression

23:52 sexpbot: Execution Timed Out!

23:52 amalloy: it has to

23:52 sorta :P

23:54 brehaut: jweiss: anyway, i dont understand what you want that isnt handled by try catch

23:54 jweiss_: brehaut: maybe i'm confusing this use-case with a different one

Logging service provided by n01se.net