#clojure log - Sep 06 2009

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

0:02 prospero_: forget anything you've imported

0:02 start with a clean slate

0:43 poet: (doto (JFrame.) (add (JLabel. "Hello World")) pack show) gives "Unable to resolve class JFrame" Any idea why?

0:45 hiredman: have you imported the class?

0:46 you are going to have other issues with the method calls in the doto

0:46 the method names need to be prefixed with a .

0:46 .pack .add .show

0:46 arbscht: that's from an old example

0:47 poet: ahhh gotcha

0:47 yeah it's from one of the clojure vidoes on blip.tv from 2009

0:47 *2008

0:48 arbscht: poet: try this for a somewhat idiomatic, current and substantial example http://gist.github.com/164652

0:49 poet: arbscht: nice, thanks

1:08 prospero_: I'm walking an expression tree, and trying to pretty print each node

1:08 it's coming out garbled

1:08 <-

1:08 (<-a

1:08 a+(+vec2

1:08 (vec2 1 1) (vec2 1 1)vec2

1:08 (vec2 1 1) (vec2 1 1))

1:08 (+ (vec2 1 1) (vec2 1 1)))((<- a (+ (vec2 1 1) (vec2 1 1))))

1:08 it's all interleaved, for reasons that I don't really understand

1:09 has anyone seen this before?

1:09 if I replace the expression with a constant list, like [1 2 3], it comes out perfectly fine

1:10 that is, if I just call (pprint [1 2 3]) instead of (pprint expr), it comes out fine

1:19 ok, so I guess it's a bit much to assume someone's seen something exactly like this before

1:19 I don't think there's any concurrency at work here, but would that cause this behavior?

1:20 are writes to *out* atomic?

1:35 LauJensen: Top of the morning gents

3:26 LauJensen1: For the DZoners among you: http://www.dzone.com/links/best_in_class_the_blog.html

3:33 wavister: going to start using refs, and i'm a little shaky on one concept. if I'm just reading a set of refs, should I open a dosync and then call ensure on all the refs I'm reading to be sure that between the beginning of the function and the end of the function a transaction isn't committed that changes all my data?

3:34 tomoj: wavister: I don't think that matters

3:34 you get a snapshot in the transaction

3:34 LauJensen1: ~ensure

3:34 clojurebot: I don't understand.

3:34 wavister: so just open a dosync and deref with @?

3:34 tomoj: even if some commit happens in the middle of your dosync, you still see the old values

3:34 LauJensen1: Rich offered a really good explanation on ensure vs write-skew, lemme see if I can find it

3:35 tomoj: but there is some reason for ensure, I just don't understand it yet

3:35 LauJensen1: wavister: You can read outside of a dosync, there are no reader locks

3:35 hiredman: erm

3:35 if you want a consistant snapshot between all the refs, I am pretty sure you need ensure

3:35 tomoj: oh?

3:36 hiredman: yes

3:36 tomoj: ants.clj doesn't have any ensure

3:36 LauJensen1: ensure basically locks the ref from modifications coming from outside your own transaction and gives you the in-transaction value of that ref

3:36 hiredman: I could be wrong

3:37 wavister: i understood the primary reason for ensure being that if you're not modifying a value, but it's dependent on what you are modifying, you should just put a token ensure in there to keep it part of the same data set

3:37 but i'm just reading

3:38 so maybe a doseq is all i need

3:38 hiredman: dependent?

3:38 wavister: i mean dosync

3:38 tomoj: if you're just reading I think ensure is unnecessary, but I am more likely to be wrong than hiredman

3:39 I mean, the problem ensure solves is _write_ skew, huh?

3:39 LauJensen1: If you are using a reference in a transaction, and the output of that transaction affects something else. Then you need to ensure that your ref maintains its value throughout your transaction right? Thats what its there for. yes to solve write_skew

3:40 tomoj: that's if you're only reading one ref and then writing some other ref based on the read value?

3:40 wavister: ok i think we're saying the same thing i just said it funny

3:40 hiredman: I withdraw my earlier statement, I now believe tomoj is correct

3:40 tomoj: you do need a dosync though if you want a snapshot, right?

