#clojure log - Aug 26 2010

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

0:54 ihodes: anyone home? got a q re: a simple function

0:54 mebaran151: I could try to help

0:55 ihodes: alright, so there's this post by cgrand, and it's about finding the fibo nums. (here: http://clj-me.cgrand.net/2010/06/04/primitive-support-for-fns/) and he's saying a supefast version is taking ~800ms on his new laptop. this version is many lines of code...

0:55 ,(def fibs (map second (iterate (fn [[x y]] [y (+ x y)]) [0 1])))

0:55 clojurebot: DENIED

0:56 mebaran151: ihodes: don't def

0:56 ihodes: (take 39 (map second (iterate (fn [[x y]] [y (+ x y)]) [0 1])))),

0:56 ,(take 39 (map second (iterate (fn [[x y]] [y (+ x y)]) [0 1]))))

0:56 clojurebot: (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986)

0:56 ihodes: that takes 0.059ms on my laptop…

0:56 ,(time (take 39 (map second (iterate (fn [[x y]] [y (+ x y)]) [0 1])))))

0:56 clojurebot: (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986)

0:56 "Elapsed time: 0.873 msecs"

0:56 mebaran151: alright?

0:57 ihodes: well, i feel as though i'm missing something.

0:57 mebaran151: that it's going that fast?

0:57 ihodes: my little fibo fn is orders of magnitude faster than cgrand's

0:57 and i guess rich's too

0:57 yeah…i must be not seeing the whole picture

0:57 mebaran151: ihodes: his fib's I think were purposefully inefficient

0:58 they were meant to show how fast math can be

0:58 because you're using iterate, you're caching the intermediate results (as though you'd memoized the functions)

0:59 ihodes: "computes (fib 38) on my laptop in 650ms where my (or even Rich’s) best http://clj-me.cgrand.net/2010/06/04/primitive-support-for-fns/"

0:59 mebaran151: I don't think there's do: it was just a numeric benchmark

0:59 ihodes: "took 2 seconds"

0:59 (later amended to 800ms)

1:00 mebaran151: see, his fib is purpsoefully bad

1:00 he's not trying to make it fast

1:00 he's trying to make a lot of math ops

1:01 it's like when people demonstrate the factorial function using recursion: it nicely shows the power of recursion: really a loop is probably a lot more efficient

1:03 Bahman: Hi all!

1:03 ihodes: megaran151: haha alright, i figured i was missing something there. thanks

1:08 mebaran151: no problem

1:09 this misunderstanding shows the most important part of programming: the right algorithm can beat the most clever compiler every single time

1:09 ihodes: exactly what i was thinking.

1:10 though i wish there were an even nicer way to express the fibos than the one i have (above)

1:10 mebaran151: the iterate seems pretty nice to me

1:10 ihodes: i know... but mapping second over it... inelegant! haha

1:11 mebaran151: nah, that's par for the course in functional programming: you have to keep your state in your arguments

1:12 I think they used exponentially more math ops than you do in the iterate version

1:12 you could just use plain ol' loop and recur too, but I think the iterate version is a lot nicer

1:13 ihodes: it's certainly the favorite one of the far too many i've thought up haha

1:14 mebaran151: you could have also kept some atom local to your function and mutated that to maintain your state, but that wouldn't have been nearly as functional

1:14 ihodes: my favorite* but there's got to be some construct that would allow me to drop the mapping

1:14 oh that would've been AWFUL! :P

1:14 mebaran151: you could probably do it using the lazy-seq macro, but that would be less convenient

1:17 ihodes: true, but still a little more complex than before. thank you for the help! i'm off to bed

1:21 tomoj: ,(time (dorun (take 39 (map second (iterate (fn [[x y]] [y (+ x y)]) [0 1])))))

1:21 clojurebot: "Elapsed time: 1.371 msecs"

1:21 bartj: trying to avoid reflection warnings

1:21 why is this wrong: (map #(String. ^Byte % "UTF-8") (byte-array 100))

1:24 tomoj: there is no such string constructor

1:24 hiredman: http://gist.github.com/550864

1:24 Chousuke: do you really want to transform each byte in the array into a string? :P

1:25 bartj: Chousuke, yes (but the example I give is slightly fake)

1:25 hiredman: ^- totally awesome using interpreter to figure out which classes are referenced, without executing the code and generatng an import list

1:26 Chousuke: bartj: that's weird though. You'll get completely weird results if you have anything but ASCII text :/

1:26 mebaran151: where did you get generate-imports?

1:26 hiredman: I wrote it

1:26 mebaran151: ah that would be neat to have in IDE to get all the imports upfront

1:26 hiredman: brand spanking new arkham.analytics

1:26 bartj: ok, let me clear myself

1:26 hiredman: right

1:27 mebaran151: what's arkham.analytics (other than an awesome name)

1:27 bartj: I have a Java byte array and need to get a "UTF-8" string as the output

1:27 Chousuke: bartj: you don't need map for that.

1:27 hiredman: http://github.com/hiredman/Arkham

1:28 Chousuke: bartj: String has a constructor for byte arrays IIRC.

1:28 bartj: er, I mean an array of byte-arrays

1:28 Chousuke: ah.

1:28 bartj: if you're getting reflection warnings, hint the arrays as ^bytes

1:29 bartj: currently I do: (map #(String. % "UTF-8") array-of-byte-array)

1:29 I tried to use ^Byte to avoid the reflection warnings

1:29 Chousuke: that specifies the type as Byte, not a byte array :)

1:29 ^bytes is shorthand for a byte array type tag.

1:30 At least IIRC :P

1:30 tomoj: ,(meta ^bytes {})

1:30 bartj: Chousuke, gee thanks, what is the longhand ;)

1:30 clojurebot: {:tag #<core$bytes clojure.core$bytes@1219ee8>}

1:30 tomoj: weird

1:30 Chousuke: hmm

1:30 maybe not.

1:30 hiredman: arkham.analytics can generate the correct import declaration for arkham.core

1:31 that may also mean the interpreter can run the interpreter

1:31 Chousuke: if ^bytes doesn't work try ^"[B"

1:32 hiredman: you need to test that. D:

1:36 hiredman: damn

1:36 nope

1:37 well I know I am missing deftype*, reify* and set!* support

1:40 mebaran151: hiredman: it reminds me of Ruby's evil.rb

1:52 bartj: Chousuke, bytes does work, thanks!

3:21 LauJensen: Good morning all

3:22 Bahman: Morning LauJensen!

6:35 fliebel: morning

6:35 esj: salut.

6:35 raek: god morgon

7:18 vu3rdd: LauJensen: great blog post!

7:19 LauJensen: vu3rdd: Wow, thanks! I'm a little out of familiar waters when not blogging about Clojure :)

7:20 vu3rdd: LauJensen: :) I am also always looking to improving productivity and am an emacy guy..

7:21 But I like those non-emacs stuff in your blog post the most. I think they are all very important and right on.

7:21 LauJensen: Great, thanks

7:22 fliebel: LauJensen: Where can I find your blog? vu3rdd made me curious.

7:22 LauJensen: bestinclass.dk

7:22 vu3rdd: http://bestinclass.dk/index.clj/2010/08/developer-productivity--the-red-pill.html

7:22 fliebel: I've seen that url berfore...

7:22 LauJensen: I think there's almost 35 posts on Clojure, and 2 on misc

7:24 And for those of you using Conkeror, you can browse all posts just hitting ]]

7:29 fliebel: LauJensen: What is the magic in Conkerer? That's what ships with KDE, right?

7:29 LauJensen: fliebel: No no no... NO!

7:29 Thats Konqeror

7:30 fliebel: LauJensen: Ah, you scared me :P

7:30 LauJensen: Conkeror is a webbrowser which adheres to Emacs standards. There's virtually no UI. You hit 'f' to following a link, 'g' to enter a URL, M-x some-command to run arbitrary commands. B to go back, F to go forward etc..

7:30 Its very, VERY fast

7:30 In terms of the UI. Its Mozilla under the hood, so perf like Firefox

7:31 fliebel: LauJensen: I'm a vin and webkit user ;)

7:31 *vim

7:31 bobo_: think there is a plugin for firefox that does that, but with vim commands

7:31 LauJensen: fliebel: Then you will frown upon all talk of productivity :)

7:32 fliebel: *frowns*

7:34 LauJensen: I'm just reading that your site is 'baked' as you call it. Amazing :)

7:34 LauJensen: yea its wonderful :)

7:37 fliebel: LauJensen: But you do run some script to 'log' comments?

7:37 LauJensen: No scripts - The submit form sends the comment to the backend where Moustache is waiting for it. Then its sent into a moderation queue, once I approve its directly baked into the html file

7:39 fliebel: That is what I mean, you run Moustache at the back to catch the comments.

7:39 spariev: LauJensen: great post! one question, though - does #clojure channel count as Social network :) ?

7:40 fliebel: LauJensen: Do you have a search function?

7:40 esj: spariev: no, too old skool

7:40 LauJensen: spariev: No

7:40 fliebel: grep goes a long way when everything is html :)

7:40 spariev: and thanks :)

7:41 fliebel: LauJensen: I'd generate a jsonp index and do it all in JS.

7:41 LauJensen: fliebel: I wouldn't, because I want to use Enlive for reading the data

7:42 fliebel: LauJensen: ? So how would you do it?

7:42 LauJensen: fliebel: Its open source

7:43 fliebel: LauJensen: Where is it?

7:43 LauJensen: fliebel: Right where the baked blogpost says it is :) http://github.com/LauJensen/bestinclass.dk

7:44 fliebel: LauJensen: Hadn't reached the bottom yet.

7:44 LauJensen: Sorry, no rush

7:45 spariev: btw, any recommendations on tiling wm for windows ? others, than "use Linux" :)

7:45 LauJensen: spariev: Hmm, no I think you stole my best one :)

7:45 spariev: heh

7:46 LauJensen: But are you planning on doing serious development on Windows? Seriously? :)

7:47 spariev: well, I have Ubuntu at home, but have to use Windows at work

7:48 gonna try bug.n http://www.autohotkey.net./~joten/

7:49 LauJensen: Sweet, that almost looks like Awesome

7:49 esj: spariev: i was forced into windows for a while 2 years back, at that time there was no tiling wm.

7:49 I quit that job after 3 months

7:50 windows is too painful

7:51 LauJensen: True, I sympathise esj that you had to go through that

7:52 esj: seriously, I won't work in a windows shop. period.

7:52 cemerick: wow, you'd think this was #linux or something :-P

7:53 LauJensen: hehe

7:53 spariev: esj: actually, usually I develop remotely on linux servers, but for other MS SQL/Office etc-related work I have to keep windoze on my desktop

7:53 LauJensen: spariev: ?!!? Its not even policy thats forcing you?

7:53 Why dont you jut boot MS SQL, Office etc, under Linux ?

7:53 opqdonut: can't you just run a vm

7:53 LauJensen: The only thing you cant work your way out of, is policy restrictions

7:59 bobo_: i dont find windows THAT horrible to work in

8:00 opqdonut: i find

8:00 cygwin alleviates it a bit

8:00 but the wm is horrible

