#clojure log - Oct 30 2010

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

0:17 itistoday: how does package.el work with respect to updates?

0:17 save a new version of clojure-mode is released, how does one get it?

0:34 replaca: Upper: if you're still there: I think you misunderstand what loop does in clojure. That form isn't actually looping at all.

0:36 Upper: I did other solution, but in clojure can't I force to exit of a loop?

0:37 replaca: so, if you simply want to pass over a seq, use doseq, like so:

0:37 ,(doseq [i (range 11)] (print i))

0:37 clojurebot: 012345678910

0:38 replaca: but if you want a conditional exit, use loop and recur, like this:

0:40 ,(let [r (rangle 10000000] (loop [i (first r) r r] (when (< r 10) (print r) (recur (first (rest r)) (rest r))))

0:40 clojurebot: Unmatched delimiter: ]

0:40 replaca: ,(let [r (range 10000000] (loop [i (first r) r r] (when (< r 10) (print r) (recur (first (rest r)) (rest r))))

0:40 clojurebot: Unmatched delimiter: ]

0:41 replaca: ,(let [r (range 10000000)] (loop [i (first r) r r] (when (< r 10) (print r) (recur (first (rest r)) (rest r))))

0:41 clojurebot: EOF while reading

0:41 replaca: ,(let [r (range 10000000)] (loop [i (first r) r r] (when (< r 10) (print r) (recur (first (rest r)) (rest r)))))

0:41 clojurebot: java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Number

0:41 replaca: ,(let [r (range 10000000)] (loop [i (first r) r r] (when (< i 10) (print i) (recur (first (rest r)) (rest r)))))

0:41 clojurebot: 0123456789

0:41 replaca: finally!

0:42 the handling of r and i can be cleaner there, but you get the idea maybe

0:42 loop only goes around if you have recur in the tail position

0:43 lrenn: yeah, my bad, i was just correcting the binding vector, didn't even thing about what he was trying to do.

0:43 replaca: it's not loop in the sense of CL's loop macro. Clojure doesn't have that

0:43 lrenn: s/thing/think/

0:43 sexpbot: <lrenn> yeah, my bad, i was just correcting the binding vector, didn't even think about what he was trying to do.

0:45 replaca: but a lot of times in clojure, we don't use loop to accomplish that at all, but rather first order functions (like some) on lazy sequences

0:45 then it's easy to consume (and therefore produce) only that part of the computation that you care about

0:53 * replaca will test his examples in the repl and paste them into #clojure from now on :(

0:55 replaca: dirs

0:55 oops!

1:11 Upper: yeah, really

1:14 Thoth: Hey all, I have a question that seems like it ought to be an FAQ, but I have had no luck with it. I have a clojure-contrib.jar on my classpath, but (use 'clojure.contrib.str-utils) breaks with a FIleNotFoundException. I'm a clojure newbie, so I might be making any number of mistakes. Any idea what might be going on?

1:15 I'm on OSX, I tried installing clojure-contrib with ports and by building from the git repository

2:02 samx: beginner question.. i'm trying to use pretty printing in my own namespace, but having trouble bringing the functions to my namespace: (ns test (:require clojure.pprint)) (pprint "test") -> Unable to resolve symbol: pprint... What am I doing wrong?

2:04 replaca: samx: I think you want :use instead of :require

2:04 samx: that seemed to do it.. thanks :-)

2:05 replaca: samx: good idiom is (:use [clojure.pprint :only [pprint]] and then you don't get any other names

2:05 (oops, add a trailing paren there!)

2:05 samx: what is the :require actually do then?

2:06 replaca: samx: require make the namespace available to you. after that you can say (clojure.pprint/pprint foo) and it'll work

2:06 samx: a nice for is (:require [clojure.pprint :as pp])

2:07 then you can invoke (pp/pprint foo)

2:07 some folks prefer that to :use :only

2:08 samx: ok.. that makes sense.. i'll play around with these a bit..

2:08 replaca: samx: have fun!

2:08 samx: thanks

2:16 ubii: any suggestions on the best way to setup a clojure development environment on Mac OS X?

2:21 replaca: ubii: I'm not a mac guy, but a simple thing to do would be to pull clojure & contrib 1.2 from here: http://clojure.org/downloads

2:22 ubii: and then look at "getting started" and "REPL and main" on the clojure.org home page

2:22 ubii: replaca: thx, ended up going the lein route

2:23 replaca: Even better!

2:23 ubii: And that's working OK?

2:23 ubii: so far

2:23 samx: i just downloaded the clojure.jar, and started with it.. and then i got intellij community edition, and installed the clojure plugin for it

2:24 replaca: one problem is that thare are *too* many ways to do it, each with its own quirks

2:41 samx: ok.. next beginner question.. i'm trying to go through a list/vector/.. using loop and recur.. but instead seem to be creating an infinite loop.. what's wrong here: (loop [myseq (seq [1 2 3])] (if (nil? myseq) true (recur (rest myseq))))

2:47 hoeck: samx: myseq will be never nil because you call rest on it

2:47 samx: use next instead

2:47 ,(rest [1])

2:47 clojurebot: ()

2:47 hoeck: (nil? (rest [1]))

2:47 ,(nil? (rest [1]))

2:47 clojurebot: false

2:47 samx: oops.. thanks :-)

2:47 hoeck: ,(nil? (next [1]))

2:47 clojurebot: true

2:48 hoeck: samx: or test with empty?

2:48 ,(empty? (rest [1]))

2:48 clojurebot: true

2:49 hoeck: which is cleaner for collections than nil, plus it works on all kinds of empty collectsion (empty? {}), (empty? []) ...

2:49 magicduncan: hi all, can anyone recommend the best place to start for streams in clojure?

2:49 replaca: magicduncan: what do you mean by streams?

2:51 magicduncan: I guess being able to define something that will produce stuff at unknown times from now into the future, that we can assign to something, filter, transform and create downstreams from

2:51 replaca: magicduncan: I think that's mostly covered by lazy-seqs in clojure

2:52 but you can also use something like fill-queue

2:53 magicduncan: yeah i reckon they would certainly feel like lazy-seq to work with, but would need to be...how shall I say.....long lived?

2:53 replaca: in which sense

2:53 ?

2:55 do you mean they continue producing results forever, slowly? Or the previous results are persistent? Or something else?

2:55 magicduncan: lets say I could create a stream of clockticks. Done, it is streaming clockticks, in its own thread I think. Then I could come back later and define a stream of filtered clockticks based off of the original, on some arbitrary filtering basis. Done, it would then also be left running

2:55 not sure if Im making sense even to myself ;)

2:56 replaca: do you want old ones to go away without being consumed when no one was interested?

2:56 if you just want the stream, you can just build a lazy seq out of futures

2:57 magicduncan: I guess Im looking to create some sort of interactive pipeline model. Hmm, Im not sure if old streams should disappear if there no one is listening. I think the definition for the stream should stick around in case anyone wanted such things in the future

2:57 replaca: though you eventually run out of memory ith that model :)

2:58 s/ith/with/

2:58 sexpbot: <replaca> though you eventually run out of memory with that model :)