3:40 LauJensen1: Yep

3:41 wavister: i do want a snapshot. ok I'm good. thankies.

3:44 anyone interested in neural nets around here? i'm writing a basic feed-forward neural net function which i could share if the first round of testing goes ok.

3:56 tomoj: wavister: yep

3:56 I actually started working on some nnet stuff in clojure

3:57 specifically I'm interested in writing an implementation of ken stanley's neat and hyperneat

3:57 the current implementations are all in languages I hate and the code is _nasty_

3:58 wavister: not neat, huh?

3:58 tomoj: I tried digging into one of them and every other line was like `if DEBUG_FOO_FEATURE`

3:58 wavister: i'm not familiar with them

3:58 tomoj: it's pretty cool

3:58 http://www.cs.ucf.edu/~kstanley/neat.html

3:58 or perhaps http://en.wikipedia.org/wiki/NeuroEvolution_of_Augmenting_Topologies

3:59 with neat you evolve neural networks with arbitrary topologies using a genetic algorithm

3:59 with hyperneat you evolve these networks which describe a different network's connections in a multi-dimensional vector space... mind-bending stuff

4:00 very cool thing about hyperneat is you've got this network (they call them CPPNs - compositional pattern producing networks) which describes the connection weights for another network, but the CPPN has infinite resolution

4:01 so if you're, say, doing image processing, and you start out with a 20x20 input layer, you can use the evolved CPPN to give weights for a network with a 100x100 input layer, or a 1000x1000 input layer

4:02 wavister: infinite... so it's continuous, or lazy?

4:02 tomoj: the CPPN is continuous

4:02 wavister: ah nice. analog is back.

4:02 that is sexy

4:02 tomoj: basically the CPPN is a network that takes pairs of node coordinates as input and outputs a connection weight

4:03 so you've got a structure laid out for your neural network, and to get the weights between each pair of nodes, you ask the CPPN, which is a network of compositions of continuous functions

4:04 so you can increase the resolution of your network and the CPPN will give the higher-res network a similar overall structure as the previous low-res version

4:05 wavister: makes sense intuitively, but the "network of compositions" part is fuzzy

4:05 i will definitely do some looking into this

4:06 tomoj: http://eplex.cs.ucf.edu/hyperNEATpage/HyperNEAT.html

4:06 wavister: yes, i found that one

4:06 i'll need to do some reading

4:06 tomoj: unfortunately the papers seem to underspecify the algorithms :(

4:07 and it's really hard for me to understand the code that's been written, especially since even if I could understand what it was doing, I'd still have to figure out a totally different way to do it since this is clojure

4:08 anyway I'd love to take a look at your code sometime

4:08 wavister: well i don't pretend to be immersed in the field, but we could powow on this if you like. i'm semi-active in an AI community

4:09 tomoj: yeah, that'd be awesome

4:09 how long have you clojured?

4:10 here's what I've done so far: https://gist.github.com/8d58e8f912dcaa24e7d1

4:10 it's gross.

4:11 wavister: i haven't been clojuring for long... either that or i learn slow. i feel like a noob still. maybe a month or two

4:11 tomoj: I think that's about how long I've been doing it

4:11 I still feel like a noob as well

5:44 Fossi: hi

5:55 winterstream: Is there a multimethod I can override in order to get the str function to return a string representation of my object?

6:03 tomoj: ~def str

6:04 doesn't look like it

6:04 hiredman: ,(doc print-method)

6:04 clojurebot: "; "

6:04 hiredman: clojurebot: bah!

6:04 clojurebot: Excuse me?

6:05 hiredman: str calls .toString

6:07 tomoj: so you can dispatch printing to a writer on type

6:07 ?

6:07 clojurebot: trampoline is http://groups.google.com/group/clojure/browse_thread/thread/6257cbc4454bcb85/3addf875319c5c10?#3addf875319c5c10

6:07 tomoj: wat

6:08 hiredman: pardon?

6:10 ,(doc *print-dup*)

6:10 clojurebot: "; When set to logical true, objects will be printed in a way that preserves their type when read in later. Defaults to false."

6:11 hiredman: when using print dup there is a multimethod print-method you can hook into

6:29 winterstream: hiredman: Thanks; I'll look into that.

8:11 ambient: is there any better way to express "(if (not (seq foo)) foo (recur (rest foo)))"?

8:11 shorter, more compact

8:11 inside loop/recur

8:11 LauJensen: (if-not (seq foo)) ?

8:12 ambient: there's no (empty foo)? for sequences

8:12 LauJensen: ,(empty? [])

8:12 clojurebot: true

8:12 ambient: cool :p

8:12 now i feel i should've rtfm:d more

8:13 LauJensen: No no thats what we're here for

8:13 ambient: :D nice

8:13 LauJensen: The documentation is where we go, if Chouser fails :)