8:00 spariev: opqdonut: I considered vm, but stuff I do with MS SQL and our in-house win-only apps are at times resource-heavy and it was dog-slow under vm

8:00 cemerick: Windows over linux any day of the week here. :-P

8:00 fliebel: LauJensen: Did I mention defn and I are going to do a 'baker'? that is why I'm so interested in your static site generator.

8:00 LauJensen: fliebel: No you didn't, what are you baking?

8:01 cemerick: please, if you're going to be unintelligent, please be quiet about it :)

8:01 * cemerick facepalms @ LauJensen

8:02 LauJensen: thanks

8:02 fliebel: LauJensen: We're doing about the same as you did. Get our blogs to run on Clojure by writing a baker. With the difference that we're taking a more general approach and that I don't have a VPS to run Moustache on, so it'll be even more static than yours.

8:02 cemerick: LauJensen: it's a large, wide world. Different strokes for different folks, as they say.

8:03 LauJensen: fliebel: Great, I will look forward to seeing that, are you open sourcing it ?

8:03 fliebel: LauJensen: We named it Utterson, after the character in Jekyll(ruby) and Hyde(python). It's on github ;)

8:03 LauJensen: hehe, alright

8:04 Utterson... man thats almost as terrible as 'madison', why arent anybody grabbing 'Clabango' ? :)

8:04 fliebel: LauJensen: I'm thinking about a git based workflow for publishing, possibly using gh pages.

8:05 I'm even trying to come up with something for comments that does not involve running something special on the server, but haven't figured that out yet.

8:05 LauJensen: cemerick: If you fly in for Conj Labs Frankfurt, I'll be happy to help you install Arch

8:06 fliebel: LauJensen: There are actually Clojure conferences in europe?!

8:06 cemerick: LauJensen: Thanks, but no thanks. I've had enough desktop linux pain for one lifetime.

8:06 LauJensen: fliebel: http://conj-labs.eu

8:06 fliebel: cemerick: How about BSD?

8:06 cemerick: fliebel: same-same

8:06 LauJensen: cemerick: The pain comes from ignorance, once everything is set up correctly, its a very helpful system to be on

8:07 cemerick: LauJensen: this is just like our emacs disagreement -- I've better things to do with my time on earth than screw around with window managers and the like

8:07 fliebel: LauJensen: around €1000 is a bit much for a student like me.

8:07 cemerick: nevermind getting sound cards to work :-(

8:07 LauJensen: cemerick: You're the lumberjack who's too busy to sharpen his axe. So instead of spending 2 days on getting setup, you spent 15 years working at 70% speed

8:08 fliebel: *thinks cemerick should sing the lumberjack song*

8:09 LauJensen: cemerick: Im not trying to give you a hard time, so if you're working on a hateful rant now, you can save it for later :)

8:09 opqdonut: I'm not convinced that what works for LauJensen works for everybody

8:09 but for me, yes

8:09 except I prefer opera >:)

8:09 LauJensen: opqdonut: Does it have keyboard browsing?

8:09 fliebel: cemerick: Don't want to be a Mac fanboy, but I havea working sound card, window manager and Unix power ;)

8:10 opqdonut: LauJensen: pretty much, yes

8:10 fliebel: LauJensen: No, mouse gestures ;)

8:10 LauJensen: haha

8:10 cemerick: LauJensen: I'm pretty sure I've never hatefully ranted at anyone. :-(

8:10 opqdonut: LauJensen: lots of one-key shortcuts, navigating with the keyboard is easy

8:10 LauJensen: cemerick: Im glad - I just wanted you to know that it wasnt personal, just in case you were warming up :)

8:10 opqdonut: , starts a search for links

8:10 clojurebot: java.lang.Exception: Unable to resolve symbol: starts in this context

8:10 opqdonut: so mostly I just navigate with ,<typesomething><return>

8:11 LauJensen: I particularily like how 'f' searches both for links and input fields

8:12 fliebel: LauJensen: http://github.com/pepijndevos/utterson There is and 'old' branch, containing our previous efforts. We both walked off, met yesterday and started over with a clean slate :)

8:12 LauJensen: Ouch :)

8:13 fliebel: LauJensen: So there is a workish generator in 'old', an not very much in 'master', but 'master' is going to be awesome.

8:13 LauJensen: Are you guys using Enlive templates to generate the html ?

8:14 fliebel: LauJensen: 'old' is using the [html [head]] thingy from contrib, the new one… enlive if it depends one me.

8:14 LauJensen: Enlive is like DOM for Clojrue, right?

8:15 LauJensen: Ok - I dont think I could recommend any Clojure lib more than Enlive at the moment, its that good

8:15 fliebel: Enlive is 2 things. 1) Selectors that work like CSS selectors, and 2) Templates which allows you to transform data into html using those selectors

8:15 fliebel: LauJensen: Do you write posts in Markdown, Textile, plain HTML or something else?

8:15 LauJensen: It was a couple of relatively simple (take 'relatively' loosly), that allowed me to import my entire Wordpress blog into html

8:16 fliebel: I write them in a nice WYSIWYG editor

8:16 fliebel: LauJensen: What?! You? a productivity emacs guru? :P

8:17 LauJensen: Yes ma'am

8:17 cemerick made me :(

8:18 fliebel: My blog is currently on Posterous, but I find myself writing posts in markdown all the time, becasue wysiwyg editors screw up my html. especially things containing code.

8:18 LauJensen: Well, it helps when you write the stuff yourself

8:19 You can install bestinclass locally and launch the admin.clj file to bring up the admin interfaces, browse to /editor to make a blogpost, hit submit to send it to moderation in /admin

8:20 fliebel: LauJensen: Ah! so you wrote a wysiwyg editor with emacs keybindings? Or just plain old… what's the WP thing called...

8:20 tinymce

8:20 LauJensen: fliebel: No I use the ckeditor, but I parse the results myself (not doing much to it), and the emacs keyboard bindings I get for free since I use Conkeror

8:21 fliebel: LauJensen: Okay, you win… I still prefer Markdown though.

8:21 LauJensen: I might prefer it aswell after seeing Utterson

8:22 fliebel: LauJensen: Are you runnign bestinklass.tk on a private server?

8:23 LauJensen: I have no association with bestinklass.tk

8:23 fliebel: *bestinclass.dk

8:23 LauJensen: oh, yes thats on a personal server

8:24 But I suppose GAE could be used if you wanted to

8:24 The only thing which is very non-general about my solution is its commitment to nginx - You need to run on a linux host (ofc) and you need to have the default logging module enabled

8:24 fliebel: LauJensen: That is something… Can you run any ring app on GAE's java api?

8:25 LauJensen: I would think so

8:25 (haven't tried)

8:25 There are a few annoying restrictions like no threading, no concurrency semantics

8:25 esj: seduced by the power of the dark screen he has become....

8:26 fliebel: LauJensen: Maybe only run a comments module on GAE, and keep the rest safe and warm on my local computer.

8:27 Might even poke that together with Python...

8:27 LauJensen: fliebel: Yea, I considered outsourcing comments to DISQUS, but I think my solution is more elegant.

8:27 You would have to modify the queue though, as its actually handled by an agent right now, but that should only be a small workaround

8:27 sunkencityryleh: I've run clojure on appengine but I've found the environment being a little too much work to get to run smoothly

8:28 LauJensen: Something like a comments engine could nearly run on a C64, theres no work involved

8:28 fliebel: LauJensen: DISQUS had spam in its sample form when I last looked, so I'm not trusting them. Your solution is very elegant if you have access to a good server.

8:29 good server != shared php host

8:29 LauJensen: good rule of thumb :)

8:29 I didn't know about the spam, scary

8:29 They are in wide use

8:30 fliebel: LauJensen: Maybe I'll device something with Twitter or Facebook to handle my comments :D I've also thought about merging gists and other crazy things.

8:30 LauJensen: oh no :(

8:31 fliebel: LauJensen: Yea, that's bad :(

8:32 LauJensen: I think the gist idea is rather interesting, but not very workable.

8:32 chouser: I've had knocking around in my head ideas for a sort of split server for blogs and websites, where the bulk of the content is handled by a static server, whose content is regenerated on demand (such as when a comment is posted) by somethat that can be slower to start (like GAE) or sometimes unavailable (like a server at home)

8:34 LauJensen: fliebel: I think its a little like stealing their capacity

8:35 fliebel: LauJensen: It is, and it wouldn't work anyway.

8:35 LauJensen: chouser: I have actually pondered a system like that myself

8:36 fliebel: LauJensen: I f you find an mbox parser for Java, you could handle comments by email :)

8:37 LauJensen: fliebel: hmm, thats not a bad idea. Just use maildir instead and you've got plaintext

8:37 Actually that would be super simple to set up

8:37 Just configure a dovecot to receive and distribute

8:38 mrBliss: If anyone's interested, here are my dotfiles (Emacs, Conkeror, Zsh etc) http://github.com/mrBliss/dotfiles

8:38 LauJensen: mrBliss: Thanks

8:38 fliebel: LauJensen: Even my PHP host has an email server built in. Just need to fetch and parse them.

8:40 LauJensen: yea, so fetchmail works with maildir I believe

8:43 fliebel: LauJensen: The interesting thing is how to match mails to posts.

8:44 LauJensen: Shouldnt be a problem

8:44 I dont recall how I do it now, but I wouldnt be surprised if I just inspect the referer field in the header of the POST request

8:46 fliebel: LauJensen: emails don't have a referrer, do they? or are we talking about different things?

8:46 LauJensen: No they dont, but Im just saying, but the info in the email somewhere and scan for it, emails have headers as well

8:48 fliebel: LauJensen: Tell me about it… :S They have a message ID and a lot of crap about through which servers it traveled.

8:49 LauJensen: You could of course put something in the subject line to identify the post.

8:50 chouser: I think you can put a subject in a mailto: url

8:50 LauJensen: yea

8:50 and body as well

8:50 fliebel: chouser: Yea, you can put a whole lot of gunk in the mailto url.

8:51 LauJensen: but anyway, its a non-problem

8:51 fliebel: I agree

8:52 chouser: the biggest issue with comments, I think, is spam.

8:52 LauJensen: chouser: I haven't had a single spam comment since I added the lisp captcha

8:52 And I had ... MANY ... before :)

8:53 fliebel: Security trough obscurity is something when you write captchas ;)

8:54 LauJensen: If it works, it works :)

8:54 And since its a lisp specific captcha, I can do more of the language comparisons without getting any flame :)

8:54 fliebel: Millions of spam bots are programmed to spam wordpress blogs and circumvent re-captcha and akismet. No soe many attack bestinclass.dk

8:55 (the platform, not the specific blog)

8:57 *waiting for defn to get started*

8:57 raek: I get a "dot already refers to: #'net.licenser.sandbox/dot in namespace: se.raek.trattern" when I try to re-evaluate the ns declaration of the namespace se.raek.trattern

8:58 anyone else have this problem?

8:58 LauJensen: fogus: thanks for putting my article on HN :)

8:58 fliebel: *votes*

8:59 LauJensen: *thanks* :)

8:59 fliebel: *gets lost in reading HN*

9:06 alekx: 1. what is the essential tool set for a clojure-man?