2:58 magicduncan: run out of memory from the definitins or the actual events coming down the streams?

2:59 replaca: well, if you save the events for arbitrary consumers to consume at a later date

3:00 magicduncan: ah, I see. No I think if you werent listening at the time then too bad for you, you missed the event

3:00 replaca: for ajaxy systems, i've done streamy things that drop events if you don't keep up

3:01 I mean, you can just have a thread banging an atom and consumers read from it

3:02 but then you have the problem if the consumers read too fast

3:02 so what I've done is have a tuple <serial, value, promise> in a ref.

3:03 the consumer keeps the serial as the cookie for the last thing it got

3:04 and then checks the ref: if the serial in the ref is newer than the cookie the consumer has, take the value other wise block on the promise.

3:04 new values update the ref with a new tuple, and fulfill the promise in the old one

3:05 magicduncan: how bout this example. lets say I could define (stream priceticks stock-exchange) and then later come along and define (stream googleShareTicks priceTicks) filtering the original stream. Would probably tho still need to create something that consumed from googleShareTicks if the events werent going to be dropped

3:05 replaca: that way fast consumers get items as they become ready and slow ones simply miss

3:06 it'd be pretty easy to chain them together

3:06 if you had a main firehose and then derivitive ones

3:06 magicduncan: Im not sure I understand how consumers would get away from you like that. In Java theres the notion of the blocking queue

3:07 replaca: magicduncan: right, the problem with a blocking queue is:

3:07 if 1 person reads from it, they take the data

3:08 if nobody ready from it, it slowly uses all your memory (or with LBQ blocks the producer)

3:08 which is no problem is some situations and a disaster in others

3:08 magicduncan: right, ok this is more a pub-sub, I see the problem

3:08 replaca: yeah, that's where I'm coming from

3:09 magicduncan: really need the stream (publisher) to not have to know if anyone is listening or not, but needs to know if it is to determine whether to hold on to the event at all

3:09 replaca: I haven't done the thing of defining channels in terms of other channels, but I don't think it would be too hard to build that

3:10 right, tht's why the intermediate mechanism is nice

3:10 it handles both waiters and "idle" cases

3:11 if you want, I presented some code in my talk at the conj. The slides are here: flow-preso.heroku.com

3:11 look at slide 37 and following

3:12 magicduncan: hey so, if Im understanding your approach right, each consumer is polling for changes, keeping track of the last one it received to differentiate anything new?

3:12 replaca: yeah, that works best with long wait ajax push consumers

3:13 magicduncan: ok, I need to give that some thought. I'll take a look at your slides. Thanks!

3:13 replaca: but obviously there are a lot of variations (esp. if you know you're clients aren't going to disappear on you)

3:13 sure. enjoy!

3:51 angerman: is clojuredocs.org new?

4:21 how do I create a 2d float array?

4:38 jarpiain: ,(make-array Float/TYPE 10 20)

4:38 clojurebot: #<float[][] [[F@114f313>

4:40 angerman: jarpiain: is there an easy way to create one from a seq of seqs?

6:56 (byte 254)

6:56 ,(byte 254)

6:56 clojurebot: java.lang.IllegalArgumentException: Value out of range for byte: 254

6:56 angerman: so what does java make from (byte)(254.0)?

7:02 ,(byte 0xFF)

