#clojure log - May 30 2010

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

1:04 hiredman: ,(+ 1 2)

1:04 clojurebot: 3

1:05 hiredman: (doc map)

1:05 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

1:20 defn: mmmm map

1:24 KirinDave: I think I am finally starting to understand how protocols are meant to be used.

3:15 vIkSiT: hmm, could anyone explain the concept of currying?

3:15 and how one does it in clojure?

3:16 vegai: it's partial application

3:17 if you have a function f that takes two parameters, you can bind the first parameter and get a new function that takes the remaining parameter

3:18 let's say sum function f(x,y)=x+y, you can get an inc from that by g(y)=f(1,y)=y+1

3:18 vIkSiT: vegai, right. I think I understand that - but I still don't know why it would be used. One thing I can think of is to eliminate anonymous functions?

3:18 vegai: dunno exactly how it works in clojure

3:19 it allows an additional form of abstraction. IMHO, not a very important one, but Haskellists seem to enjoy it

3:19 yeah, it's kind of a shortcut for some lambda forms

3:20 vIkSiT: ah

3:20 looks like js has a curry function too, and it seems applicable in prototype.js

4:28 argh

4:28 how do i break an infinite loop using slime/emacs?

4:28 LauJensen: ,q

4:28 clojurebot: java.lang.Exception: Unable to resolve symbol: q in this context

4:29 vIkSiT: LauJensen, ?

4:31 Raynes: Not sure he was answering your question.

4:32 vIkSiT: aah.

4:32 hmm, i'm sure there must be a way

4:32 hoeck: vIkSiT: ctrl-c or ctrl-g

4:33 vIkSiT: okay, so perhaps someone can help me out with the problem. trying to do : a function f that takes a list [1 2 3 4], and returns all sublists formed by removing successive elements..

4:33 * hoeck presses those keys in panic when he encounters a infinite loop on the repl, not being shure which one works

4:33 vIkSiT: so (f [1 2 3 4] should give me [1 2 3 4] [2 3 4] [3 4] [4]

4:33 hoeck, :) will try

4:33 Raynes: That wont work.

4:34 hoeck: ,(reductions pop [1 2 3 4])

4:34 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$pop

4:37 hoeck: ,(reductions (fn [c _] (next c)) [1 2 3 4] [1 2 3 4])

4:37 clojurebot: ([1 2 3 4] (2 3 4) (3 4) (4) nil)

4:37 vIkSiT: hmm, how does that work exactly?

4:38 hoeck: reductions is like reduce, but it returns intermediary results

4:39 vIkSiT: ah

4:39 also what is the fn [c _] doing?

4:39 why not just fn [c]?

4:39 hoeck: it ignores the second argument, therefor the idiomatic underscore

4:39 Raynes: Because the function needs to take two arguments.

4:40 vIkSiT: ,(doc reductions)

4:40 clojurebot: "([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."

4:40 hoeck: basically thing reduces a sequence to nothing, because were only interested in the intermediate results

4:41 vIkSiT: hmm tying to understand why that function needs 2 args

4:41 LauJensen: vIkSiT: What I meant was, that if the SLIME buffer hangs in a loop, ",q" will quit it

4:42 hoeck: normally, you want reduce to do something useful, like (reduce + '(1 2 3))

4:42 or (reductions + [1 2 3])

4:42 vIkSiT: hoeck, right

4:43 hoeck: but you are only interested in the intermediate steps of "eating" a sequence

4:43 vIkSiT: aaaah

4:43 gotcha.. the second arg is never used

4:43 hoeck: ,(next [1 2 3 4]

4:43 clojurebot: EOF while reading

4:43 vIkSiT: its just a placeholder

4:43 hoeck: ,(next [1 2 3 4])

4:43 clojurebot: (2 3 4)

4:43 hoeck: ,(next [1 2 3])

4:43 clojurebot: (2 3)

4:43 Raynes: In your case, the second arg is never used.

4:43 hoeck: and so on - right

4:43 vIkSiT: right, i understand now

4:43 Raynes: But in the case of (reductions + [1 2 3 4]), the second arg is being used.

4:43 vIkSiT: so, what would be the idiomatic functional way of doing this?

4:43 I was trying to do a loop recur version of this and hitting the inf loop

4:44 hoeck: since reductions is in core now, I guess its idomatic and functional, its even lazy :P

4:46 ,(map #(nthnext [1 2 3 4] %1) (range 4))

4:46 clojurebot: ((1 2 3 4) (2 3 4) (3 4) (4))

4:47 vIkSiT: LauJensen, btw, i didn't wnat to close the slime buffer itself. i was just hoping to break the loop without having to close the buffer itself..

4:47 hoeck: works too, but only for vectors, not for lists

4:47 vIkSiT: hmm

4:48 * hoeck just confirmed that c-c c-c in slime kills the currently executing repl thread

4:48 vIkSiT: ah thanks, let me check that

4:48 http://paste.lisp.org/display/110963

4:48 i'm tryhing to do something like that

4:49 hoeck, re the generating sequences bit

4:51 any suggestions on how that would/should work?

4:51 hoeck: (recur (next c)) instead of (recur (next coll))

4:53 and instead of (zero? (count c)), use (empty? c)

4:54 vIkSiT: hoeck, ah, but the point i'm still stuck at is - how do i recur AND use conj to build the sequence?

4:54 usually the recur examples happen like : (recur (dec n) (* factorial n)))))