9:06 2. is there a Sinatra-like web framework in Clojure?

9:06 MrHus: alekx: compojure

9:06 alekx: (newbie questions for learning purposes)

9:06 LauJensen: wow, 4 points and Im already #5 on HN frontpage :) thanks guys

9:07 MrHus: http://github.com/weavejester/compojure

9:07 LauJensen: alekx: A very minilistic and interesting web framework is Moustache, be sure to check it out

9:07 fliebel: LauJensen: I suppose it multiplies points by the inverse time since the submit, or something like that :P

9:07 alekx: LauJensen: is it that "Mustache"

9:08 LauJensen: Hmm

9:08 fliebel: alekx: No, that is a templating engine

9:08 LauJensen: http://github.com/cgrand/moustache

9:08 alekx: http://mustache.github.com/

9:08 LauJensen: nono alekx, http://github.com/cgrand/moustache

9:09 alekx: got it... so I got compojure (heard of it before) and moustache... that's good enough for now

9:09 what about the "toolkit"?

9:09 fliebel: alekx: Dangerous questing with all these vim and emacs people in one chanel ;) haha

9:09 alekx: are there any essential tools that would be recommended to have around? right now I'm just using clojure w/ jline

9:10 MrHus: alekx: leiningen is a must

9:10 http://github.com/technomancy/leiningen

9:10 alekx: I know... I've tried to avoid any mentions of editors/IDEs/etc.

9:11 leiningen is sort of Ant + Maven, right?

9:11 fliebel: I personally have nothing but clojure, contrib, leiningen and a modal editor ;)

9:11 MrHus: alekx: correct

9:11 fliebel: How about a nice debugger?

9:12 alekx: I hope IntelliJ will help me there... but being at the beginning I'm not really sure I need it so soon

9:12 MrHus: fliebel: Are the nice clojure stacktraces not enough.

9:12 zmila: ,(apply * [])

9:12 clojurebot: 1

9:13 alekx: is there a link to the core/contrib APIs?

9:13 MrHus: http://richhickey.github.com/clojure-contrib/

9:13 fliebel: It;s right on the homepage I think, or most of the time on top of google.

9:14 alekx: the format probably tricked me :-)

9:14 thanks

9:14 raek: http://clojure.github.com/clojure-contrib/ is the new page

9:15 the official repository is now at github.com/clojure (was at github.com/richhickey before)

9:16 LauJensen: alekx: A good slime setup and jvisualvm takes you a looong way

9:16 In terms of debugging

9:16 alekx: slime?

9:16 clojurebot: slime-install is an automated elisp install script at http://github.com/technomancy/emacs-starter-kit/blob/2b7678e9a331d243bf32cd8b591f826739dad2d9/starter-kit-lisp.el#-72

9:16 n2n3: ,()

9:16 clojurebot: ()

9:16 LauJensen: alekx: Slime is SUPER LIST INTEGRATION MODE for EMACS


9:16 sexpbot: alekx: Slime is SUPERIOR LIST INTEGRATION MODE for EMACS

9:17 LauJensen: :)

9:17 alekx: looks like the discussion is going the direction I wanted to avoid initially :)

9:17 LauJensen: alekx: With it, you get to set breakpoints in your code, inspect locals, lookup source code, etc etc

9:17 Oh sorry, go on :)

9:17 mrBliss: LauJensen: wikipedia tells me it is Superior Lisp Interaction Mode for Emacs ;-)

9:17 alekx: I suck at emacs... used with new fancy IDEs and vim

9:17 LauJensen: mrBliss: :(

9:18 raek: alekx: what was compojure 0.3 is now (well basically, at least) split up into Ring (middleware and servlet containers), Hiccup (HTML generation) and Compojure 0.4 (Routing)

9:18 LauJensen: alekx: I sucked at Clojure once, didnt stop my progress though :)

9:18 raek: Clout as well?

9:18 alekx: and I guess I'll be sticking with those for now...

9:18 raek: Moustache is a small and well documented routing lib, really recommend it

9:19 hrm, what did clout do again?

9:19 mrBliss: alekx: I have been tweaking my tools non stop since I started with Clojure (13 months ago)

9:19 alekx: I guess it's one thing to suck at a language and another to an env/editor/etc

9:19 MrHus: I don't agree with emacs for a beginner, there's just to much to lean before you can even start with clojure.

9:19 LauJensen: Wow, Im #1 on HN now :)

9:19 * LauJensen enjoys the moment while it lasts

9:19 LauJensen: :)

9:20 n2n3: and there's a slimv.vim

9:20 alekx: anyways... no religious/vim vs emacs/vegan vs non-vegan flamewars for me :D

9:20 fogus: LauJensen: No problem. I liked it.

9:20 raek: ok, so if compojure routing was split off into clout (correct?), what is left in compojure then?

9:21 LauJensen: fogus: I appreciate any and all help I can get, to help spread the FUD :)

9:21 MrHus: raek: glue code

9:21 LauJensen: raek: A list of imports and a little routing helper I think

9:21 raek: right.

9:22 LauJensen: So again, learning both Moustache and Enlive is seriously well spent time

9:22 MrHus: I just hope ring gets to be de defacto standard, its really easy to make a small framework around it.

9:23 LauJensen: MrHus: It already is

9:23 Both Compojure, Conjure and Moustache rest fully on Ring

9:23 fliebel: It would be nice to have some heroku-style ring hosting...

9:23 mrBliss: What's the best way to interact with PostgreSQL from Clojure?

9:24 fliebel: LauJensen: Do you know anything about aleph + ring?

9:24 LauJensen: fliebel: A little

9:25 mrBliss: I recommend trying contrib.sql, theres a wiki page that shows how with psql

9:25 MrHus: http://en.wikibooks.org/wiki/Clojure_Programming/Examples/JDBC_Examples#DataSource_-_PostgreSQL

9:25 LauJensen: Which my lovely assistant just fetched for you

9:25 fliebel: LauJensen: Just wanted to know their relation.

9:26 LauJensen: fliebel: alpeh uses Netty and not ring as far as I know

9:26 mrBliss: LauJensen & MrHus: thanks, btw Lau, what's gonna happen with ClojureQL?

9:26 fliebel: LauJensen: But you could maybe run Ring apps on Aleph ;)

9:26 LauJensen: mrBliss: Im thinking very seriously abou that right now

9:27 I think, I hope, that I'll find the time before new years to push it into 1.0, in which case you will have the worlds finest interface to mysql, psql and derby, which is easy to extend to any number of backends

9:27 But Im pressed on time, the crew has been released. Time will tell

9:27 mrBliss: LauJensen: Looking forward to it

9:27 LauJensen: Yea me too. Its frustrating that I have so little time for it, because truthfully its a fantastic project

9:28 mrBliss: LauJensen: It's ok if you spend your time on writing blogposts abouts Emacs or Clojure ;-)

9:29 LauJensen: haha, thanks

9:29 fliebel: LauJensen: Do you have anything in mind for noSQL? or is i SQL only?

9:29 LauJensen: fliebel: Meikel had almost completed Mongo integration and FleetDB is already supported

9:30 Which was one of the things that caused a slowdown - We were eager to work with nosql, but it required us to split the codebase

9:31 fliebel: interesting...

9:32 LauJensen: If anybody wants to donate about $5000 I'd be happy to wrap it up and tie a bow around it :)

9:32 fliebel: I still need to take a closer look at FleetDB. So far the only noSQL I've done is CouchDB.

9:33 LauJensen: I gotta jet, bbl

9:33 And thanks for all the upvotes guys

9:33 fliebel: :)

9:34 When you use FleetDB in Clojure, do you talk via the server, or directly to the Clojure code?

9:36 alekx: LauJensen: at 1st glance I don't like Enlive... I think HTML code should stay HTML

9:36 MrHus: alekx: shameless self plug: http://github.com/MrHus/Hadouken

9:37 mrBliss: alekx: would you rather mix HTML with Clojure like those but ugly php scripts

9:37 (no offense intended for templating systems, yes offense for php ;-)

9:38 MrHus: mrBliss: php is great :p

9:39 mrBliss: MrHus: imho it's like using notepad instead of Emacs ;-)

9:40 MrHus: sure its has stupid function names with weird parameter's. No one ever knows where the haystack is.

9:40 But it has great documentation. And it runs everywhere.

9:40 alekx: mrBliss: it doesn't need to be completely messy... there are good templating engines out there

9:41 MrHus: Plus notepad beats emacs every day :P

9:41 mrBliss: MrHus: lol

9:42 MrHus: imho emacs is absolutely horrible, I can barely tolerate aquaemacs

9:42 mrBliss: MrHus: which editor do you use then?

9:42 MrHus: textmate

9:43 sid3k: LauJensen: you've a very nice website, I'm going to follow it

9:43 mrBliss: MrHus: mmm, and on windows and Linux?

9:43 MrHus: but i don't use any fance features anyway.

9:43 sid3k: thanks for the latest post btw

9:43 MrHus: notepad++

9:43 redcar

9:43 mrBliss: MrHus: Do you write Clojure in notepad++?

9:44 MrHus: If i need to yes.

9:44 Or e text editor

9:44 on windows

9:44 mrBliss: Yeah, the textmate for windows

9:44 Does it have a builtin repl?

9:45 MrHus: nope

9:45 I use terminal

9:45 and lein repl mostely

9:45 mrBliss: Does lein repl have history (select previous input etc)?

9:45 MrHus: yes

9:45 jkkramer: do any of those editors have lisp indentation yet?

9:45 clojurebot: Lisp isn't a language, it's a building material.

9:46 MrHus: Alan Kay

9:47 mrBliss: I don't know textmate very well, but can you do everything with your keyboard?

9:47 MrHus: mrBliss: http://redcareditor.com/screenshots/

9:47 redcar is textmate for linux

9:47 but you can do everything by keyboard

9:47 raek: was there any consensus on what the word for "clojure programmer" is, btw? Clojurian? Clojurist? Clojeur?

9:48 MrHus: the real power lies in the snippet though

9:48 mrBliss: Clojurian

9:48 I like CLojeur

9:48 raek: me too

9:48 MrHus: Clojurians

9:48 http://first.clojure-conj.org/

9:48 near the bottom

9:49 mrBliss: MrHus: isn't Redcar horribly slow (written in ruby)

9:49 MrHus: I have to admit I'm a mac guy

9:49 so I dont use linux that much anyway

9:50 mrBliss: I have a MBP too

9:50 raek: it would be fun if Clojure would have a super hero mascot called "Sir Clojeur"...

9:50 MrHus: Whats the default notepad on linux anyway, i cant remember its name

9:50 mrBliss: Gedit for gnome

9:51 MrHus: gedit

9:51 that one

9:51 What linux are you running

9:51 raek: syntax hilighting for clojure was recently added to gedit

9:51 fliebel: raek: Really? nice!

9:51 mrBliss: Currently Windows 7! Programming happens in a Ubuntu 10.04 VM

9:52 raek: http://groups.google.com/group/clojure/browse_thread/thread/f2f698c594c84bbf/9b15b243fdfccbd5?lnk=raot

9:52 MrHus: Does arch linux have clojure support?