8:14 hiredman: that looks like last

8:14 or empty

8:15 ,(empty '(1 2 3 4))

8:15 clojurebot: ()

8:15 hiredman: ,(last '(1 2 3 4))

8:15 clojurebot: 4

8:15 Fossi: how do distinct and set compare performancewise?

8:16 ambient: try it with (time)

8:16 hiredman: ~def distinct

8:16 ericthorsen: Is it possible to get a macro to output a def with meta data? (def #^{:private true} fred)

8:17 hiredman: not like that

8:17 Fossi: not with the reader macro

8:17 hiredman: #^{} is reader syntax

8:17 Fossi: at least not if you don't want to read it runtime :)

8:17 ericthorsen: understood

8:17 Chousuke: ~def defn-

8:18 see there for an example :P

8:18 though hm, I guess that's not so good.

8:19 because it doesn't use `

8:20 you can also do `(defn ~(with-meta name (merge (meta name) {:private true})) ...)

8:20 ericthorsen: that is where i was looking

8:20 that is where i got to

8:21 Fossi: hmmm. the repl does not like printing (range 100k) :D

8:21 ericthorsen: Chouser: my problem must be elsewhere...let me take another look. thx!

8:23 Fossi: seems distinct is faster on smaller sets

8:23 which makes sense :)

8:25 Chousuke: distinct is also lazy :p

8:26 LauJensen: ~def distinct

8:29 Gents, I posed this on DZone this morning and for some reason I dont see it in 'new links', why? http://www.dzone.com/links/best_in_class_the_blog.html

8:34 mikem`: ~def println

9:18 icemaze: Hi, I'm thinking about opening a ticket but I'd like some clarification. Is there anyone who can help?

9:22 hiredman: ticket for what?

9:23 icemaze: I have a performance problem where clojure code is MUCH slower than equivalent Java. I read some performance-related articles and applied type coercions but my code is still 250x slower than Java. I was wondering if there might be a problem with my code.

9:24 hiredman: sounds believable

9:24 icemaze: Also, is this a valid reason to open a ticket. I believe it is since on clojure.org it is implied that clojure should have good performance.

9:24 hiredman: have you brought it up on the mailing list?

9:24 (google group)

9:24 icemaze: nope, I tried sending an email but it was rejected. You think I should subscribe?

9:25 hiredman: rejected? are you sure?

9:25 icemaze: Because I wasn't subscribed

9:25 hiredman: the first email snet to the group is modereated so sometimes there is a delay

9:26 icemaze: quote:

9:26 We're writing to let you know that the group that you tried to contact

9:26 (clojure-dev) either doesn't exist, or you don't have permission to post to it.

9:26 hiredman: oh

9:26 wrong group

9:26 ~group

9:26 clojurebot: group is http://groups.google.com/group/clojure/

9:26 icemaze: oh, ok thanks.

9:30 hiredman: ~performance

9:30 clojurebot: http://clojure.org/java_interop#toc46

9:32 icemaze: Thank you again. I'll try a couple of things before posting.

11:25 hchbaw: Hi, I just wrote swank_fuzzy.clj for Emacs/SLIME!

11:28 Please get it from http://gist.github.com/179737 if you like. Thanks.

11:40 Chousuke: hchbaw: neat. did you send it to the swank-clojure maintainer already?

11:40 hchbaw: Chousuke: Yes, I did.

11:52 Chousuke: Are you using SLIME?

11:55 Chousuke: hchbaw: yeah.

11:55 hchbaw: Chousuke: If you using anything.el also, please take a look this,

11:56 Chousuke: http://wiki.github.com/hchbaw/anything-slime.el/commandlistinaction

11:57 Chousuke: That is SLIME + anything.el combination :)

12:00 Chousuke: hmm, I can't seem to get that fuzzy completion to work

12:01 I just get a beep and "insert: Format specifier doesn't match argument type" in *messages*

12:01 is there something I need to do besides applying your patch to swank-clojure?

12:01 hchbaw: Oh sorry.

12:02 I take a look.

12:04 Chousuke: Sorry, SLIME version please?

12:05 Chousuke: hmm, I'm not sure, actually. apparently rather old :/

12:05 it's a git checkout, and the latest commit date seems to be "Sun May 17"

12:07 hchbaw: Sorry, mine is "Thu Sep 3". Using this git://github.com/nablaone/slime.git

12:08 Please upgrade?

12:10 Chousuke: I will, a moment.

12:15 it works now.

12:16 hchbaw: yey!

12:18 angerman: how would we setup a performance meter? To get an idea on how fast clojure is on a given host?

12:21 hiredman: function calls per second

12:24 angerman: hiredman: do we have a benchmark toolbox?

12:24 Chousuke: :P

12:24 hiredman: not that I am aware of

12:25 we could steal some badly written inefficent project euler solution

12:26 call it "one standard clojure" and then on fast machines could say "this machine gets *two* standard clojures!"

12:26 angerman: hmm... maybe some map/reduce flops thing.

12:27 hiredman: it would looks similar to a test

12:27 a set of functions, a set of input, how long does it take the functions to run

12:29 angerman: ok, so we don't have any default solution for that yet.

12:41 duck1123: Can anyone think of any possible reason why I would be getting a no such var exception when that the fn I'm calling is in a ns that's being used?

12:42 I can't understand why it's not seeing it, this was a simple refactor

12:42 hiredman: how are you calling it?

12:42 Lau_of_DK: paste it?

12:43 duck1123: hold on

12:49 http://gist.github.com/181867

12:49 sorry, there's a lot to this, and I tried to cut it down

12:49 I'm almost ready to just publish this thing openly, but I don't want to publish all the history

12:50 I have tried with and without fully qualifying the call to redirect

12:51 hiredman: what happens if you declare redirect?

12:51 duck1123: in model.auth?

12:52 it's declared in view

12:54 I'm in the process of factoring out all the calls to redirect and moving them to view.auth, but I just can't understand why it's not seeing it

12:54 and as my build is failing, I can't get into slime

12:55 LauJensen: Its when you load the namespace that it fails ?

12:55 hiredman: can you put a (use 'net.mycyclopedia.view) right after (ns …) in auth

12:56 duck1123: This is during AOT compile

12:57 the auth module gets compiled early on in the build process

12:57 hiredman: you know

12:57 you have a circular dependency there

12:58 I wonder if that is the problem

12:58 duck1123: you're right

12:59 I just added the dependency on view in model.auth to support the refactor of redirect

12:59 my models shouldn't have a dependency on anything in view

13:00 I guess I'm just going to have to take this refactor a bit deeper

13:02 LauJensen1: duck1123: the paste was a little confusing to me, but one time I felt like Clojure was running around corners with me, I had a 'used' or 'required' a namespace before one of its dependencies, and it took a while to track down :)

13:04 duck1123: yeah that's definitely what's going on here. It's a design flaw on my part really, but I only uncovered it when I went to go correct it.

13:05 This auth module is the tricky one because it's the only one that doesn't correspond to a table in my database.

13:05 LauJensen1: Ok, you sorted it out now ?

13:06 duck1123: not yet, but I'm confident that when I remove any reference to redirect from model.auth, the problem will go away :)

13:07 LauJensen1: Alright - If not, put it on Gitorious (next to ClojureQL), and we'll have a look :)

13:09 duck1123: I'm a clj-record guy myself

13:09 I forked clj-record to give it some very nice features

13:10 I've been toying with the idea of re-writing clj-record so that it uses clojureql internally

13:10 LauJensen1: I didnt know about clj-record, whats it do ?

13:11 duck1123: it's an orm for clojure

13:11 let me paste some code so you can see it in action

13:11 LauJensen1: ~clj-record

13:11 clojurebot: Excuse me?

13:11 LauJensen1: Great, thanks

13:12 duck1123: http://gist.github.com/181873

13:12 model.statement from my code

13:13 look at find-records

13:13 LauJensen1: I see, interesting

13:14 duck1123: I think one of the simpler files may have been netter

13:14 but i add metadata of the model on every element returned

13:14 that allowed me to write multimethods that dispatched on the type of record

13:15 LauJensen1: Yea, thats what we do in the backend actually

13:17 duck1123: see, I had to hobble together my own sql generation for my branch, I know I could use clojureql and benefit from it

13:17 but if i recall correctly, there was something that i was doing in mine that couldn't be done in yours

13:18 do you limit?

13:19 LauJensen1: I think kota just implemented it, its on our task list at least

13:19 And in some sense, you get take for free, because resultsetseq is lazy :)

13:23 duck1123: John and I have some differences of opinions on names and whatnot, that's why my branch wasn't fully merged, but it's been working great for my purposes

13:23 I swear, I deleted so much code, it was sad yet great

13:23 angerman: is there some pretty-printer for clojure that does backet indentation?

13:24 duck1123: I think pprint is the best you get

13:25 I've been wanting to make generators for models for my project, but I couldn't find anything I liked, so I did something else

13:29 Fossi: hchbaw: looks cool. will try

13:31 hchbaw: Fossi: Good luck :)