4:54 where n is being decremented

4:54 but in my case - i'd like to pass in a seq

4:55 hoeck: see http://paste.lisp.org/display/110963#1

4:57 vIkSiT: hoeck, ah interesting. whats the <computed value> part about?

5:00 hoeck: there, you place your value

5:01 vIkSiT: hoeck, not sure i understand

5:01 hoeck: vIkSiT: http://paste.lisp.org/display/110963#2

5:03 vIkSiT: oh. does this imply that during a recur, a (next c) is actually passing the next into the recur form?

5:03 so in that line : (next c) (conj ret c), c is now (next c). It got modified

5:04 Chousuke: vIkSiT: it didn't get modified, it gets rebound

5:04 vIkSiT: ah I see

5:05 Chousuke: it kind of appears to be the same thing though, but since Clojure is a functional language, it's good to keep the terminology separate

5:23 vIkSiT: Chousuke, agreed

5:23 brb

5:48 pastorn: Raynes: hello :D

5:48 Raynes: pastorn: Ohai.

5:48 :D

6:00 naeu: what's the easiest way to call functions A and B 1000 times each in parallel?

6:06 Chousuke: (future (dotimes [i 1000] (a))), repeat for b?

6:06 naeu: oh, interesting, I hadn't considered futures

6:07 I was just looking at the following: (pcalls #(dotimes [_ 1000] (a)) #(dotimes [_1000] (b)))

6:08 Chousuke: (doc pcalls)

6:08 clojurebot: "([& fns]); Executes the no-arg fns in parallel, returning a lazy sequence of their values"

6:08 Chousuke: I had forgotten that entirely :P

6:11 naeu: looks pretty nifty :-)

7:32 Lajla: Chousuke, Se Lexx on fallinen.

7:47 _na_ka_na_: Q: I just learnt that calling (seq coll) where coll is itself a lazy-seq would realize the 1st element of coll. Any clues why seq was chosen to behave this way, it must have some other utility??

7:48 OForero: I am having some issues trying to run circumspec tests

7:48 http://paste.pocoo.org/show/219948/

7:49 I used the scripts from labrepl that appear to work

7:49 any ideas?

10:59 defn: is it possible to destructure over a coll?

10:59 nevermind im thinking backwards i think

10:59 Raynes: defn: As long as you aren't thinking sideways.

11:00 defn: :)