9:52 mrBliss: Like ubuntu?

9:52 raek: clojure really only depends on a java runtime

9:53 MrHus: but as a package

9:53 vsthesquares: hey guys, how do I get leiningen to compile all the files in my src tree?

9:54 mrBliss: MrHus: nope: http://www.archlinux.org/packages/?q=clojure

9:54 vsthesquares: $ lein compile

9:54 raek: I think clojure os packages aren't used that much

9:54 leiningen takes care of downloading the correct clojure version

9:54 vsthesquares: mrBliss: it skips files that are in subdirs of src

9:54 raek: which might be different from project to project

9:55 mrBliss: vsthesquares: you prolly need the gen-class directive in your ns declaration

9:55 vsthesquares: why do you want them compiled?

9:55 raek: that depends on if he wants to generate custom java classes or not

9:56 vsthesquares: mrBliss: because otherwise main file won't compile

9:56 raek: I think one might have to add a :aot directive in the project.clj

9:56 mrBliss: http://github.com/technomancy/leiningen/blob/master/sample.project.clj#L60

9:56 MrHus: vsthesquares: are you trying to create a jar?

9:56 vsthesquares: yes, most certainly

9:57 you need :aot directive for building jars?

9:57 mrBliss: no

9:57 MrHus: lein jar or lein uberjar

9:57 mrBliss: look at Uberjar on this page: http://github.com/technomancy/leiningen/blob/master/TUTORIAL.md

9:57 MrHus: lein uberjar creates a stand alone jar

9:57 with clojure included sort of speak

9:57 vsthesquares: alright

9:57 cemerick: fliebel: just noticed the blogging software discussion earlier; I've found wordpress.com very pleasant, including clojure code highlighting (via syntaxhighlighter)

9:57 vsthesquares: will look through those docs, thanks guys

9:58 raek: :aot is for choosing which namespaces that should be ahead-of-time compiled

9:58 vsthesquares: oh ok

9:58 raek: :main could be relevant too

9:58 vsthesquares: i got that figured out

9:59 but when lein tries to compile main, it says it can't find some class files

9:59 which is logical, because it hasn't compiled them

9:59 MrHus: lein jar compiles for you

10:00 mrBliss: vsthesquares: are your namespace names correct

10:00 MrHus: can you pastebin your code

10:00 mrBliss: foo.bar for src/foo/bar.clj

10:00 MrHus: might help

10:02 vsthesquares: mrBliss: okay, i got my namespaces messed up

10:02 that should fix it

10:02 MrHus: please let us know

10:02 fliebel: What is the best Markdown solution I can get for Clojure? I found 3 possible options so far: MarkdownJ, Showdown+Rhino and Pegdown.

10:04 mrBliss: I'm gonna go for pegdown for my own blog

10:06 Last version of markdownj is from Oct 2008, pegdown 13 Aug 2010

10:06 fliebel: mrBliss: Did you manage to get it from Leiningen?

10:06 jkkramer: fliebel: had a pretty painless experience using markdownj. it's on clojars

10:06 pegdown looks pretty nifty, though

10:07 fliebel: jkkramer: I used Markq

10:07 downj for awehil

10:07 *screws up typing*

10:07 mrBliss: fliebel: I haven't actually used it, but: http://clojars.org/search?q=pegdown

10:07 polypus: given a leiningen project P, with a jar Q as a dev dependency, and that jar has dev dep R, will R be pulled into lib/dev if i do a lein deps in P?

10:07 vsthesquares: okay, so I guess dash in namespaces translates to underscores on the filesystem

10:07 thanks guys

10:07 problem solved

10:08 fliebel: jkkramer: MarkdownJ works fine, but it uses regex, which busts the stack on Java for large files.

10:12 raek: polypus: yes

10:12 notsonerdysunny: Hi everybody, I am trying to use " lein native-deps " ... Assuming that I might not be using it right i tried it on rincanter(just to test native-deps) .. and I get the following error.. "Caused by: java.lang.IllegalAccessError: make-dependency does not exist" does anybody have a suggestion?

10:12 Leiningen 1.3.0 on Java 1.6.0_17 Java HotSpot(TM) Client VM

10:13 dnolen: notsonerdysunny: huh, native-deps 1.0.2 ?

10:13 notsonerdysunny: [native-deps "1.0.2"]

10:13 dnolen: yea right

10:13 dnolen: notsonerdysunny: darn, been busy, I guess my fix wasn't enough. lein 1.3.0 shuffled a few things around.

10:14 notsonerdysunny: will look into that.

10:14 fliebel: uh-oh… what does a clojure comment look like? not # not // … lost

10:14 notsonerdysunny: oh thanks dnolen

10:14 pdk: ; fliebel

10:15 notsonerdysunny: dnolen: do you think going to lein 1.2.0 will solve the problem?

10:16 fliebel: How can I get a package updated on clojars?

10:16 dnolen: notsonerdysunny: 1.2.0 will probably work with native-deps 1.0.1

10:16 notsonerdysunny: dnolen: k will try that ..

10:16 MrHus: fliebel change your version and push again

10:17 fliebel: MrHus: I mean, a package someone else pushed to clojars.

10:17 mrBliss: fliebel: you can make your own account and update his package

10:17 I've seen it happen in the past

10:17 dnolen: notsonerdysunny: oh if you're feeling extra nice (and it's probably the same amount of work), you could figure out what the deal is with native-deps and send me a pathch :D native-deps is only like ~20 lines of code.

10:18 mrBliss: fliebel: like lein-javac: three versions on clojars

10:19 fliebel: http://clojars.org/lein-javac and http://clojars.org/org.clojars.neotyk/lein-javac (and some others)

10:19 polypus: raek: ty

10:19 fliebel: mrBliss: That's not very nice...

10:19 notsonerdysunny: dnolen: I will see what I can do .. I am all new to this java and jar stuff .. and jna .. If I can do some thing I will send you the patch

10:20 mrBliss: fliebel: it's not very nice of the authors when they don't update their package on clojars ;-)

10:21 dnolen: notsonerdysunny: thx! ... native-deps isn't very fancy. all it does is unjar the native dependencies jar into the right place. the bug is that lein fns got moved to different namespaces.

10:25 MrHus: dnolen: make-dependency is now in leiningen.util.maven

10:28 dnolen same for make-repository

10:29 Bahman: Hi all!

10:31 dnolen: MrHus: thx

10:44 fliebel: How can I run the clj repl with all lein deps on the cp?

10:46 bobo_: fliebel: lein repl?

10:46 fliebel: bobo: wow, nice :)

10:46 bobo_: sometimes its to easy :-)

10:47 fliebel: nah, can't be to easy. Only frustrating to overlook it all the time :P

10:47 repl is not even listed in help: pom

10:47 help

10:47 upgrade

10:47 install

10:47 jar

10:47 test

10:47 deps

10:47 uberjar

10:47 clean

10:47 compile

10:47 version

10:47 new

10:47 chouser: please don't do that.

10:48 fliebel: chouser: Did that come across as a dozen messages? at my end it looks like one

10:48 dnolen: native-deps 1.0.3 on github now, clojars later today.

10:48 chouser: fliebel: IRC doesn't support newlines inside a single message

10:48 fliebel: so yes, a dozen messages

10:48 fliebel: chouser: I'm sorry

10:49 chouser: fliebel: I forgive you.

10:49 :-)

11:00 fliebel: bobo: the lein repl doesn't seem to work properly. I still can't import pegdown.

11:03 mrBliss: fliebel: how do you import pegdown?

11:05 fliebel: mrBliss: (import (org.pegdown PegDownProcessor))

11:06 LauJensen: sid3k: thanks :)

11:07 mrBliss: fliebel: maybe you forgot the quote (import '(org.pegdown PegDownProcessor))

11:08 fliebel: mrBliss: Still the same java.lang.ClassNotFoundException: org.pegdown.PegDownProcessor (NO_SOURCE_FILE:3)

11:08 mrBliss: fliebel: I'm gonna try it out now (with cljr)

11:09 fliebel: I just tried it and it worked

11:10 fliebel: can you paste the output of lein classpath

11:10 fliebel: or check if pegdown is on your classpath

11:10 fliebel: mrBliss: classpath is not a task. Use "help" to list all tasks.

11:12 mrBliss: fliebel: which version of leiningen are you using (1.3.0 is the latest)

11:12 fliebel: mrBliss: Leiningen 1.1.0 :$

11:13 mrBliss: fliebel: you now what to do ;-)

11:14 s/now/know

11:16 fliebel: mrBliss: Yea, I got it from MacPorts :s Can lein upgrade itself, or do I need to get a frsh version from somewhere else?

11:17 mrBliss: fliebel: lein upgrade

11:17 fliebel: mrBliss: Guess what… upgrade is not a task. Use "help" to list all tasks.

11:17 LauJensen: Any of the Cake authors in here now?

11:18 mrBliss: fliebel: you should install it manually than

11:19 fliebel: replace your current lein script with http://github.com/technomancy/leiningen/raw/stable/bin/lein (chmod +x it) and run lein self-install

11:19 fliebel: mrBliss: How about this? curl http://github.com/technomancy/leiningen/raw/master/bin/lein | sh

11:22 jlf`: technomancy: btw, `lein new' doesn't terminate the last line of the defproject form in project.clj with a newline

11:22 mrBliss: fliebel: $ which lein to see where you're current lein is located

11:23 fliebel: mrBliss: It's located in .Trash now I'm afraid ;)

11:24 mrBliss: fliebel: cd /opt/local/bin; sudo wget <the mentioned url>; sudo chmod +x lein; ./lein self-install

11:24 fliebel: mrBliss: I'm busy already :)

11:24 mrBliss: fliebel: let me know if it solved your problem

11:25 arohner: is there a function to remove several keys from a map at the same time?

11:25 fliebel: mrBliss: I don't get the lein installation… I download a file, run install, and the have the same file(name)

11:26 arohner: (dissoc-multi m [:a :b :c])

11:27 MayDaniel: dissoc can do that.

11:27 mrBliss: fliebel: it downloads a jar containing the real leiningen in ~/.m2/...

11:31 fliebel: mrBliss: I think it works!

11:32 mrBliss: fliebel: good work

11:32 arohner: MayDaniel: oh, thanks. I should read the doc string more often...