15:08 cemerick: has anyone taken the time to implementing RB trees (or some other balanced tree construction) using zip?

15:08 implement*

16:13 rhickey: cemerick: vs sorted-set/map?

16:13 cemerick: rhickey: yeah, something that could be extensible / easily augmented

16:14 rhickey: extended in what way?

16:15 cemerick: e.g. for interval trees

16:16 aggregate data, more generally

16:17 rhickey: doesn't a user-supplied comparator let you do what you want?

16:18 cemerick: no, because efficient window queries given overlapping intervals requires maintaining a :max entry on each node

16:21 rhickey: do you have an example of a RB tree that would let you extend it in this way?

16:22 danlarkin: technomancy joins to roll some heads

16:22 technomancy: that's right... heads: watch out

16:22 cemerick: Scala has a generalized RB tree framework that I used back in the day (e.g. 1.5 yrs ago, maybe more) to decorate nodes as necessary with aggregate data. They just went through a big refurb in their data structures though, so I've no idea whether that's there anymore.

16:23 tree-balancing is just a painful thing to keep dealing with...seems like a problem worth solving once (and for all?) well, in a way that others can just focus on the data model.

16:24 rhickey: it's not just a decoration though, you need to maintain it during rotations etc, right?

16:25 cemerick: yeah; if I remember right, the scala framework had an interface one implemented where you could plug in implementations for adjusting nodes on a right rotation, left rotation, etc.