7:02 clojurebot: java.lang.IllegalArgumentException: Value out of range for byte: 255

8:14 noidi: what's the simplest way to update the nth item in a seq?

8:15 if I was using a vector I could use an update-in, but I'm dealing with a lazy seq

8:22 there must be a simpler way than this... (defn update-nth [s n f] (concat (take n s) [(apply f [(nth s n)])] (drop (inc n) s)))

8:30 oh well, I realized I need to convert to a vector anyway for this use case

8:30 seq was a bad choice for several reasons

8:32 esbena: does clojuer have any libraries for solving minimum cost maximum flow instances?

8:35 noidi: esbena, I have no idea what you are asking for, but most of Clojure libraries are quite generic. You'll probably need to use Java libraries for domain-specific things.

8:41 esbena: noidi, ok. btw. minimum cost maximum flow instances are a general formulation of a lot of algorithmic problems. ex. freight scheduling.

8:48 noidi: esbena, maybe this could help you? http://stackoverflow.com/questions/51574/good-java-graph-algorithm-library

8:49 esbena: noidi, thx!

8:49 noidi: http://www.yworks.com/products/yfiles/doc/api/y/algo/NetworkFlows.html

9:39 tonyl: morning

10:40 angerman: is there something like -> that takes a vector of forms and applies -> on them?

10:41 just wondering if there's something like that already

10:44 tonyl: something like this (apply -> [:foo str keyword])?

10:44 but that doesnt work, -> is a macro

10:45 angerman: hmm no, wait, i'll code something up.

10:45 -< and -<< are not used yet, right?

10:46 tonyl: not as far as I know

10:59 angerman: how do I get the contents of a list in a macro?

11:01 tonyl: by defering the list, i think. I am barely new to macros

11:01 ~@

11:01 clojurebot: @ , {a b c]

11:03 tonyl: angerman: so you want a fn or macro that takes a vector of forms and applys -> to those forms?

11:03 angerman: kinda

11:03 (defmacro -< [e & forms] (for [f forms] `(-> ~e ~@f)))

11:03 is pretty close

11:04 tonyl: oh i see, yeah

11:04 i don't think you need splicing for f, ~f should work. i thought ~@ was for sequences

11:04 angerman: it would basically allow to branch

11:05 yes f is a sequence

11:05 e.g. (-< 1 [(+ 1) (+ 1)] [(+ 2) (+ 2)])

11:05 should return (list 3 5)

11:06 tonyl: then you want the list to be evaluated

11:08 angerman: well, as above is already quite good. the only problem is that for returns a list and that list is trying to be evaluated :/

11:15 bhenry: i need to set an atom in one namespace and get it from another. is this a bad practice?

11:17 tonyl: ,(for [vf [[(+ 1) (+ 1)] [(+ 2) (+ 2)]], f vf] `(f))

11:17 clojurebot: ((sandbox/f) (sandbox/f) (sandbox/f) (sandbox/f))

11:17 tonyl: ,(for [vf [[(+ 1) (+ 1)] [(+ 2) (+ 2)]], f vf] `(~f))

11:17 clojurebot: ((1) (1) (2) (2))

11:17 angerman: hmm...

11:17 got it done

11:17 tonyl: great

11:17 what do you have?

11:17 angerman: (defmacro -< [e & forms] (apply vector (for [f forms] `(-> ~e ~@f))))

11:18 notsonerdysunny: is there a way to find out the number of arguments a given closure is going to take from the repl?

11:18 angerman: ,(defmacro -< [e & forms] (apply vector (for [f forms] `(-> ~e ~@f))))

11:18 clojurebot: DENIED

11:18 angerman: :D

11:18 tonyl: :P macros

11:18 angerman: well but this not let's one branch out :D

11:18 threading with branches ... yey

11:18 tonyl: sounds fun

11:19 notsonerdysunny: you can check the meta from the fn for the arity

11:21 angerman: (-< and (-<< do look somewhat retarded though :D

11:21 tonyl: haha

11:21 how about inception :P

11:22 angerman: pardon me?

11:22 tonyl: a cool name would be inception

11:24 angerman: don't know if that's appropiate though. I'm thinking along thread-splicing

11:25 notsonerdysunny: tonyl: as I said these are closures returned by some macro other than defn .. so it does not have the :arglists in the meta info.. i tried to do that

11:25 angerman: it basically allows you to do branches

11:26 e.g. you want to compute something further with x but you do need x later on again or in a different way.

11:26 notsonerdysunny: tonyl: however I feel it should be able to some how tell me that info .....

11:26 tonyl: yeah i know, just going with it. that is an interesting name

11:26 angerman: so just branch it out, compute and merge them back together.

11:26 wsimpson: t-1000?

11:27 :P

11:27 tonyl: yeah i like it, that is what r u using it for?

11:27 angerman: well doing some image processing. I usually want to keep the image around while computing the histogram.

11:27 was just wondering if there was a threading approach as well

11:27 tonyl: notsonerdysunny: I also think it should be easy to find

11:28 hopefully the image is not that big

11:30 angerman: no. ~ at most 600 x 150 x 1 byte

11:33 tonyl: notsonerdysunny: my advice would be to explicitly add the arglists meta to those closures if you can.

11:36 angerman: you can get rid of apply if you want

11:36 angerman: how?

11:36 clojurebot: with style and grace

11:36 tonyl: (defmacro thread-splicing [e & forms] (vec (for [f forms] `(-> ~e ~@f))))