11:33 fliebel: mrBliss: well, almost :( after running a command I can't get back my prompt.

11:34 ah, I can

11:35 jlf`: is there a cli for searching for clojar libraries and adding them to project.clj? maybe a lein plugin or somesuch?

11:36 mrBliss: jlf`: lein-search?

11:36 * jlf` googles

11:37 Raynes: cljr has search capabilities built in as well.

11:38 jlf`: thanks

11:40 ninjudd: LauJensen: i'm here for a few minutes

11:41 LauJensen: ninjudd: I gotta go though, so we can catch up later

11:42 ninjudd: LauJensen: i'll be around all day starting in about 2 hours

11:44 jlf`: is there a way to specify additional default dependencies and dev-dependencies for new lein projects?

11:47 mrBliss: jlf`: no easy way

11:48 fliebel: Is there any definitive guide to getting vimclojure set up with leiningen?

11:48 I found a lot, but all of them are different.

11:48 jlf`: hmm, so lein-search must be manually added to each project for the clojar search functionality to be available in that project?

11:50 mrBliss: jlf`: http://github.com/technomancy/leiningen/blob/master/NEWS#L36 (I haven't tried it out yet)

11:51 jlf`: mrBliss: thanks, i'll check that out

11:56 Bjering: 50000k clients, jvm CPU usage, 2% :)

11:56 eh

11:56 50k I mean ;)

11:59 jkkramer: Bjering: nice, planning to blog or post code about your adventure?

12:00 danlarkin: what kind of clients?

12:02 Chousuke: Bjering: You had worse results earlier, didn't you? What did you do to make it better?

12:02 Bjering: Chousuke, I switched to JDK7 and Nio.2

12:03 Chousuke: Oh, cool.

12:03 Bjering: danlarkin: Chat bots, they say something every 1-10 sec

12:03 Chousuke: Bjering: so it's on par with the C++ version now?

12:03 Bjering: Chousuke, it _works_ on windows. It was the selector based "old NIO" that had horrible performance on windows.

12:04 danlarkin: Bjering: using netty? or rolled your own NIO crud?

12:04 Bjering: Chousuke: Yes, though one caveat still, its Java now, but I am sure my clojure code will be just as fast now that I am ready. (Write in java first as to follow the NIO.2 samples I saw easier)

12:05 danlarkin, my own, as I couldnt wrap my head around Grizzly and netty dont have NIO.2

12:05 technomancy: clojurebot: forget slime-install

12:05 clojurebot: Titim gan éirí ort.

12:07 technomancy: jlf: nice catch; thanks

12:13 Bjering_: hmm :( Something is wrong. After a few minutes it totally hung my system.

12:15 LauJensen: Bjering_: I just dropped in - How did you get the JVM to perform like the C++ ?

12:15 Bjering_: By using NIO.2 on windows

12:15 ie the stuff that maps to IOCP

12:15 LauJensen: Ok, great

12:16 Bjering_: That is the same OS tech used by my C++ solution.

12:16 LauJensen: How did you hook into NIO.2 from Clojure?

12:16 Bjering_: havent done that yet, it was the Java version

12:16 LauJensen: oh

12:16 Bjering_: but earlier tests suggested bottleneck was all javas selector.

12:16 LauJensen: So next up from you is a wrapper-lib I assume? :)

12:17 Bjering_: yes, and perhaps when I do that I can think it through and find the bad bug that killed my system.

12:17 LauJensen: k

12:17 Bjering_: I suspect it has todo with memory, still far from the C++ one there, 1.6Gb vs 100MB.

12:18 LauJensen: Bjering_: Optimizing functional code usually boils down to one word: Allocation

12:19 And by boiling down I mean, removing reflection, getting to the primitives, etc..

12:20 Bjering_: Well, it the same in C++, key there is pretty much to is to never ever allocate memory... use the stack, and if that fails use your own custom mem-pool. Now I understand I need to let go of that thinking and find new ways in the jvm way.

12:20 technomancy: LauJensen: nice post ... except for the part about paredit. when are you going to come into the 21st century with us? =)

12:21 hiredman: technomancy: you see http://gist.github.com/550864?

12:22 danlarkin: hiredman: I saw, and I did an :-o

12:22 technomancy: hiredman: zomg

12:22 my hat, sir. it is off to you.

12:23 hiredman: it's not perfect (yet)

12:26 Raynes: :-o

12:31 fliebel: hiredman: what's that gist about?

12:33 arkh: does anybody know any examples using seque?

12:33 hiredman: uses arkham (clojure interpreter) to trace clojure code without executing it, and generate imports for the classes you use

12:43 raek: hrm, auto complete messed up my slime

12:44 it made the buffer-namespace association not work, so that when I evaled things in foo.clj (after having evaled (ns foo)) the defs ended up in user

12:50 slyrus: technomancy: URL for LauJensen's post you're talking about?

13:15 LauJensen: technomancy: hehe :) One day we'll sit down together, and you can show me why you love it

13:15 slyrus: http://news.ycombinator.com/item?id=1635764

13:15 Its quite crazy how much interest that post gathered, I posted it about 4 hours ago and the site has been hit over 10.000 times already

13:16 raek: is there any way of stopping servlet containers to add "; charset=iso-8859-1" to the Content-Type header?

13:16 mefesto: i read that post this morning and thought it was really good :)

13:16 mrBliss: LauJensen: have you got a graph of the 'HN effect'?

13:16 mefesto: although i can't give up coffee :(

13:16 LauJensen: thanks mefesto :)

13:16 mefesto: the headaches are too much for me :-\

13:16 LauJensen: mrBliss: No I just count hits in my interface, hits and referrers

13:17 mefesto: The headaches just made me more determined, I refuse to have anything have power over me

13:17 But man they were bad :)

13:17 Even up until like the 13.th day or so, they could almost cripple me

13:18 mefesto: Yeah, I kicked coffee a while ago for 6 months, then somehow it got me again

13:24 esj: LauJensen: yeah, the headaches are the worst

13:27 Chousuke: I haven't even bothered trying to give up coffee :P Properly brewed coffee actually tastes good.

13:28 (I don't use sugar or milk either)

13:29 LauJensen: Workwise what I hated the most, was getting up, having my coffee and then working effectively for 1.5 - 2 hours, then feeling the slow-down, having to get a new batch. I cant say I'll ever want to go back to that

13:38 Is there a variable in the JVM someone, which will tell me if theres an active internet connection on all OSs?

13:40 jfields: what do you do for dissoc-in? update-in with dissoc?

13:40 chouser: jfields: yeah

13:41 jfields: chouser, thanks.

13:41 mefesto: LauJensen: java.net.NetworkInterface.isUp() ?

13:41 http://download.oracle.com/javase/6/docs/api/java/net/NetworkInterface.html

13:42 LauJensen: mefesto: didn't know about that one, thanks

13:42 I wonder when I'll get used to those docs being on oracle.com...

13:49 neotyk: Hi *, Why do I get "WARNING: promise already refers to: #'clojure.core/promise in namespace: async.http.client.test, being replaced by: #'async.http.client.util/promise"?

13:50 ok, I had (refer-clojure .. in my (ns, instead (:refer-clojure

13:50 thanks :)

13:52 LauJensen: np

13:58 ,(enumeration-seq (java.net.NetworkInterface/getNetworkInterfaces))

13:58 clojurebot: (#<NetworkInterface name:tap0 (tap0) index: 4 addresses: > #<NetworkInterface name:lo0 (lo0) index: 3 addresses: > #<NetworkInterface name:xl0 (xl0) index: 1 addresses: >)

13:58 LauJensen: ,(map #(.isUp %) (enumeration-seq (java.net.NetworkInterface/getNetworkInterfaces)))

13:58 clojurebot: (true true true)

13:59 LauJensen: its all true..

14:06 mefesto: LauJensen: is that good or no?

14:06 LauJensen: I just did an ifdown eth0 and ran that and it reported false as expected

14:07 LauJensen: yea its good. You cant rely on just filtering out the first interface which is up, since lo count as such

14:07 mefesto: you can filter out lo using the isLoopback property

14:07 LauJensen: oh right

14:08 mefesto: (filter #(not (.isLoopback %)) ifaces)

14:09 Anyone know if there is a good swt clojure wrapper somewhere?

14:11 chouser: even if all the interfaces are, doesn't mean you have an ip address or are connected to anything

14:11 perhaps you just want to ping some server?"

14:11 fliebel: Has anyone seen defn today? (I think clojurebot might be able to tell me that)

14:12 chouser: ~seen defn?

14:12 clojurebot: defn was last seen in #clojure, 1712 minutes ago saying: http://copperthoughts.com/p/the-golden-ratio-is-evil/

14:12 hiredman: ,(/ 1712 60)

14:12 clojurebot: 428/15

14:12 hiredman: ,(int (/ 1712 60))

14:12 clojurebot: 28

14:13 fliebel: chouser: Does clojurebot have a manual?

14:13 chouser: fliebel: yep. his name is hiredman

14:14 fliebel: http://github.com/hiredman/clojurebot

14:14 danlarkin: Bjering: what about NIO.2 did you find necessary? Over non-2 NIO I mean

14:15 Bjering: danlarking, It seems on windows "old-NIO" is using select, which works very poorly on windows. Windows high performance network should use IOCP.

14:16 danlarking, but there might be some switch to make it work, I mean they have made NIO providers extendable etc, I am just to poor at the Java infrastructure to find it.

14:16 danlarkin: Bjering: ah, ok

14:19 Bjering: Well I think/hope I am done with the fiddly OS-related issues now and can focus on the fun (and on topic!) part, that is to learn how to wrap it up in good clojure code.

14:21 danlarkin: do you happen to know if nio2 is on the netty roadmap? I've used netty and I quite like its abstractions -- you too might find them useful

14:21 Bjering: A naming question, ctor-like functions, that builds an "identity", is there a standard way of naming these? Should it be create-acceptor or make-acceptor or just create or make in the acceptor namespace?

14:22 danlarking: I did, they are great, not their fault it didnt work so well on my windows machine. I dont know how they view NIO.2 I would suspect they will add it once its officially released.

14:23 chouser: Bjering: I haven't seen a single common naming scheme yet. make-Foo and new-Foo are both pretty common.

14:25 LauJensen: chouser: how about create- ?

14:25 chouser: LauJensen: I haven't seen that as much.

14:26 I'm not stating an opinion -- they all look a little ugly to me.

14:26 wait, there I did.

14:26 LauJensen: hehe

14:26 What would you prefer?

14:26 chouser: I've used new- and make- myself. Felt dirty.

14:27 mrBliss: http://lamp.epfl.ch/~odersky/blogs/isscalacomplex.html can you guys come up with good pictures for Clojure? :)

14:27 LauJensen: chouser: A near cousing to "Something." would be nice

14:28 danlarkin: I use create-

14:28 and make-

14:28 LauJensen: maybe you should just stick with one?

14:28 chouser: I sometimes use foo to create Foo

14:28 danlarkin: I should, it's a bad habit

14:29 chouser: Is it better to stick with a bad one than to experiment trying to find a good one?

14:29 LauJensen: If constructing java objects has syntatic support, shouldnt the same be available when dealing with clojure stuff?

14:29 Bjering: how finegrained should one be about namespaces, should I stick most of my functions into one namespace (caio as in clojure aio) or split into many, like "caio.acceptor", "caio.connector" etc ? I suspect the former, the latter smells of "OO-thinking" ?

14:30 LauJensen: Bjering: It depends on the size, but the former is most often used I think

14:30 Chousuke: just remember to have at least two segments in the namespace :P

14:30 so caio.core instead of just caio

14:31 LauJensen: also, you cant name it caio if it contains clojure code, then it must be caiojure, right technomancy? :)

14:31 Chousuke: no.

14:31 :P

14:31 danlarkin: a good rule of thumb is no more than a handful of functions per namespace. Some domains aren't suitable to that level of separation though

14:32 LauJensen: danlarkin: I would say very rarely do I keep them so small

14:32 Bjering: So, start with a single one, split if it becomes unwieldy? Now that suts the door on cleverly naming ctors _only_ make, but I guess that is a not such a good thing, hampers refactoring if I cannot move it around.

14:32 Chousuke: Bjering: I think in general you want to make the namespaces so that a person who only wants one piece of functionality doesn't need to require multiple namespaces.

14:33 Bjering: but prefixing/postfixing function-names depending on what datastructre they act on (or in ctor case, returns) when there exists a namespace facility feels bad too.

14:34 Chousuke: well you should try to make them polymorphic in that case :/

14:34 Bjering: well, if they are _at all related_

14:35 Chousuke: but I suppose in that case splitting them into their own namespaces can help.

14:36 I would err on the side of having more namespaces

14:36 as long as they have more than a few functions each :P

14:41 chouser: I tend to only split namespaces if I think they're actually likely to be used independent of each other

14:49 LauJensen: btw, whats the general attitude about clojars, everybody happy with it, is it working out okay ?

14:50 Raynes: I'm certainly happy with it. Never crapped out on me before.

14:54 technomancy: LauJensen: it's quite good, but it's a very serious problem that its maintainer is not always available. he's working on moving it to somewhere that a team can admin it, but progress is slow.

14:54 LauJensen: Oh okay - So he's being kept quite busy I take it

14:55 technomancy: busy with school, it sounds like.

14:55 once it's on the new server then kotarak and myself can help out with maintenance.

14:55 and we can start talking about setting up mirrors.

14:56 LauJensen: Cool

14:56 Why is that a length progress? Copy files, change dns, life goes on?

14:57 technomancy: dunno. =\

14:57 fliebel: technomancy: I think it would also be useful to device a way to keep packages updated… as one package, not as a copy name pepijn.somepackage which is also abandoned shortly thereafter.

14:58 bartj: er, what does "^:static" mean ?

14:58 that it is a static variable ?

14:58 , (doc :static)

14:58 clojurebot: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.Symbol

14:58 pdk: symbols don't have docstrings

14:58 hmm

14:58 (doc ^)

14:58 clojurebot: Unmatched delimiter: )

14:59 pdk: (doc ^)

14:59 clojurebot: Unmatched delimiter: )

14:59 pdk: (doc '^)

14:59 clojurebot: Unmatched delimiter: )

14:59 pdk: thanks clojurebot

14:59 ^ must be a reader macro there so time to google that

15:00 bartj: googling [^:static] just searches for "static"

15:00 this was introduce after 1.0 for sure :)

15:00 kotarak: ^:static foo means *rougly* (with-meta foo {:static true})

15:00 They are not equivalent, though.

15:01 pdk: ^ adds metadata to an object it seems

15:01 http://clojure.org/reader

15:01 so in this case it probably is acting as a compiler hint to make the object static that we attached the :static metadata to

15:02 arohner: bartj: ^:static attaches {:static true} as metadata to the next object. It's used in, e.g. defn to mark the function as static

15:03 a static function 1) can't be a closure, 2) can take primitives (long, double) as arguments and return a primitive

15:03 bartj: static functions in a functional langugage ?

15:04 was all of this stuff introduced in 1.2 ?

15:04 arohner: and 3) executes faster than a "normal" function because the JVM can inline it

15:04 pdk: are those the only differences with static functions in clojure

15:04 or does it also apply with the traditional java meaning when you try to make/extend a java class in clojure

15:04 arohner: they were introduced in a branch that was made between 1.1. and 1.2, and just got merged into master

15:04 technomancy: related to 3) static functions cannot be rebound.

15:05 arohner: pdk: clojure static has no relation to java the language static

15:05 LauJensen: arohner: Has this been put into an artifact yet, or is it strictly avail from github?

15:05 arohner: LauJensen: I don't know. There might be a 1.3 snapshot that contains it

15:05 chouser: (symbol (apply str (mapcat #(cons "\n" (next (map {\0 \ \1 \#} (Long/toBinaryString %)))) [185 13235209671M 25939708511M 1654794401M 12429901063M 131081 65539])))

15:05 kotarak: LauJensen: if it's available from github it should be in the snapshots

15:06 LauJensen: kotarak: which one?

15:06 kotarak: The latest one?

15:07 LauJensen: (rich said no snapshot, just after he merged)

15:07 bartj: this static functions in clojure seems new, can any one please point to some tutorial on the web ?

15:07 LauJensen: bartj: its right around 3 days old, dunno if there are any tutorials yet, but the concept is simple

15:07 bartj: google doesn't seem to help in this rare case -

15:07 haha

15:07 kotarak: LauJensen: aha? When it's in master it should get compiled on the hudson server, I would think..

15:07 LauJensen: kotarak: Thats what I thought

15:08 arohner: bartj: the design notes are here http://www.assembla.com/wiki/show/clojure/Enhanced_Primitive_Support

15:08 LauJensen: bartj: Its a regular function, that just works on primitives, ie math is 100x faster or so

15:08 bartj: LauJensen, I found a mention of this on your gist - http://gist.github.com/442044

15:08 * technomancy scratches his head over why the word "static" was used to describe class-level methods and fields in java

15:08 bartj: and was very bewildered

15:08 technomancy: "you keep using that word; I do not think it means what you think it means"

15:08 LauJensen: I gist too much, blame gist.el :)

15:08 kotarak: LauJensen: the last build was 4 days ago...

15:08 LauJensen: The merge was 3 days ago I think

15:09 tomoj: a804f7c9

15:09 kotarak: LauJensen: then it's probably not contained...

15:09 mefesto: inconceivable!

15:10 bartj: sorry for sounding naive- but I thought static = "don't create an object"

15:10 that analogy doesn't seem to ring a bell for "static" functions in clojure

15:10 LauJensen: bartj: its just a word we use :)

15:10 technomancy: bartj: that's the java meaning of static, which has nothing to do with the English meaning.

15:11 tomoj: oh, changelog on hudson is backwards..

15:11 bartj: technomancy, what would you say is the true meaning ?

15:11 arohner: bartj: the clojure meaning has to do with the function not being rebound

15:11 tomoj: it's at 9b702a06d, so that's the latest :)

15:12 arohner: literally, static means "unchanging"

15:12 bartj: ok, but in the Clojure context ?

15:13 arohner: the clojure function can't be rebound, i.e. using binding

15:13 so then it doesn't need locking or a volatile

15:13 bartj: ha! so static functions are not first-class ?

15:13 or am I mixing up stuff ?

15:14 arohner: bartj: they are still first class, but they can't be in closures

15:14 so you can't do (let [a 1] (defn ^:static foo [x] (+ a x))

15:14 but you can do (defn ^:static foo [x] (inc x)) (map foo (range 0 10))

15:15 that's a map outside the defn, in case the parens aren't clear

15:15 bartj: arohner, the map example is pretty clear

15:15 arohner: first class function means the function can be passed around as a variable, like any other

15:15 dnolen: bartj: ^:static also allows the JVM to do really crazy optimization tricks

15:23 bartj: ok, thanks a lot guys

15:24 everytime I ask a question you guys just have all the answers

15:25 I was reading a bit of closures

15:25 pdk: if you were to add multiple bits of metadata to a function in a defn form arohner

15:25 arohner: pdk: I don't understand

15:25 bartj: and I think I have been using closures without knowing what they were

15:25 pdk: would it go something like (defn ^:meta1 ^:meta 2 function [args] ...) or (defn ^{:meta1 true :meta2 true} function [args] ...)

15:26 bartj: but does closure = anonymous functions ?

15:26 pdk: no

15:26 arohner: pdk: (defn ^{} function [args])

15:26 pdk: closures are created e.g. by defining a function within the body of a let form

15:26 say (let [x 1] (fn [] x))

15:27 mefesto: bartj: they also include variables available in the scope that the fn was defined in

15:27 chouser: depends on if you want the science or engineering defintion of "closure"

15:27 pdk: in this case it returns a function that's closed over the value of x defined in the let form

15:27 mefesto: (defn make-adder [x] (fn [y] (+ x y)))

15:27 pdk: there's another example

15:28 in mefesto's example

15:28 if you call say (make-adder 3) it'd return a function that took one argument y and returned y + 3

15:28 arohner: chouser: what's the difference?

15:29 chouser: I just mean that AFAIK there's no special case in the code for fn objects that close over things vs. those that don't.

15:29 bartj: pdk, strictly speaking there are no let forms here - http://lispwannabe.wordpress.com/2008/10/24/closures-in-clojure/

15:30 arohner: chouser: doesn't there have to be, because of ^:static?

15:30 chouser: so from an enginerring or language implementation stand point, it's not very meaningful to give them different names

15:30 arohner: oh, ^:static is different.

15:30 mefesto: bartj: illustrating the example a bit more: http://pastie.org/1118666

15:31 chouser: but sciency mathy people would say (def f (fn [])) creates a function not a closure

15:31 but the compiler doesn't care

15:31 arohner: chouser: the name is useful to distinguish what you can do with closures vs. languages that don't allow them

15:31 tomoj: hmm, I'm getting an error about missing org.clojure.contrib:complete:jar:1.3.0-SNAPSHOT, but I can see it right there at build.clojure.org/snapshots

15:32 is [org.clojure.contrib/complete "1.3.0-SNAPSHOT"] not right?

15:32 arohner: chouser: I wouldn't say (def f (fn [])) creates a closure, because it doesn't "close over" anything

15:34 bartj: mefesto, thanks for you example, it was definitely illuminating!

15:35 chouser: arohner: I am hereby dubbing you "mathy" :-)

15:35 arohner: ok :-)

15:35 I don't think I'm mathy, just a pedant

15:36 chouser: I'm just suggesting it's not useful pedantry, in this case

15:36 bartj: mefesto, so, in your example add1 and add2 would be closures, right ?

15:36 chouser: fn objects are created using the same code path, and behave the same way, whether they close over anything or not.

15:37 arohner: chouser: agreed, but I find it very useful when talking to C programmers about what makes lisp / FP different

15:37 mefesto: bartj: yeah they are functions that "closed over" the x value in the 'make-adder function

15:37 chouser: hm, sure.

15:38 bartj: so come on! anonymous functions are closures!

15:39 because, well - they are functions whose variables are bound in the lexical enironment of the function

15:39 s/enironment/environment

15:39 arohner: bartj: you're talking about two different properties of the same thing

15:40 bartj: anonymous means, "I can create a function without naming it" i.e. (fn [x] (inc x)) has no name, unlike (defn foo [x] (inc x))

15:40 bartj: ok...

15:41 arohner: bartj: the concept of closures means, "a function can refer to variables in its enclosing scope, defined outside the function"

15:41 chouser: ,(map #(* % %) (range 5))

15:41 clojurebot: (0 1 4 9 16)

15:42 chouser: there's an anonymous function that doesn't close over anything

15:42 arohner: bartj: so yes, clojure functions can be anonymous, and can be closures

15:42 hiredman: it means it can refer to names lexically bound in the lexical scope the function was created in

15:43 pdk: clojure has a shorthand syntax for very brief anonymous functions too as in chouser's example with the #(* % %) bit

15:43 chouser: ,(let [n 2, double (fn double [x] (* n x))] (map double (range 5)))

15:43 clojurebot: (0 2 4 6 8)

15:43 pdk: useful for passing simple functions as arguments for map, reduce, apply, whatever

15:43 chouser: there's a fn named double (not anoymous) that closes over n

15:44 fogus: ,(let [f (let [x 100] #(+ x %))] (f 42))

15:44 clojurebot: 142

15:44 fogus: chouser: !! you're too fast

15:44 chouser: (fn [x] (* x x)) ...another way to write the same anonymous fn

15:45 I guess #() is called an anonymous function literal, as opposed to just an anon fn

15:45 patrkris: is reduce not using InternalReduce in 1.2?

15:45 chouser: patrkris: I don't think so.

15:45 it got commented out

15:45 DanielGlauser: chouser: #() is the same as (fn [] ()), correct?

15:46 patrkris: chouser: you know why?

15:46 chouser: DanielGlauser: right

15:47 bartj: arohner, chouser hiredman I can't thank you guys enough

15:48 patrkris: chouser: no explanation in the commit log, except that rich just says he is disabling it

15:49 bartj: strictly speaking, in this example - http://pastie.org/1118666

15:50 how does make-adder "know" to assign y = 1

15:50 the above example is for closures

15:50 mefesto: make adder doesn't know about y

15:50 make-adder returns a function/closure that accepts a parameter called y

15:51 bartj: I am sorry add1

15:51 sorry, I meant add1

15:51 mefesto: add1 = (fn [y] (+ 1 y))

15:51 chouser: bartj: the thing that make-adder returns know the values of the things it closed over

15:51 mefesto: make-adder creates a function with x already set

15:52 pdk: in those examples make-adder doesn't know about y

15:52 mefesto: (make-adder 5) => (fn [y] (+ 5 y))

15:52 DanielGlauser: bartj: make-adder returns a function that takes one argument

15:52 pdk: it only knows about x and it returns a function that does know about y and x but has x set to whatever the argument to make-adder was

15:52 bartj: yes, sorry guys that was a mistake on my part

15:53 ok, I get it

15:54 LauJensen: Does anybody here have a working example, of setting up a connection to a h2 embedded db from clojure?

15:54 bartj: but, it looks like such a contrived example - almost like watching Inception!

15:54 DanielGlauser: Now, is the anonymous example returned by make-addr a closure?

15:54 bartj: I wouldn't be sorry, we're all trying to learn here

15:54 pdk: yeah closures dont tend to be immediately obvious how they can be used

15:54 DanielGlauser: if make-addr is a closure, what does it close over from its environment?

15:55 mefesto: make-adder is not the closure

15:55 pdk: probably helps to read tutorials on places like schemers.org/cliki, blog posts in various places, books like on lisp or let over lambda

15:55 mefesto: what it returns is the closure, right?

15:55 DanielGlauser: I meant the function it returns

15:55 pdk: that talk about lisp traits like macros/closures/whatever in depth to show the fancy pants uses of them

15:56 doesn't it close over the argument given to make-adder dan

15:56 mefesto: yes, the function it returns is because in order for that function to work, it needs to resolve x which is provided by the lexical scope it was created in

15:57 DanielGlauser: Cool, just wanted to be clear :)

15:58 mefesto: looking at the fn on it's own shows that it has to have some "extra magic" in order to work

15:58 (fn [y] (+ x y))

15:58 that alone couldn't work

15:59 chouser: in fact you get a compile error

15:59 bartj: ok, the only use case for closures right now seem to be when using the surrounding variables ?

16:00 hiredman: bartj: that is literally *THE* case

16:00 pdk: if you did something like (let [myref (ref blah blah)] ...)

16:01 hiredman: http://en.wikipedia.org/wiki/Funarg_problem

16:01 DanielGlauser: bartj: Think about a function that builds other functions and what problems you would want to solve with that pattern

16:01 pdk: then in the body of that let block you could define one or more functions that operate on that myref variable

16:01 while keeping it invisible to everything else

16:02 DanielGlauser: Let's say you were creating a function that spit out parsers, you would want to say what each parser would parse when you spit out the function

16:03 but each parser would want to take an argument of what they needed to parse

16:03 Closures are good for patterns of building functions

16:04 bartj: does that make sense or am I totally out in left field?

16:05 bartj: went to drink some water...

16:05 but, yes it makes a lot of sense right now

16:06 mefesto: bartj: this is an example of what pdk was saying: http://pastie.org/1118745

16:06 DanielGlauser: Hmmmm... perhaps we could use a place up on clojuredocs.org that covers examples of concepts as well as library functions

16:06 mefesto: the currval atom cannot be accessed by anything... kinda like a private variable

16:07 hiredman: local

16:10 bartj: mefesto, that is quite an intelligent way to get two different outputs based on your *current* state

16:14 pdk: also lets you keep those bits of mutable state visible only to a set of functions you're allowing to use/modify it so other bits of code can't scribble over that state

16:26 _ulises-: evening all

16:27 astoddard: is anyone here using org-babel-clojure in org-mode?

16:29 tomoj: I'm not, but I'm interested

16:29 think it needs a rewrite

16:30 _ulises-: can anybody help me with this: http://pastebin.com/Y52yuNwi (newbie here)

16:32 mefesto: _ulises-: (load "/foo/bar") ?

16:32 _ulises: hmm, let me try

16:32 mefesto: _ulises: if you want to make an instance of foo.bar you need to compile it too

16:33 _ulises: I thought that loading foobar.clj was enough?

16:33 also, (load "/foo/bar") doesn't work but (load "foobar") does so I suppose that the latter is the way to go

16:33 mefesto: for clj files but im guessing you want to create a java class right?

16:33 _ulises: yup :)

16:33 mefesto: i was guessing that since your ns is foo.bar that your file is foo/bar.clj ?

16:34 _ulises: oddly enough, this works just fine: (defn make-foo (proxy [Object] [] (-toString [] "Hi!")))

16:34 mefesto: if it's foobar.clj then i guess that makes sense :)

16:34 Raynes: You rarely ever need to actually compile your Clojure code to Java class files. You only need to do that for generally advanced Java interop purposes.

16:35 _ulises: mmm

16:36 arkh: mefesto: what causes the symbols test1-nextval and test2-nextval to remember (and apply) their current value to the function assigned to them?

16:37 mefesto: arkh: they are closures that have an atom called currval available in their environment

16:37 astoddard: tomoj: about org-babel-clojure, I am in the same boat

16:38 arkh: mefesto: : ( currval is local and should disappear between invocations (obviously it sticks around so I'm missing something)

16:38 astoddard: I am wondering about how to connect babel with something like cljr to control the setup

16:39 mefesto: arkh: that's the behavior of closures, they have access variables that they reference that are in the lexical scope

16:39 *access to variables

16:40 arkh: mefesto: I'll have to read up on that. Given that the value is persistent, why is it implicitly used for the single parameter 'num'?

16:40 mefesto: subsequent calls aren't made with any arguments

16:40 _ulises: also, when I load the file, the result is nil while if I eval (proxy ...) the result is not

16:40 :(

16:41 mefesto: arkh: this is the line of interest: (fn [] (swap! currval inc))

16:41 bartj: arkh, put in another way, they are local in their scope

16:41 mefesto: arkh: on it's own that code is invalid since currval isn't defined

16:41 arkh: what makes it valid is the outer scope

16:41 i hope im wording that correctly :)

16:42 arkh: but the outer scope is requires the parameter num on each execution

16:42 s/is//

16:42 sexpbot: but the outer scope requires the parameter num on each execution

16:42 mefesto: arkh: currval is an atom that is initialized to num

16:43 arkh: ohh

16:44 ok - I need to read up on closures. mefesto:. bartj: thank you for the explanations

16:45 technomancy: ~suddenly

16:45 clojurebot: BOT FIGHT!!!!!111

16:45 technomancy: what?

16:45 clojurebot: what is cells

16:45 chouser: ~cells?

16:45 bartj: arkh, you weren't here when all these guys were explaining closures to me ?

16:45 clojurebot: cells is http://gist.github.com/306174

16:45 mefesto: _ulises: this works: http://pastie.org/1118839

16:45 technomancy: clojurebot: facepalm is http://tinyurl.com/38v7jlj

16:45 clojurebot: Roger.

16:45 arkh: bartj: I think I was away and just caught the tail end of the discussion

16:45 mefesto: _ulises: but your classpath needs to be setup a certain way

16:46 _ulises: let me try

16:46 kilofu: q

16:46 arkh: bartj: I'll read the backlog ;)

16:47 mefesto: _ulises: by default clojure will compile assuming there's a classes dir in $PWD

16:47 raek: _ulises: proxy always returns an object, but gen-class generates an ordinary class *when compiled*

16:47 so 'load' does not return an instance...

16:47 _ulises: ah, that explains the nil

16:48 back to the (ns foo.bar ...) do I have to have foo/bar.clj ala Java?

16:48 raek: but as mefesto showed, you can compile the namespace and use the ordinary contructor syntax to create an instance

16:48 _ulises: basically, yes

16:48 that is the recommended way

16:48 _ulises: ok, I didn't know that, thanks

16:48 mefesto: _ulises: i don't think your file paths _have_ to match but the generated class will use the ns to create foo/bar.class

16:49 _ulises: oh!

16:49 mefesto: but yeah thats recommended

16:49 bartj: here I created one paste based on the explanations here

16:49 http://pastie.org/1118851

16:49 raek: if you require a namespace foo.bar, clojure will look for foo/bar.clj

16:50 (compile looks for the file using the same rule too)

16:50 also, hyphens in namespace names correspond to underscores in file names

16:50 _ulises: well, call me thick but it just doesn't work for me :(

16:51 I've set it up like mefesto did (foo/bar.clj)

16:51 mefesto: _ulises: what was the error?

16:51 _ulises: then ran (compile 'foo.bar)

16:51 IO exception, no such file or dir.

16:51 hrm

16:52 mefesto: this is probably the classpath thing

16:52 _ulises: this is using cljr swank + emacs btw

16:52 mefesto: by default clojure assumes ./classes exists and is in your classpath

16:52 you can override in the repl with: (set! *compile-path* ".")

16:52 _ulises: ah, it may be that ./ is not in my classpath

16:53 raek: if you do ahead-of-time compilation (or basicaly anything that requires you to divide the source into multiple files) I would recommend leiningen

16:53 mefesto: assumeing the current dir is in your classpath :)

16:54 _ulises: hrm ... still no luck :/

16:54 mefesto: _ulises: you on linux?

16:54 _ulises: os x

16:55 raek: you can print the classpath using (println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))

16:55 what file path does the IO exception complain about?

16:56 _ulises: that it can't find bar.clj

16:56 but it must be the classpath as I did the set! *compile-path* and then it worked

16:56 in any case, got to go, thanks for your help chaps :)

16:57 raek: I pernollay think leiningen would be a better fit than cljr in your case (at least for setting up the classpath)

16:57 as it works with project directories

16:57 with src/ and classes/ directories automatically added to the classpath

16:57 you shouldn't have to tweak the classpath manually, really

16:59 ssideris: do you guys know whether running "lein swank" from a project dir will setup the classpath automatically for you?

17:00 Raynes: ssideris: It does.

17:01 ssideris: Raynes: thanks, I'll give it a try...

17:01 raek: it adds src/, lib/, classes/, resources/ (and maybe some more) plus those for all the dependencies and dependencies dependencies, etc

17:05 ssideris: if I add new dependencies and then run "lein deps" I suppose I'd have to re-start swank and reconnect from emacs, right?

17:05 Raynes: ssideris: Yes.

17:28 ssideris: it works! thanks :-)

18:05 jkndrkn: Hey all. I'm using a BufferedReader to access a resource hosted at a remote location. I'm doing streaming writes.

18:05 *streaming reads.

18:06 My application code requires me to pass this reader to an instance of SuperCSV for CSV parsing.

18:06 However, I also need the raw lines of CSV for composing detailed error reports.

18:07 Currently, I am having to use two readers but would like to avoid doing so since this scheme essentially requires me to pull data down twice.

18:08 I can create a lazy sequence of strings from one reader, is there any way that I can both consume this lazy sequence in one place in my application code and also draw from it elsewhere by somehow converting it into a BufferedReader?

18:09 In other words, can I create a BufferedReader that reads from a lazy sequence. And, if so, is this a safe approach to use that won't cause head retention or other kinds of excessive memory consumption?

18:14 raek: that should indeed be possible

18:15 I have to sleep. good luck!

18:23 tomoj: did ignore-trailing-slash disappear? :(

18:48 jkndrkn: Here's my question written in a more coherent fashion: http://stackoverflow.com/questions/3580152/clojure-java-most-effective-method-for-minimizing-bandwidth-consumption-when-per

18:48 I would greatly appreciate if someone could take a look ^_^

18:55 ssideris: is native-deps broken?

18:55 it seems that although i've added it as a dev dependency, :native-dependencies is being ignored

18:56 dnolen: ssideris: no it should work I just tested it this morning, you need 1.0.3 tho

18:56 will be pushing it clojars in 30-45 minutes or so.

18:56 ssideris: if your in a rush, just clone the git repo and run install from the repo directory

18:58 ssideris: dnolen: no particular rush, just learning how to use leiningen etc and I was hoping to play with penumbra a bit. Thanks!

18:59 wwmorgan: jkndrkn: Could you download the file to local storage, and then open two streams on it?

19:12 jkndrkn: wwmorgan: Yes, but that would defeat the purpose of streaming in the first place: to begin processing data right away as soon as it starts arriving rather than wait for the whole file to download.

19:14 wwmorgan: We may have to fall back to that scheme if we can't figure out a good way to do this.

19:18 wwmorgan: jkndrkn: are you reading the records by calling CsvBeanReader.read?

19:24 chouser: java.lang.RuntimeException: java.lang.IllegalStateException: no 'this' pointer within static method

19:24 what does that mean?

19:24 or rather, what sort of code can trigger that error?

19:25 ssideris: in java?

19:25 fsmunoz: chouser: I could be completely wrong

19:25 wwmorgan: chouser: it strongly resembles the java compile-time error of having a "this" in a static method. There is no "this" for static methods

19:25 fsmunoz: chouser: but a static method doesn't have a "this", it is used fr instance methods

19:26 chouser: right, but how to get this from a clojure defn form?

19:27 fsmunoz: chouser: I use "this" when I'm implementing istance methods via proxy... they work as expected there. Apart from that I know close to nothing.

19:29 chouser: huh!

19:30 ok, it appears to happen when you call a protocol method from inside a static function

19:31 now that I say that, it sound vaguely familier. hm.

19:32 tomoj: it's a "temporary limitation"

19:34 fsmunoz: SOme hours ago I mention this doubt, bu maybe I'll have better luck now: I'm having trouble "converting" an imperative solution to a functional one. Essencially I need to build an array/vector that contains x/y coordinates for an hexagon. They are calculated like this.x[0] = foo; this.x[1] = this.x[0] + bar, etc, etc. I'm using make-array and aset now, but that is, well, hardly idiomatic. Any hints on a more "functio

19:34 nal" way of going at it? I've toyed with the idea of having the two vectors as atoms, is that sensible?

19:36 wwmorgan: fsmunoz: can you paste the imperative code?

19:36 fsmunoz: wwmorgan: sure: https://malenkov.dev.java.net/20090226/hexagon.java

19:37 The relevant part is there in the middle, the "this.x[0]" stuff

19:37 ssideris: i have the feeling this is going to be 4 lines in clojure :-)

19:38 fsmunoz: ssideris: that's partially what I'm hoping, I'm very aware that I'm using an hammer for everything

19:38 In this case make-array, which is clearly a coup-out since it allows aset.

19:39 Having 6 different let vars doesn't seem much cleaner either.

19:44 chouser: I'd just use a let to compute the things that are used more than once first

19:44 then put those and the remaining expressions into your array or vector or whatever.

19:47 fsmunoz: chouser: yes, that would be the "6 different let vars" approach. It would work, but somehow it doesn't look very elegant. In this situation it would work, but if doing a polygon with 20 vertices it wouln't scale well.

19:48 but maybe that's the way to go, that or setting x and y as atoms and using swap!

19:48 kencausey: this doesn't seem like a common thing to me, normally shapes are going to be defined by external data

19:48 fsmunoz: would still be more imperative, but would at least avoid using Java arrays

19:48 kencausey: are you sure the issue is that you are try to treat data as code?

19:49 s/is/isn't/

19:49 sexpbot: are you sure the isn'tsue isn't that you are try to treat data as code?

19:49 fsmunoz: kencausey: this is a grid... the hexagons will have to be drawn somehow, it's the "base world".

19:50 kencausey: ok, fine, this case may not be a problem and may really be imperative

19:50 There is a point though on the complexity scale where it makes sense for it to change from a code issue to a data issue

19:51 fsmunoz: kencausey: yes, I was wondering that, the objective itself is merely to do the calculation for determining the vertices, so it's perhaps one of those situations were it's ok to "cheat" ;)

19:51 sexpbot: how so?

19:53 I really can't think of a way to draw an hexagon that doesn't involve calculating the vertices using math (and some variables that govern superficial stuff like scale)

19:53 But I'm almost as bad at math as I am at clojure, so feel more than free to correct me

19:53 kencausey: the questions is not whether math is used or not

19:54 it's whether it is done at runtime or compiletime

19:54 fsmunoz: kencausey: runtime, since e.g. the user could change the zoom scale. But why exactly is that difference important in terms of the way of calculating it?

19:55 Sorry to burden you with questions that could be obvious, I'm trying to pick as much brains as possible ;)

19:55 kencausey: for a hexagon, probably none, for thousands of them or more maybe an optimization

19:55 chouser: it'd be better to cheat with extra locals than with atoms

19:56 atoms suggest coordinated mutation from multiple threads

19:56 fsmunoz: chouser: yes, probably bad idea, true

19:57 kencausey: ahh, yes, instead of calculating it on the fly having it all pre-calculated in order to improve performance, something like that?

19:59 wwmorgan: fsmunoz: right now you're using mutation for the local variables i and j?

20:00 fsmunoz: wwmorgan: let me check, I'm not using i/j for coordinate printing yet, merely for adjusting the loop increments

20:00 wwmorgan: no, I set them in let, then just use them to increment x/y in the respective recurds

20:00 *recurs

20:01 wwmorgan: I've used loop/recur in place of the while's in there.

20:02 chouser: (map #(vector (+ x %1) (+ y %2)) [0 R R 0 (- R) (- R)] [(- S) (- L) L S L (- L)])

20:03 fsmunoz: Looks like TECO Emacs, which means it's probably perfect!

20:03 chouser: heh

20:04 fsmunoz: Intersting, very interesting

20:04 And without a doubt more elegant than using aset.

20:05 Plus, completely functional

20:05 many thanks chouser

20:05 (and wwmorgan, kencausey)

20:07 Part of my difficulties with Clojure have to do with imperative thinking: I've notived that when using imperative style I could get away with not knowing much about a language, but with functional programming it's almost fundamental to learn them.

20:12 wwmorgan: fsmunoz: that paint method is pretty oversized. You can get practice writing more functional clojure by writing more functional java :-)

20:13 fsmunoz: wwmorgan: ehehe, yes, but what I was really after was the hexagon stuff, it just happened to be in Java. The coords-to-x/y stuff isn't obvious, and that page has the advantage of explaining it well enough

20:14 The paint stuff I'll likely rewrite (eventually having each hex drawing itself instead of doing it linearly, etc).

20:14 But the calculation itself is always needed.

20:15 bortreb: fsmunoz: you're doing the meteor contest?

20:16 fsmunoz: bortreb: no, what's that?

20:16 bortreb: http://shootout.alioth.debian.org/u32/performance.php?test=meteor

20:16 it's a benchmark game that involves placing hexagons on a board

20:17 fsmunoz: Well, I'll be damned

20:17 Plenty of source code in there!

20:17 bortreb: you can submit clojure stuff too :)

20:18 fsmunoz: bortreb: as you can see from my doubts, I don't think it would do it justice ;)

20:20 But thanks a lot for the hint, I will most surely use it.

20:28 chouser: fsmunoz: that map/vector solution may be more elegant, but it's certainly slower than a 6-clause let would be

20:28 fsmunoz: chouser: I'll optimise it latter then, at this stage I'm putting elegance above performance :D

20:28 chouser: even because it has better learning value

20:29 bortreb: Is there a real solid way of creating a map of all the static final ints in a class?

20:29 er, I mean a seq

20:33 mefesto: bortreb: by "solid" do you mean non-reflection based way?

20:33 java.lang.reflect i mean

20:34 bortreb: not at all, just something that isn't in any way a hack

20:34 and is in all cases functionally correct

20:36 mefesto: bortreb: not sure if contrib has something already but the manual way would be: (.getFields ClassName)

20:37 it'll give you an array of fields that you can filter based on type or other characteristic you are looking for

20:37 bortreb: yes, I've done that, but then what? How can I sell if they're static ints and grab the actual values?

20:38 mefesto: getModifiers i believe

20:38 java.lang.reflect.Modifier has the constants that will be bitwised or'd on the field's modifiers property

20:39 bortreb: huh

20:39 mefesto: Modifier.STATIC

20:40 im rusty on bitwise stuff so someone please correct me but maybe: if (Modifier.STATIC & field.getModifiers()) {...} is it

20:40 bortreb: cool --- that's everything I need. thanks mefesto

20:43 mefesto: (bit-and Modifier/STATIC (.getModifiers field))

20:44 tomoj: (Modifier/isStatic (.getModifiers field))

20:45 mefesto: ugh, way better :)

20:45 bortreb: yay for tomoj!

21:17 fsmunoz: chouser: just as a note, the new version based on your map approach is *much* quicker than the previous one I had, which followed the original Java code using aset and aget. When maximising it would take 1 second to fill the new area, now it is immediate.

22:27 dnolen: anybody else experiencing issues pushing to clojars?

23:59 fielcabral: I just got swank-clojure from github. Should I use the latest slime on common-lisp.net with it or the one from elpa (20100404)?

Logging service provided by n01se.net