16:25 The pattern-matching folks are just laughing at me now. :-)

16:25 technomancy: danlarkin: how goes?

16:26 danlarkin: technomancy: good... I'm finishing my re-setup after reformatting. *grubmles*

16:26 technomancy: danlarkin: ah, that can be a pain if you haven't automated it.

16:26 at least now your filesystem is case-sensitive! =)

16:28 danlarkin: yes! I'm a grown up now

16:50 dthomas: Hi. Is there a good way to get the value associated with all the base keys, in order, from a struct "instance"?

16:52 Or, alternatively, is there a way to get all the base keys of a struct [in order]?

17:01 jensli: dthomas, just to create one and call (keys ...) on it should work i think.

17:02 Oh, you said values...

17:02 Fossi: hmmm. seems send-body of http.client only supports strings, maps and InputStreams. what is the prefered way of converting a byte-seq into one of them?

17:02 ByteArrayInputStream?

17:03 dthomas: jensli: (keys some-struct) would return all the keys, not just the base keys, right?

17:03 technomancy: Fossi: that would be my guess

17:03 Fossi: do i need to call anything on the seq?

17:03 dthomas: jensli: My goal is to get the value of all base keys in the struct instance, but I could easily accomplish that if I had a way to get all the base keys in the struct "type."

17:03 jensli: Then create a new struct, call (keys ...) use those keys to extraxt the right values of your struct, with select-keys?