11:01 I have something like (let [[[k v]]] '(("a" "b") ("c" "d")) {k v})

11:01 which embodies what im trying to do, but id like to apply that to all of the items in a coll, not just the first element

11:02 ,(let [[[k v]] '(("a" "b"), ("c" "d"))] {k v})

11:02 clojurebot: {"a" "b"}

11:05 dnolen: ,(into {} (map vec '(("a" "b") ("c" "d"))))

11:05 clojurebot: {"a" "b", "c" "d"}

11:05 defn: dnolen: thanks

11:35 _na_ka_na_: anyone know what fn* is? in source lazy-seq

11:36 Borkdude: Is there an easier way to accomplish this, e.g. without force-set? http://gist.github.com/419108

11:40 alexyk: is there a blog aggregator for clojure blogs one can submit his to?

11:40 Borkdude: alexyk: there was http://clojure.in/ I thought, but now it says: coming soon

11:40 eevar: http://www.reddit.com/r/clojure ?

11:42 joshua-choi: _na_ka_na_: fn*, I believe, is a special form of Clojure that you don't have to care about. Its purpose is to provide the base implementation of the clojure.core/fn macro.

11:43 _na_ka_na_: joshua-choi: ok so for all purposes (example understanding source) I may assume its same as fn?

11:43 joshua-choi: Very similar. Not exactly the same in arguments, maybe.

11:43 Look at what clojure.core/fn does in terms of fn*.

11:49 _na_ka_na_: Borkdude: (reduce (fn [m [k v]] (assoc m k (conj (m k #{}) v))) {} (concat {:a 1 :b 2} {:a 1 :b 3}))

11:53 Borkdude: _na_ka_na, my purpose was to provide a fn to merge-with, sorry I didn't made that clear

11:53 but maybe there was already smth in Clojure like force-set

11:54 ,(merge-with (fn [r l] (if (set? r) (conj r l) (conj #{} r l))) {:a 1 :b 2} {:a 1 :b 3})

11:54 clojurebot: {:a #{1}, :b #{2 3}}

12:03 _na_ka_na_: i once saw a uml kind class diagram for the java source of clojure .. anyone knows where to get the most updated version of that ?

12:03 replaca: ,(merge-with (fn [r l] (if (set? r) (conj r l) (conj #{} r l))) {:a 1 :b 2} {:a 1 :b 3 :c 5})

12:03 clojurebot: {:c 5, :a #{1}, :b #{2 3}}

12:04 joshua-choi: _na_ka_na_: There's a chart for Clojure's core classes and interfaces.

12:04 replaca: but that's not so satisfying

12:05 _na_ka_na_: joshua-choi: link?

12:06 joshua-choi: _na_ka_na_: It was on among the Google group's files, but I couldn't find it there. It's at here too though: http://bc.tech.coop/blog/081108.html

12:37 Licenser: (doc partition-all)

12:37 clojurebot: "([n coll] [n step coll]); Returns a lazy sequence of lists like partition, but may include partitions with fewer than n items at the end."

12:38 Licenser: (partition-all 1 (range 10))

12:38 ,(partition-all 1 (range 10))

12:38 clojurebot: ((0) (1) (2) (3) (4) (5) (6) (7) (8) (9))

12:43 pdk: testing

13:04 Borkdude: replaca: right

14:14 raek: _na_ka_na_: saw your unaswered question from some hours ago. (seq coll) have to realize the first element in order to know whether it should return nil or not

14:14 (seq coll) always return nil if there are no elements

14:50 krumholt: hi. i am looking for a way to apply a function exactly n times. example: (bar 5 foo arg) would be (foo (foo (foo (foo (foo arg)))))

14:56 Raynes: technomancy: Pingy.

14:58 hoeck: ,(first (drop 5 (iterate - 1)))

14:58 clojurebot: -1

14:58 hoeck: krumholt: ^

14:59 LauJensen: hoeck: perhaps 'take' would be better than 'drop'

14:59 krumholt: hm ok i coud do nth too right?

14:59 LauJensen: yea

15:00 krumholt: ok thanks

15:00 hoeck: LauJensen: I assumed he is interested in the sixth function application, not the whole seq of intermediate results

15:01 or (reduce (fn [a _] (- a)) (- 1) (range 0 6))

15:01 LauJensen: hoeck: Ok - He said 'I need to apply a function exactly n times'

15:01 hoeck: a bit uglier in my eyes, but potentially more efficient

15:31 datka: has anyone managed to get compojure 0.4 working with maven and the maven jetty plugin?

15:32 or at least in a situation where it works compiled to a war.

15:58 bozhidar: what would be idiomatic way to create a sequence comprising of several same values?

15:59 in my case I'd like to do an (apply * [2 2 2]) (2 to the power of 3)

16:00 I cannot use Math/pow since it works with double, and I'm about to the some BigInt calculations

16:00 s/the/do

16:04 krumholt: ,(repeat 3 5)

16:04 clojurebot: (5 5 5)

16:05 krumholt: bozhidar, or in your case (apply * (repeat 3 2))

16:05 ,(apply * (repeat 3 2))

16:05 clojurebot: 8

16:06 bozhidar: krumholt: 10x, that's exactly what I needed. I weren't aware of the existence of repeat

16:11 pf_moore: Hi - dumb question, but how do I refer to something on clojure.contrib from a .clj script?

16:11 (refer clojure.contrib.accumulators) doesn't work for me...

16:12 (I have clojure-contrib.jar in my classpath

16:13 bozhidar: pf_moore: I think you forgot to quote the namespace symbol

16:13 (refer 'clojure...

16:14 and you should have done an require before that

16:14 or you can simply do use to combine require & refer in a single step

16:15 pf_moore: Ah! I'd tried quoting, but missed that it was a different error. Sorted now, thanks!

20:15 joshua-choi: Hey, let's hypothetically say that I have an immutable data structure implemented in Clojure called a Relation. If I want to coordinate a mutating database, should I use many refs each of a Relation, or should I use one ref of a map of Relations?

20:42 tomoj: joshua-choi: I think it depends

20:43 joshua-choi: Hmm

20:43 tomoj: one ref is prettier, but means anyone changing the database has to compete

20:43 many refs is ugly but only changes to the same ref need to compete

20:43 same ref(s) I mean

20:44 joshua-choi: Are there any other disadvantages to many refs that you can think of?

20:44 tomoj: I can't, but that is not good evidence that there aren't any :)

20:44 joshua-choi: You know that "Functional Relational Programming" paper that Rich Hickey said was an inspiration for Clojure, or something? I'm thinking of writing a library modeled very closely to that with datatypes and protocols, just for kicks

20:44 This question is very germane to that

20:45 tomoj: the turing tarpit paper?

20:45 joshua-choi: Yeah

20:45 tomoj: cool, good luck

20:45 joshua-choi: But I gotta release the FnParse beta first, now that I got Autodoc to work

21:36 jcromartie: I HATE MUTABLE OBJECTS

21:37 hi

21:37 just wanted to share

21:51 gregh: you're in the right place

21:51 that is all

21:51 programble: omg mutation

22:03 jcromartie: "Mutable objects are the new spaghetti code" is a quote that will go down in history.

22:09 programble: yum, spaghetti

22:09 with mutable tomato sauce?

22:10 jcromartie: based on the stains in my tablecloth, tomato sauce is persistent

22:50 tetron: I'm trying to figure this out, is tail recursion as a way of passing program state between iterations of a loop good or bad in clojure?

22:51 I understand that clojure doesn't do tail recursion, so...

22:51 tail recursion optimization, I mean

23:09 chouser: tetron: direct recursion without 'recur' or 'lazy-seq' may cause problems if you're doing a lot of iterations.

23:09 s/may/will/

23:09 sexpbot: tetron: direct recursion without 'recur' or 'lazy-seq' will cause problems if you're doing a lot of iterations.

23:10 redalastor: I'm looking for a way to take a make a seq that is the cumulative sum of another seq. I'm currently thinking of recur, is there a cleaner way?

23:11 chouser: ,(reduce + [2 4 6])

23:11 clojurebot: 12

23:11 redalastor: chouser: I meant if the first seq is (1 2 4), the second should be (1 3 7).

23:12 tomoj: there's reductions somewhere

23:13 chouser: yeah, reductions is what you want. it's in clojure.core in 1.2-snapshot

23:14 ,(reductions + [1 3 7])

23:14 clojurebot: (1 4 11)

23:14 chouser: oh

23:14 ,(reductions + [1 2 4])

23:14 clojurebot: (1 3 7)

23:14 chouser: yes.

23:14 redalastor: Wow. I'm impressed, I didn't know this existed.

23:15 tetron: chouser: that's what I thought, perhaps "trampoline" what I am thinkiing of?

23:15 redalastor: thanks

23:16 chouser: tetron: if you need some kind of recursion, lazy-seq, recur, and trampoline are all options that may help.

23:17 tetron: chouser: well, what I need is essentially an event loop where the state changes each time through

23:18 so it seems like either one can rebind a var (in a transaction?) or pass the new state in a tail-recusive call

23:20 tomoj: maybe you want an agent that sends the new state to itself?

23:20 or keep the state in refs/atoms?

23:20 tetron: yea, perhaps

23:21 chouser: the loop blocks waiting for events?

23:21 tetron: no, actually it's a discrete event simulation

23:22 well, actually it's a learn-clojure simulation :-)

23:22 chouser: hehe

23:22 tetron: coming from a common-lisp background

23:23 sort of

23:23 chouser: self-sending agent is likely what you want. have you looked at Rich's ant sim?

23:23 tetron: yea, I did

23:23 chouser: I used a similar technique in a little demo sim I did for a talk a couple weeks ago.

23:24 tetron: that works then

23:24 chouser: oh, ok. so send-sending agents is how the ants simulate events.

23:25 tetron: so is there an effective difference between that and a trampoline except for which thread it runs on?

23:27 chouser: yes, they do have somewhat similar runtime shape if you will. I hadn't ever thought of it that way.

23:27 in both cases you do some work, then package up your state in a function call (or a function call + agent state), and pass that to some 3rd party to have it executed

23:28 with the agent, other threads can observe the agent-state part which of course isn't the case with trampoline

23:29 tetron: I see

23:31 I don't suppose you have a link to the ant demo?

23:32 n/m, going to bed

23:32 good night

23:32 thanks

Logging service provided by n01se.net