11:37 vec takes a coll

11:37 i don't think it changes in perf but just a thought

11:37 how?

11:37 clojurebot: with style and grace

11:37 tonyl: that is funny

11:37 @

11:37 ~@

11:37 clojurebot: @ is splicing unquote

11:38 tonyl: ~~

11:38 clojurebot: #<ClassCastException java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;>

11:38 tonyl: ~`

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

12:07 notsonerdysunny: is there a way to list all the namespaces that are available in all the jar files available in the current *classpath* ?

12:07 with having to require all of them....

12:09 tonyl: i would look in clojure.contrib.find-namespaces

12:09 probably the fn find-ns-decls-on-classpath

12:11 Thoth: On the subject of clojure-contrib, I am having a terrible time finding it on my classpath. I have it at /opt/local/share/java/clojure/lib/clojure-contrib.jar and /opt/local/share/java/clojure/lib is in my classpath, but I keep getting an error "Could not locate clojure/contrib/str_utils__init.class or clojure/contrib/str_utils.clj on classpath"

12:12 It's breaking on the line (use 'clojure.contrib.str-utils)

12:12 tonyl: i think that is a deprecated namespace

12:13 no, my bad

12:13 Thoth: str-utils you were thinking?

12:13 tonyl: does the str_utils.clj file exist?

12:14 i used to have this problem, can't remember how i fixed it

12:14 Thoth: No.....I had just installed the jar from ports. Maybe I should go grab it

12:14 Maybe I should grab the entire clojure-contrib package as .clj files

12:15 tonyl: the clojure.contrib.str-utils is deprecated since 1.2

12:15 Thoth: Ooohhh.

12:15 tonyl: but clojure.contrib.str-utils2 is a replacement i thikng

12:15 *think

12:15 http://clojure.github.com/clojure-contrib/#str-utils

12:15 Thoth: Ah hah. :-)

12:16 Interesting. Thanks!

12:16 I'll give that a try

12:45 jaley: Hi guys! question about the bean function... the documentation says the returned object is a "read-only implementation of the map abstraction..." - does read-only here mean something different to Clojure's normal persistent datastructures? or is this just to make it clear that what's returned is immutable, unlike the original java object?

12:55 ohpauleez: jaley: It's just a regular APersistentMap

12:55 like {}

12:55 that is proxying the object

13:17 mtopolnik: I've been doing some memory measurements on lazy seqs

13:17 turns out that on a 64-bit JVM the overhead of lazy seq per node is 120 bytes

13:18 compared to 56 bytes for a PersistentList

13:18 seems quite a lot

13:19 are there any plans to optimize the structures?

13:19 clojurebot: I don't understand.

13:20 mtopolnik: java.utilLinkedList has 40 bytes per node

13:22 for example, once a lazyseq's node is forced, it basically becomes a cons

13:22 maybe only the cons could be kept around

14:11 LauJensen: People still recovering from the Conj? :)

14:21 ivey: Hey, would any of you use a key/value store abstraction layer? So you could write to it, and have it speak mongo/redis/tokyo/cassandra/ whatever else?

14:29 jaley: ohpauleez: sorry was afk - thanks a lot, that's what i needed to know! :)

14:53 alexyk: ninjudd: awesomest Halloween costume!

14:54 http://yfrog.com/7e1kqfj

14:55 noidi: brilliant :D

15:26 philjordan: hi

15:26 so I've just realised that 2 locally defined functions can't be mutually recursive

15:26 jaley: (doc trampoline)

15:26 clojurebot: "([f] [f & args]); trampoline can be used to convert algorithms requiring mutual recursion without stack consumption. Calls f with supplied args, if any. If f returns a fn, calls that fn with no argu...

15:27 philjordan: yeah, I know about trampoline

15:28 jaley: oh. :)

15:28 philjordan: my case isn't quite the classic recursion, one of my functions needs to hold on to a reference to the other (as in a closure)

15:29 I'm trying to work out a minimal equivalent case

15:31 hmm, maybe I want letfn

15:34 replaca: philjordan: yeah, letfn is designed for that exact situation

15:35 philjordan: okay, I realise my case is more complicated than letfn will let me do

15:36 one of my functions is actually the result of a higher order function call

15:36 which as far as I can tell, letfn won't let me do. hm.

15:36 * philjordan looks at letfn source

15:39 philjordan: okay, where the devil is letfn* defined :-/

15:39 jarpiain: LetFnExpr in Compiler.java, it's a special form

15:40 philjordan: ah.

15:41 thanks, that saves me some searching, but I suspect it also means I can't do what I'm trying to do

15:43 i.e. something like this:

15:44 (let [a (h-o-f (fn [x] (fn [] (b x)))) b (fn [y] (a y))] a)

15:45 which probably doesn't make it any clearer

15:45 replaca: philjordan: you can't just have three fns in your letfn?

15:46 so that the fn called by h-o-f is also a neamed fn

15:46 philjordan: the problem I see is that letfn requires function *bodies* whereas one of my functions is actually the return value of a higher-order-function

15:47 replaca: philjordan: oh, i see. hmmm.

15:47 philjordan: actually, letfn seems to inject the 'fn' part

15:48 letfn* itself might allow me to do what I want

15:48 going to try a (pprint (macroexpand on a letfn expression to wrap my head around it

15:52 user=> (pprint (macroexpand '(letfn [(a [x] (b x)) (b [y] (a y))] a)))

15:52 (letfn*

15:52 [a (clojure.core/fn a [x] (b x)) b (clojure.core/fn b [y] (a y))]

15:52 a)

15:52 that looks promising

15:53 jarpiain: ,(letfn* [x 1 y 2] (+ x y))

15:53 clojurebot: java.lang.ClassCastException: clojure.lang.Compiler$ConstantExpr cannot be cast to clojure.lang.Compiler$ObjExpr

15:53 jarpiain: it really wants (fn ...) expressions there

15:53 philjordan: damn

15:54 I guess that kind of makes sense

15:55 td123: is clojure still getting developed?

15:55 philjordan: I'll have to think about it some more, maybe I can express it in terms of 2 fns like that

15:55 Raynes: td123: http://github.com/clojure/clojure

15:55 td123: I see the git repo hasn't been updated since june

15:56 oh

15:56 nvm :)

15:56 Raynes: I assume you were looking at the told repository.

15:56 td123: Raynes: you assume correctly

15:56 Raynes: Clojure is more lively than it's ever been. :>

15:57 philjordan: thanks for the help so far, this needs to bounce around my brain some more. til then I'm using an atom as a level of indirection :-/

16:01 jarpiain: letfn* initially writes nulls in the new locals and then has to patch the right values in the created closures

16:02 Upper: , (map #(% %) filter(odd?) (range 1 10))

16:02 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$odd-QMARK-

16:02 td123: what do you guys think is the best intro to clojure out there?

16:03 Raynes: I've heard good things about Stuart Sierra and Luke Vanderhart's Practical Clojure.

16:04 jaley: design/style question: i'm tempted to write a function, "beanify", to iterate through the nest of javabeans i get back from a web service calling bean to convert them to maps. is this bad? will i regret it in a few weeks? :)

16:05 Upper: how to print only odd number sequence? I want to print a number of times, example, if the args is 5, it will return 1 3 5 7 9

16:06 angerman: (range 1 (* 2 5) 2) ?

16:06 ,(range 1 (* 2 5) 2)

16:06 clojurebot: (1 3 5 7 9)

16:06 Upper: tks

16:08 td123: angerman: what does that comma do?

16:08 angerman: invoces clojurebot

16:08 quizme: I'm having trouble with leiningen & neo4j. Can somebody explain to me what this means? ---> http://pastie.org/1260692

16:08 td123: oh neat

16:08 Raynes: &(range 1 (* 2 5) 2)

16:08 sexpbot: ⟹ (1 3 5 7 9)

16:08 td123: ,(println "hi bot")

16:08 clojurebot: hi bot

16:08 td123: hehe

16:09 Raynes: sexpbot has a pretty arrow. <3

16:09 jaley: ;; presumably it's protected from things like (iterate inc 1)?

16:09 Raynes: Yes.

16:10 Both bots are.

16:10 angerman: ,(println "&(println \",(nil)\")")

16:10 clojurebot: &(println ",(nil)")

16:10 sexpbot: ⟹ ,(nil) nil

16:10 Raynes: My pretty arrow prevents botchains.

16:11 Upper: angerman: is possible print -> 1;3;5; instead of (1 3 5) ?

16:11 angerman: hmm. backspace?

16:12 jaley: Upper: there's a str-join function in contrib/str-utils

16:12 Upper: right

16:12 angerman: Raynes: hmm... I guess backspace character eating does not work

16:12 replaca: Upper: cl-format supports more customization as well

16:12 Raynes: &(doseq [x (range 1 (* 2 5) 2)] (print (str x ";")))

16:12 sexpbot: ⟹ 1;3;5;7;9;nil

16:13 Raynes: That's actual printing though.

16:14 LauJensen: &(do (println "1") (println "2"))

16:14 sexpbot: ⟹ 1 2 nil

16:15 vibrant_: how can i join 2 vectors?

16:16 Raynes: &(into [1 2 3] [4 5 6])

16:16 sexpbot: ⟹ [1 2 3 4 5 6]

16:16 vibrant_: thanks Raynes

16:17 Raynes: There is also concat, but it returns a lazy-seq and not a vector.

16:17 &(concat [1 2 3] [4 5 6])

16:17 sexpbot: ⟹ (1 2 3 4 5 6)

16:18 replaca: Upper: like this: (cl-format nil "~{~a~^;~}" [1 3 5])

16:18 for string output

16:18 use true or *out* instead of nil if you want it to print

16:19 Upper: that doseq from Raynes worked well

16:21 Raynes: &(println (apply str (interpose ";" (range 1 (* 2 5) 2))))

16:21 sexpbot: ⟹ 1;3;5;7;9 nil

16:21 Raynes: That's an option.

16:23 cl-format is a beast.

16:24 jaley: is there a less ugly way of doing something like... (if (coll? x) x [x])?

16:25 i want to map over x, but sometimes it'll be a single object, not a collection, and i want to treat as a collection of 1 object i guess

16:27 chouser: replaca: I know you've told me this before, but what's the easiest way to pprint code?

16:30 wdouglas: Is there any guide for viewing function definitions in jar files with emacs? (e.g.. M-. jumps to text region of the definition)

16:31 jaley: wdouglas: I think I saw that demonstrated in the video for CDT (clojure debug toolkit?). I suspect that feature wouldn't have been added if it was already possible? so probably no, but not sure.

16:33 arohner: wdouglas: what do you mean? M-. jumps to defintions inside jars for me

16:33 wdouglas: jaley: thanks I'll take a look at that

16:33 arohner: It used to work for me too but I switched over to a new vm and now it does not.

16:34 vibrant: any libs recommended for game programming?

16:34 jaley: wdouglas: actually yeah... working on openjdk for me

16:34 wdouglas: arohner: I just figure I'm missing something I normally have configured but my googling hasn't pulled up much.

16:34 arohner: wdouglas: vm? JVM? I'm running sun JDK, slime, and the jar is on the classpath, and it Just Works for me

16:34 wdouglas: you're running slime and the jar is accessible in the running classpath?

16:34 wdouglas: open-jdk. Lib in the classpath.

16:35 arohner: wdouglas: stupid question, but you're connected via slime? Does M-. on a definition in a text file work?

16:35 clojurebot: slime-installer is deprecated

16:35 wdouglas: arohner: Will make sure it isn't working on clojure core though as it is another lib in the classpath that I am having issues with

16:36 arohner: Well it jumps into the jar file (probably to the right place, just binary though)

16:36 jaley: wdouglas: a whole bunch of slime features broke for me when i upgraded my distro because versions were out of sync with the distro package manager. i stopped using the package manager version of slime as a result.

16:37 wdouglas: Ah I just use the version in elpa

16:37 arohner: works fine within the text file in SLIME

16:38 arohner: wdouglas: when you say 'just binary', what do you mean? did it jump to the jvm byte code for the function?

16:38 wdouglas: That's what it looks like to me.

16:38 arohner: wdouglas: is there a .clj containing the function in the jar?

16:40 wdouglas: arohner: Will need to figure out how to take a peek in the jar.

16:40 arohner: the package is aleph if you know off hand

16:40 arohner: wdouglas: just visit the jar in emacs. it will give you a dired window

16:40 * angerman is quite happy with his -< and -<< macros :D

16:41 wdouglas: arohner: Yep

16:41 arohner: ahh I think I get it

16:41 arohner: When I try to open the file from emacs, it says it can't find unzip

16:41 arohner: wdouglas: ah. that sounds like a problem

16:42 wdouglas: arohner: Yep X(

16:42 jaley: wdouglas: windows?

16:43 angerman: sometimes I wish clojure had infix notation

16:43 wdouglas: jaley: No, arch

16:43 rdeshpande: l

16:43 jaley: angerman: it's in incanter, $= macro

16:44 angerman: jaley: right. too bad that's not available as an external lib

16:44 hate to drag incanter with me all the time

16:44 jaley: wdouglas: ah ok. i use emacs at work and have to install cygwin for half of emacs to function properly :p

16:45 angerman: yeah, it's pretty useful

16:46 wdouglas: jaley: Same, though I have run into issues with git for windows cygwin and the normal cygwin install playing nice

16:46 jaley: arohner: Yep, unzip install fixed it. Thanks for your help.

16:48 angerman: This: (show (>- thresh-at (-< (scale (load-sample-character 1) :height *H*) [identity] [blur freq-table smooth-hist2 combined-thresh-finder]))) would definitely look better with >- thresh-at at the end.

16:48 -< is bascially a parrallel ->

16:49 and (>- fn forms) is (apply fn forms) ...

16:49 rata_: hi

16:59 angerman: lol

16:59 the threading macro is evil

17:02 jcromartie: any macro can be evil

17:02 -> is really nice :)

17:02 sexpbot: java.lang.Exception: Unable to resolve symbol: is in this context

17:02 angerman: http://gist.github.com/655742

17:02 jcromartie: -> "what?"

17:02 sexpbot: ⟹ "what?"

17:02 * angerman is probably abusing the threading idea :D

17:03 angerman: though it allows for some flow-style programming

17:03 jcromartie: I think => is a better parallel ->

17:03 name-wise

17:04 oh, I thought you meant parallel like threads

17:05 angerman: no, parallel as in splicing

17:05 though I guess you could easily add parrallel computation semantics

17:06 as this perfectly describes parrallel computation flow

17:07 jcromartie: seriously though, your code *is* evil

17:07 angerman: if you get used to the macros it is quite readable.

17:07 mostly like a flow chart :D

17:07 jcromartie: hm I guess I get it

17:08 angerman: the inc in there is somewhat confusing :D

17:08 jcromartie: it reminds me of juxt in a macro

17:09 in fact what does it do that you can't do with juxt?

17:10 never mind, I see the point

17:10 neat

17:10 saves a few ->'s

17:10 and fns

17:11 angerman: yep. there are some things you just cannot do with the default -> threading as it's a single thread.

17:11 >- basicaly splices the thread

17:11 err -< splices

17:11 and >- recombines it

17:12 http://skitch.com/angerman/d6y3y/untitled this is what I use it for

17:12 I've added the full extended version

17:12 http://gist.github.com/655742

17:14 * angerman proposes extended threading (splicing) for clojure inclusion ;D

17:18 jcromartie: is that some OCR?

17:19 angerman: not yet. but it's getting there

17:29 jcromartie: I was surprised to learn that the options out there for open source OCR are really really terrible

17:29 and haven't advanced at all in years

17:30 rata_: angerman, are you working on an open-source OCR?

17:31 angerman: rata_: this is going to be a dead stupid one with very limited functionality

17:31 rata_: ok

17:31 angerman: it's basically just a prototype for serial number detection of bank notes

17:37 rata_: does anybody know the nickname of Justin Kramer (the author of loom) in freenode? I thought it was jkkramer, but "/whowas" says there was no such nickname

17:37 technomancy: there's a /whowas command‽ nice.

17:38 angerman: whoa, interobang

17:39 rata_: technomancy, yes, there is :)

17:39 technomancy: sweet; my meme is still rolling: http://twitter.com/#!/search?q=%23unicodebandnames

17:44 angerman: technomancy: could I get your input on -< and >- ala http://gist.github.com/655742

17:46 rata_: technomancy: how can I make swank to recognize (some-ns/let-* [...] ...) as a let-like form and indent it accordingly?

17:46 technomancy: rata_: live indentation inference over swank is only implemented for CL, I think

17:47 angerman: I'm not seeing the motivation; it'd be clearer if you had original vs your new macros side-by-side

17:48 rata_: mmm... really? but it does recognize (let-* [...] ...)

17:48 technomancy: rata_: that's just static analysis in clojure-mode; nothing to do with swank

17:48 I think

17:48 rata_: ok

17:49 who's the author of clojure-mode?

17:49 technomancy: jeffrey chu, who vanished years ago

17:52 rata_: :(

17:53 angerman: technomancy: I'm having a hard time coming up with working clojure code to supply my macros

17:54 basically the idea is that when using (-> ...) you are bound to sequential computation

17:54 in my application I have an image. of which I compute the the histogram and use that to compute an optimal thresholding value. Then I stick both together (the image and the compute value)

17:55 from a flow-diagram this looks semi-sequential. At one point I need to branch ( -< ) and at one point I need to merge ( >- ) the branches again.

17:58 (-<) looks to me like information is flowing in on the left and is split into two new threads

17:58 while (>-) looks like two threads are merged together

17:58 hiredman: angerman: http://intensivesystems.net/tutorials/stream_proc.html

18:00 angerman: hiredman: interesting :D

18:04 for the lightweight use I'll use my macros

18:06 quizme: (str :a) => ":a" How do you get rid of the colon or not make it show up in the first place?

18:06 MayDaniel: (name :a)

18:07 quizme: MayDaniel awesome thanks

18:52 replaca: chouser: I was off with the kids

18:52 chouser: try this: (with-pprint-dispatch *code-dispatch* (pprint code))

18:52 also, see here for more info: http://clojure.github.com/clojure/doc/clojure/pprint/PrettyPrinting.html

19:05 rata_: how can I expose what I :use?

20:07 _seanc_: Is there no time or timestamp in clojure?

20:07 hiredman: ,(.getTime (java.util.Date.))

20:07 clojurebot: 1288483747917

20:08 _seanc_: I'm surprised there's no simple (timestamp)

20:08 hiredman: ,(System/nanoTime)

20:08 clojurebot: 1288483810267527000

20:10 Raynes: _seanc_: Where Java isn't broke, Clojure doesn't fix it.

20:10 &(java.util.Date)

20:10 sexpbot: java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn

20:10 Raynes: &(java.util.Date.)

20:10 sexpbot: ⟹ #<Date Sun Oct 31 00:11:30 UTC 2010>

20:10 Raynes: There are already excellent time libraries for Java, such as Joda.

20:10 $google clj-time

20:10 sexpbot: First out of 44400 results is: clj-sys's clj-time at master - GitHub

20:10 http://github.com/clj-sys/clj-time

20:11 _seanc_: Ok

20:11 Raynes: clj-time is a Clojury Joda wrapper.

20:11 _seanc_: I just figured that was something simple and might be a part of Clojure I was simply over looking

20:25 Plouj: keyboard on the legs: http://www.flickr.com/photos/ghoseb/5120430719/in/set-72157625254615916/ ??

20:28 LaPingvino: :P

20:38 _seanc_: Using Atoms, could you create a simple cache of sorts for a web app (Compojure) or am I misunderstanding their purpose? For instance, say the number of users; retrieve, put in atom, everyone else retrieves without hitting the db.

20:39 LauJensen: _seanc_: You might want to check out memoize, both its purpose and implementation

20:39 (it uses an atom as its cache)

20:40 _seanc_: I have, but it appears there is no way to update the values in memorize. I wanted to use atom with a vector containing a timestamp and the value. If it's more than a few days off, get an updated value

20:41 LauJensen: _seanc_: Reimplement memoize with a different caching strategy. Would be trivial to implement a timestamp check

20:45 Just to be clear though, you're not using Ring/Compojure to serve static files right?

21:12 angerman: ...

21:13 and it's one hour earlier ... timetravel

21:30 Lajla: ,(let [+ + + + + +] (+))

21:30 clojurebot: Lajla: Titim gan éirí ort.

21:30 Lajla: ->(let [+ + + + + +] (+))

21:30 sexpbot: ⟹ 0

21:50 somnium: http://gist.github.com/656004 << anyone think this is interesting? a toy implementation of structural types + pattern matching in Clojure

21:53 duck1123: Just so I'm sure I'm not missing something, it is not possible to proxy a final method, correct?

21:56 I'm trying to find a good way to mock out a concrete class for my tests. It's a PITA to set up and I only call a handful of methods on it, one of which is final

22:05 rata_: somnium: interesting :) I like it

22:20 quizme: how do you change the way a java instance displays in the repl ?

22:20 right now it looks like: #<NodeProxy Node[2]>

22:21 but i want it to look like: {:id "C12345", :age 30, :name "Bob"} for example

22:26 somnium: quizme: (defmethod printmethod <javatype> (fn [w x] (.write <representation-of-x>)))

22:26 oops, (.write w <rep>) of course, you probably get the idea anyway

22:27 rata_: ah cool, someone looked at it :)

22:29 rata_: somnium, quizme: I think it's print-method

22:30 Raynes: &(doc print-method)

22:30 sexpbot: ⟹ nil

22:30 Raynes: Indeed.

22:30 alexyk: hey somnium! what's new in congomongo? are you still hacking at it?

22:31 rata_: somnium: :) I like that Haskell-like syntax

22:31 quizme: oh cool

22:31 Raynes: He better be.

22:32 somnium: alexyk: not so much :( it still scatches the itch when I need it

22:32 alexyk: purcell and arohner are helping maintain it though

22:32 alexyk: somnium: cool

22:33 Raynes: $max

22:33 sexpbot: The most users ever in #clojure is 317

22:34 somnium: rata_: right now it can't handle nullary types, and makes a deftype for each struct, so they're cumbersome to extend with protocols

22:35 but, that's toys for you, I'll go ahead and put it on github :D

22:35 rata_: good :)

22:38 somnium: alexyk: so you implemented your project from back when in haskell and ocaml too, with multiple key-value stores?

22:40 rata_: http://github.com/somnium/matchmaker

23:28 rata_: how can I expose what I :use?

23:36 Joshua__: If I was to get a Paradigms of AI Programming by Peter Norvig how hard would it be to do the book in Clojure rather than Common Lisp?

23:41 rata_: Joshua__: if you know CL and Clojure, I imagine it'd be easy

23:41 Joshua__: Well I don't know CL and I'm a real novice with Clojure.

23:41 Raynes: rata_: What do you mean by 'expose'?

23:41 Joshua__: I want to learn Clojure though, but I'm not to keen on learning CL.

23:42 gregh: Joshua__: then it might be sort of like reading about the history of opera in italian, when you don't know italian. :)

23:43 _seanc_: Question about atoms. Doesn't (let [mem (atom {})]) essentially reset the atom? To retain the value(s), would it be best to check first?

23:43 rata_: Raynes: I mean that after require'ing that file, I can access the :use'd symbols

23:44 _seanc_: I don't understand your question

23:44 Raynes: I'm pretty sure there isn't a way to do that. There was some sort of immigrate macro in compojure to do something similar, but it's generally considered bad juju.

23:45 _seanc_: rata_: I'm trying to set up a simple cache using atoms. But within the function I'm wondering if I need to do anything to prevent the atom being reset to an empty map.

23:47 if you call (def mem (atom {})), add some values, and then call def again, mem is empty. How can I prevent that?

23:47 rata_: Raynes: then how can I expose the symbols of several files in one namespace?

23:47 Raynes: rata_: That was, if I remember correctly, the exact purpose of immigrate.

23:48 rata_: mmmm... then there's no way to do it? why is it considered a bad thing?

23:48 _seanc_: do you want to rebind mem?

23:50 Raynes: rata_: Probably because then you have no idea where anything comes from. The generally accepted way of doing things is to require namespaces rather than use them, or to only :use what you need from namespaces.

23:50 _seanc_: rata_: I want to bind it once, then prevent it from accidentally being rebound after it is populated.

23:51 Raynes: rata_: http://github.com/weavejester/compojure/commit/2fe4f37a15f3bd2fb285192b05a8f270d927e1d8

23:51 rata_: _seanc_: then don't do any (let [mem ...] ...), it's already bound with def

23:52 Raynes: You *can* do it, but you might want to consider a different way.

23:52 _seanc_: rata_: I'm writing an app with compojure, at the top I do the def. What I'm concerned about is if another user hits the site that it might reset the values. Are my concerns irrational?

23:53 rata_: _seanc_: I don't know anything about compojure

23:54 _seanc_: oh well, I appreciate the help

23:55 rata_: Raynes: but I have different namespaces just to have manageable files... I want some of their functions in an shorter namespace

23:56 Raynes: _seanc_: Your files don't get reloaded when a request is made.

23:56 clojurebot: You don't have to tell me twice.

23:56 _seanc_: Raynes: Awesome! :D

23:56 Raynes: _seanc_: However, there is some developer middleware to do just that, for the purposes of development.

Logging service provided by n01se.net