17:04 Fossi: to-array or such?

17:04 jensli: Should be a cleaner way maybe.

17:05 dthomas: jensli: Good point, but agreed that seems ugly.

17:05 jensli: No, not select-keys, but something else.

17:06 You could make a global list *your-struct-keys* so you dont have to do that every time.

17:06 dthomas: Maybe there's an exposed but undocumented way to get the struct keys off a PersistentStructMap.Def, I haven't look at its source.

17:06 jensli: Yeah, that's what I'm doing right now.

17:06 Fossi: "[Ljava.lang.Byte; cannot be cast to [B" hmmmm

17:08 and there's no "byte-array" either

17:09 * Fossi scratches head

17:09 Chousuke: (into-array Byte/TYPE ...)?

17:10 Fossi: i was about to ask that

17:10 Chousuke: still, that'll make a full copy of the seq :/

17:10 best would be a seq -> InputStream adapter I guess.

17:11 Fossi: well, it's not used often, so i don't care for now

17:11 i'm just uploading user images :)

17:11 way to the server works

17:11 now, i just need to fix the other way around

17:15 technomancy: danlarkin: merging a few patches from various contributors

17:15 or clojure-http-client

17:16 danlarkin: technomancy: oof, haven't looked at that in a while

17:22 technomancy: yeah, me neither

17:23 some of these patches are 2 months old

17:23 course, one of these starter kit patches was from February... /me hides in shame

17:23 Fossi: reminds me to finally commit the couchdb patches

17:24 just added multi-key POST today

17:27 technomancy: nice!

17:31 Fossi: hmmm. damn. somehow i get a String array back from attachment-get

17:34 ok. seems to be on purpose

17:34 kinda defies my try of saving the user images in couchdb

17:34 but that's for tomorrow then

17:34 g'n8

18:03 dthomas: Is there any kind of consensus about the wisdom of using 1.0 for development? Should I be using Clojure (and contrib) from Git master instead? Are they typically usable?

18:04 ambient: been wondering the same thing, if i should use 1.0 instead of git master

18:04 dthomas: For example I think I've found that contrib.http.agent has changed significant post-1.0, so the docs on the web are unhelpful. (I can get past that issue; but I'm wondering if it's an indication that I'll be fighting an uphill battle by using 1.0.)

18:07 technomancy: dthomas: using the clojure-1.0-compat branch of contrib is recommended in that case

18:07 sticking with 1.0 is definitely the safer route

18:07 dthomas: Pre-1.0 I was used to updating every so often, and updating contrib and all the Emacs stuff along with it, including the occasional breakage or out-of-sync components. It wasn't a huge problem, but I figured I could avoid it by using 1.0. I'm wondering if the majority of the community is working off of master, though, not the release.

18:08 technomancy: Yeah, I found the 1.0 contrib branch.

18:08 clojurebot: technomancy is to blame for all failures

18:13 technomancy: clojurebot: botsmack!

18:13 clojurebot: Gabh mo leithscéal?

18:14 technomancy: dthomas: clojure-mode now only syncs against last-known-good revisions to avoid that problem

18:15 I suspect the majority of clojure devs stick with 1.0. I generally only check out master if I'm working on patches.

18:17 dthomas: technomancy: Good point of data, thanks.

18:22 technomancy: calling it "data" might be a little generous... it's a guess. =)

18:25 dthomas: technomancy: Well, it's a data point nonetheless, and from someone who seems to have a lot more Clojure experience than I do, so your guess is probably much better than any I'd make. :)

20:56 triddell: so where on assembla should I submit a patch against an issue?

20:57 issue #104 requires a simple patch

20:57 but I don't see where I create a new activity with an attachment

20:58 if that is the right way to submit a patch

21:23 Chouser: triddell: if you're a member you should be able to attach a file to the ticket

23:09 poet: Any pointers to some resources about packing an application for distribution?

Logging service provided by n01se.net