#clojure log - May 29 2011

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

2:17 sid3k: hi all. I'm having trouble to run this example code: https://github.com/zkim/xmpp-clj

2:18 amalloy: sid3k: the instructions in that readme look really old

2:18 sid3k: I compiled the module but still can't managed to execute the client

2:19 amalloy: is there any better xmpp library for clojure, with documentation?

2:20 what should I put on the main function to run the client?

2:20 amalloy: sid3k: what i mean is, they're asking you to use clojure 1.1 (a year out of date), and a version of lein-swank that's got to be older than god

2:20 sid3k: amalloy: yeah but still I wonder, how can I run the example app?

2:21 is it necessary to call my-bot?

2:21 my-boot doesn't seem like callable

2:21 amalloy: *shrug* i've never used the xmpp project. i doubt it's callable

2:22 sid3k: yeah, me too

2:22 amalloy: did you give it a username/password pair that you can successfully log in with yourself?

2:23 sid3k: amalloy: of course

2:23 then I wrote this code: (defn -main [& args]

2:23 (println "Hello World")

2:23 (xmpp/start-bot connect-info reload-helper))

2:24 when I run this module, it puts hello world and exits

2:25 this channel was so breezy 6 months ago, what happened to this community?

2:25 amalloy: well you showed up at 2:30am east-coast time :P

2:26 sid3k: good point

2:27 and it's saturday, I wouldn't want to be a part of community studying programming in saturday night

2:28 amalloy: anyway, i don't know how the xmpp lib works. maybe it does something crazy like not register any non-daemon threads, in which case exiting (main) would make the jvm terminate

2:29 but if the clojure wrapper is a year old and isn't working, i'd probably look into how the java library itself works

2:29 sid3k: hmm

2:29 arright

2:31 amalloy: sid3k: if you're not married to xmpp, you can fork sexpbot here and write an irc bot instead

2:32 sexpbot: what do you think of irclj?

2:32 sexpbot: It's AWWWW RIGHT!

2:32 seancorfield: sid3k: in addition to being late at night, it's memorial day weekend in the US and most people are away on vacation for three days :)

2:32 except folks like me and amalloy :)

2:32 amalloy: seancorfield: by the way, i've confirmed that i'm moving down to LA to work with lancepantz and ninjudd

2:33 seancorfield: i guess i'd ask what you plan to do with xmpp?

2:33 amalloy: sorry to hear you'll have to put up with LA...

2:33 but working with those guys should be fun

2:33 and you can always drive back up for weekends (which is what my wife used to do when she lived in marina del rey)

2:34 sid3k: seancorfield: I'm planning to make a jabber client for my chess app, multiplayerchess.com

2:34 s/jabber/gmail

2:34 sexpbot: <sid3k> seancorfield: I'm planning to make a gmail client for my chess app, multiplayerchess.com

2:34 seancorfield: a gtalk client, you mean?

2:34 sid3k: yeah, I didn't want to replace it again :)

2:34 * amalloy preferred "jabber client"

2:35 sid3k: hmm, jabber might be the true one

2:35 amalloy: sid3k: gtalk is just jabber

2:35 seancorfield: you might want to just take the basic java library and write your own wrapper... i haven't looked at xmpp-clj but it sounds like it isn't maintained any more and you might be able to write a better wrapper for your needs anyway...

2:36 sid3k: I also want to restrucutre its backend soon. Now it sounds better to design the whole system based on xmpp

2:37 seancorfield: yeah, make sense

2:41 seancorfield: sid3k: do you get lots of errors like this at startup: Error! A startup class specified in smack-config.xml could not be loaded: org.jivesoftware.smackx.ServiceDiscoveryManager

2:41 sid3k: seancorfield: yep

2:44 seancorfield: i just tried it from the repl and despite the errors, it worked fine

2:44 my bot responded: Hi mailto:seancorfield@gmail.com, you sent me 'test'

2:46 sid3k: I haven't tried it on repl yet. How would you code it if you wanted it to run as an app?

2:46 was my -main func wrong?

2:46 seancorfield: dunno

2:47 i'm just saying it worked fine from the repl...

2:47 sid3k: arright

2:47 thx

2:48 seancorfield: i guess you'd need some sort of loop that mostly just slept?

2:48 sid3k: hmm

2:48 seancorfield: and then in handle-message issue a stop-bot call if you get a shutdown message?

2:48 amalloy: seancorfield: that implies that the xmpp library does the insane thing i mentioned earlier, doesn't it?

2:48 seancorfield: it does seem a bit silly that starting a bot doesn't create a long lived process

2:49 but i haven't looked at the code or the xmpp library

2:50 amalloy: seancorfield: i looked at the clj wrapper and it doesn't do anything obviously persistent, just asks the java lib to do stuff

2:51 seancorfield: yeah, i concur having just read the source

2:54 the examples i can find all assume a long running java app

2:54 so, i guess the answer is main must loop / sleep until something tells the bot to shutdown

2:55 and on that merry note, it's midnight, my wine glass is empty and i'm off to bed!

2:55 sid3k: it works but still I couldn't understand how it works on the repl

2:55 seancorfield: well the repl is a long running process so it (the bot) stays running while the repl runs

2:55 anyways... 'nite

2:56 amalloy: sid3k: because the repl is still running after you call main, the process doesn't terminate

2:57 sid3k: then the documentation lacks the example of app usage

2:57 number one reason for abandoning a library

2:58 amalloy: if that's the best reason you can find to abandon a library, you should mail the author some flowers

3:00 sid3k: amalloy: hmm

3:00 btw I've found an example, in the src directory

3:03 seancorfield_: And yes I have gone to bed but I figured I'd log back in from my phone and see how the XMPP chat is going :)

3:04 amalloy: hah

3:04 seancorfield_: you need to see someone about your clojure addiction

3:04 sid3k: :)

3:04 seancorfield_: Btw we did not go to production with clojure this week :(

3:04 We found sone bugs in the app that need fixing first

3:05 amalloy: seancorfield_: just call it a public, opt-out alpha

3:06 seancorfield_: But that gave me time to replace our old logging module with log4j, clojure.tools.logging and a custom DB appender written in clojure :)

3:07 If business delay the production launch beyond this week, I'll add in congomongo and start logging to mongodb in the cloud! :) :)

3:09 So when do you move to LA? Where will you be based?

3:10 amalloy: seancorfield_: next week

3:10 have a one-month rental arranged while i look for something permanent

3:11 seancorfield_: Yeah? What part of LA?

3:11 amalloy: hoping to find a nice place in santa monica, but i'll be looking around

3:11 since the office is in west hollywood

3:12 seancorfield_: My wife lived on a houseboat in marina del rey. That's near Santa Monica I think?

3:13 Does the company have any telecommuting employees? What do they actually do?

3:13 amalloy: www.geni.com

3:13 yeah, marina del rey is nearby

3:14 seancorfield_: genealogy ... an interesting area ... all clojure?

3:15 amalloy: seancorfield_: that's what they're hiring me for. i understand they're porting a lot of ruby to clojure as well as writing some stuff from scratch

3:16 seancorfield_: Cool. Sounds like a fun project. Next time my place has a company meeting maybe I'll swing by and see more of what you guys are up to!

3:17 amalloy: neat

3:17 seancorfield_: World Singles is completely distributed but most of the core live in or just south of LA.

3:18 sid3k: lein is the coolest thing about clojure, except clojure itself

3:19 amalloy: sid3k: there's also cake

3:19 * amalloy is now obliged to say that

3:19 seancorfield_: What IDE do you use sid3k?

3:19 sid3k: emacs

3:20 I didn't hear cake before, going to check that out

3:20 amalloy: sid3k: it's similar to lein

3:20 sid3k: is it as common as lein? it seems many projects support lein

3:20 seancorfield_: Hardcore :) I do so much Java-related stuff I live and die in Eclipse with CCW.

3:21 Cake has some neat features but I think lein is way more prevalent.

3:22 amalloy: sid3k: lein is more popular, largely because it's more established. they're mostly interchangeable, really; they use the same project.clj format but have different plugins

3:23 sid3k: amalloy: which one do you prefer?

3:23 amalloy: meh

3:23 sid3k: both?

3:24 amalloy: i mostly use lein at the moment, but i have many months of happy cake usage

3:24 and i'm going to work for the cake guys soon

3:24 sid3k: sounds great

3:25 amalloy: my understanding is that cake is easier to write plugins for, and has a persistent jvm to reduce startup times for each cake command

3:25 seancorfield_: Yeah

3:25 amalloy: currently i work with long-running apps so i don't need that much, and sometimes it gets annoying to have to keep killing jvm processes, so i use lein

3:26 seancorfield_: But lein plugins are really easy to write too and there's a lot more of them

3:27 For persistent JVM stuff, there's also jark

3:27 amalloy: the clojure web-development libraries are really nice btw, sid3k. i love how easy it is to write some ring middleware

3:29 seancorfield_: I'm not convinced they're good for really HTML heavy web apps. They're good enough for rest apis and small sites.

3:30 But maybe I just need to spend more time with enlive (haven't liked what I've seen so far)

3:30 sid3k: then it's better for me. I generally seperate frontend and serve the html stuff with just a static web server

3:30 amalloy: seancorfield_: yeah, i haven't really had to write huge html stuff. but coming from a no-frameworks-here php, moving to kinda-small-frameworks clojure still feels nice

3:30 seancorfield_: World Singles sites are HTML heavy but very dynamic

3:31 So we use CFML for View-Controller and clojure for Model. Or at least we're going that way

3:36 I've been using web frameworks for nearly a decade in CFML since my time at Macromedia. I've been lead developer on three of the most popular ones (in CFML).

3:37 But I've definitely moved from large to small and I prefer multiple, composable microframeworks these days.

3:37 amalloy: seancorfield_: yes, ring is a fantastic webserver. i'm not in a position to judge re hiccup, moustache, enlive

3:39 klang: sorry to inject: isn't ring, hiccup, moustache and enlive supposed to be used in conjunction? (that's the feeling I get when I look at web programming in Clojure every 3 months ..)

3:41 seancorfield_: Ring is the foundation. The rest are optional but are often used together I believe.

3:42 amalloy: klang: ring is the webserver. hiccup and moustache (and enlive, i think?) are libraries for generating html responses to feed to the webserver

3:43 Raynes: amalloy: Ring isn't the web server. Jetty is the web server.

3:43 seancorfield_: Ring and enlive are now part of the new contrib libraries for 1.3.0

3:44 Raynes, ring has a jetty-adapter, does it have support for tomcat?

3:44 amalloy: seancorfield_: i think so

3:44 Raynes: seancorfield_: I find it adorable that you assume I would actually know a lot about Ring just because I knew that one small fact. :)

3:44 klang: amalloy: yeah, I got that idea, more or less.

3:44 amalloy: $google clojure ring tomcat

3:44 sexpbot: First out of 309 results is: Jeroen Vloothuis: Deploying a Clojure web-application as a WAR file

3:44 http://jeroenvloothuis.blogspot.com/2010/07/deploying-clojure-web-application.html

3:45 amalloy: Raynes: the fact you know is dubious anyway

3:46 seancorfield_: That blog post shows how immature clojure is for webapps right now

3:46 amalloy: ring is clojure's interface to the webserver. you could as easily say that jetty isn't a webserver either, just an interface to the next-lower layer

3:47 i guess ring is the http server, and jetty is the webserver? that's not totally false

3:47 seancorfield_: it's also a year old

3:47 seancorfield_: lein-ring is much cleaner but I worry that ring is tied to jetty?

3:48 klang: seancorfield_: things move fast (I am starting over on web dev in clojure every time I look at it ..)

3:48 seancorfield_: Yeah it can be hard to keep track of it all

3:49 We'll stick with a mix of CFML and clojure for the foreseeable future I expect

3:53 The anti-histamines are kicking in (we spent the afternoon wine tasting and those sulphites have us both congested) so I'm getting dozy. Time to sign off and get some sleep.

4:09 bpr: l

6:03 tufflax: Does anyone know how do make vimclojure detect java interop stuff (like .method and Class/thing)? I have the regexps but I can't get it to work. I don't fully understan the syntax file :p

6:51 kzar: I'm missing something here, any ideas? http://paste.lisp.org/display/122349

6:54 raek: kzar: from the docs for case: "The test-constants are not evaluated. They must be compile-time literals, and need not be quoted."

6:55 so you end up having the _symbol_ com.google.gdata.data.calendar.CalendarEntry as the first test constant

6:58 kzar: raek: Hmm so com.google.gdata.data.calendar.CalendarEntry in the clause isn't evaluated but is that not already the literal symbol?

6:58 raek: The expression's evaluated right?

7:05 raek: yes

7:07 erhm. I meant this: a case form looks like this: (case expr constant1 result1 constant2 result2 ...). here, expr is evaluated, but the constants are not

7:07 kzar: your example fails because symbols and classes are not the same (put they print the same)

7:08 ,(class 'java.lang.Integer)

7:08 clojurebot: clojure.lang.Symbol

7:08 raek: ,(class java.lang.Integer)

7:08 clojurebot: java.lang.Class

7:08 raek: a symbol evaluates to a class if it contains dots

7:08 kzar: raek: Yea it just clicked heh

7:08 raek: kzar: you can work around it with a macro: https://gist.github.com/997652

7:13 updated the gist so that it accepts (case expr (constant11 constant 12) result1 ...) style forms too

7:28 kzar: raek: Heh it's little things like this that always catch me out, I'm just having a go at doing it myself

7:28 raek: Thanks for explaining it

7:45 raek: (resolve 'com.google.gdata.data.calendar.CalendarEntry) turns symbol to class, is there a way to do the opposite?

7:45 raek: (I figured instead of resolving the conditions I could make the expression a symbol)

7:52 raek: kzar: yeah, that sounds a lot simpler.. (defn class->symbol [class] (symbol (.getName class)))

7:54 kzar: raek: Ah nice, I was trying to stop the symbol from being resolved into a class but then I realised the (class) function actually returns the class not a symbol to be resolved

7:54 * kzar doh

8:57 bOR_: is there something obvious I am missing when aset in clojure 1.3-alpha8 won't work for shorts. aset-shorts does work, but way slower than I'd expect. There is also the odd difference in speed between aset ^ints and aset-int of about 15-fold.

8:57 (doing matrix summation)

8:59 I've looked at the source of amap (which was the first thing to give me problems with shorts), and from there came to writing the amap function out, and using aset-shorts rather than aset to get shorts working), but I'm stuck at looking at the source of aset

8:59 which is where my clojure-fu breaks down :-).

9:00 related (now that I have the floor anyway), should I still be messing with java arrays in clojure 1.3, or would a vector of primitives be as fast?

9:03 bpr: is there a more concise way to parse and integer than java.lang.Integer/parseInt ?

9:05 short of using memfn of course

9:06 mids: bpr: you could use read-string

9:07 ,(+ (read-string "3") 2)

9:07 clojurebot: 5

9:08 mids: (it isnt safe though to use on input you dont control)

9:08 bOR_: ,(aset (into-array Short/TYPE [1 2 3]) (short 1) (short 1))

9:08 clojurebot: java.lang.IllegalArgumentException: argument type mismatch

9:08 bpr: ah, lol nice

9:08 bOR_: hmm.

9:08 bpr: well, i got the int string from a (re-find #"\s(\d+\)\s" string) so it's sanitised

9:10 lol, i put an extra "\" ... too much emacs in my fingers lol

9:17 mids: bpr: I dont really see what is wrong with (Integer/parseInt s) though. if you use it a low, maybe create a shorthand parse-int function for it?

10:50 markskilbeck: Hi, all. Has anybody managed to set up penumbra on Windows?

10:51 The typical process of "lein deps ... etc" doesn't seem to work for me.

11:15 Kneferilis: Hello, how fantom compares to clojure?

11:20 imade: Kneferilis: I just took a quick peak at fantom, seems interesting, definitely a better java, maybe you can tell more what impression you have about it?

11:22 Kneferilis: imade: I haven't used it yet really.

11:22 imade: I haven't used clojure for long, maybe a month, so far the things I like: uniform syntax, dynamic typing (talk to the problem not to the compiler), easy to compose functions

11:23 there's more I guess, just need to discover clojure further

11:26 Kneferilis: clojure seems a very interesting language really

11:27 imade: and I would say that easy to get started also, the syntax rules are so simple

11:27 markskilbeck: imade++

11:28 Kneferilis: I just wanted to inlcude clojure in my plaform, but clojure for .net has libraries that conflict with ironpython and ironruby which my platform also supports

11:28 http://sourceforge.net/projects/mlip

11:34 besides I don't think that ClojureCLR (Clojure for .NET) supports Clojars, Clojure libraries for Java

11:35 I tried to include Clojure for Java in my platform, but it would keep trying to emit Java Bytes codes, if it was interpreted I could include it in my platform

11:45 lnostdal: why is it emitting java byte code a problem?

11:46 Kneferilis: well, IKVM doesn't seem to accept the java byte code, I have IKVM in a .NET application

11:46 IKVM is Java for .NET

12:08 lnostdal: oh

15:10 technomancy: I've run Clojure code on IKVM very briefly. seemed to work OK.

15:12 tufflax: I'm trying to make a chat server but I run it in a future to not block the repl, but something goes bad but I don't see the stack trace. Any ideas of how I can get to see the stack trace while still using a future?

15:17 tomoj: tufflax: what are you using for the io?

15:17 oh, hmm

15:17 tufflax: Does it matter? :p

15:19 tomoj: future seems to save the exception to throw on deref

15:19 if it's thrown by the thread that runs the future body

15:19 tufflax: oh yes, nice. thank you

15:38 raek: tufflax: while still using a future, you can either make the future thread catch the exception and then convey it to you somehow, or you can inspect the future object in the repl thread with future-done? (to not block if the thread is working) and deref

15:38 the first approach could be (try ... (catch Throwable e (.printStackTrace e))), i.e. print the stacktrace to stdout

15:39 tufflax: ok, thank you

15:39 raek: to get that behaviour, you can use a bare Thread instread of an ExecutionService (what 'future' uses)

15:41 future is made for executing tasks in parallel on threads that belong to a thread pool, so that's why the error handling works this way

15:41 tufflax: I noticed that the deref approach doesn't give me a stack trace, just shows what exception it was

15:42 raek: tufflax: the original exception is contained in the cause of the exception

15:43 tufflax: hmm can i get a hold of it somehow?

15:43 raek: tufflax: what repl are you using and in what IDE?

15:43 tufflax: vim with vimclojure

15:43 raek: when I develop in emacs, it shows me the whole stacktrace chain with all causes

15:43 tufflax: hm

15:44 raek: tufflax: if you only get the name of the exception, then you probably have the default clojure repl

15:44 tufflax: ok

15:44 raek: tufflax: in that case, you print the stacktrace as usual with (.printStackTrace *e)

15:44 I think that should print the causes too

15:45 tufflax: oh, yes *e

15:45 raek: in any case, you can get the caus of an exception by calling .getCause on it

15:45 tufflax: ok

15:46 hmm, that wasn't very informative...

15:46 getCause that is

15:47 raek: it will just return another exception object, which you can call .printStackTrace on

15:47 tufflax: oh

15:48 raek: iirc, that should have the same effect as calling .printStackTrace on the original object, except that one "Caused by" section will be missing

15:48 (well, the section before the first "Caused by" line)

15:51 thorwil: how do i get a <!DOCTYPE html> out of a hiccup defhtml?

15:53 amalloy: thorwil: (doctype :html5)

15:53 thorwil: Unable to resolve symbol: doctype in this contex

15:53 amalloy: it's in page-helpers

15:54 i note with some amusement while looking for this that the hiccup jar includes .form-helpers.clj.swp

15:55 thorwil: ah, dang! thank you!

16:00 tufflax: thank you raek, now it's off to #java to ask about using sockets with nio channels and select and all that, apparently i did something wrong :p

16:04 amalloy: tufflax: ##java

16:05 tufflax: yes, /j java takes me to the right place, but thanks :)

16:06 raek: anyone know what the extra # means?

16:06 bpr: i think the server appends a # when the previous channel gets too full

16:06 ... could be wrong (that's from some distant memory)

16:07 well, it creates a new channel with a # appended to the name, is what i meant if it wasn't clear

16:07 prepended*

16:08 amalloy: it's to do with how canonical/authoritative the channel owners are re the name. you can find it in the freenode daq

16:11 http://freenode.net/policy.shtml#channelownership

16:14 raek: ^

16:22 gfrlog: I can't remember the last time I was glad that (:foo {}) didn't throw an exception

16:22 usually I end up diagnosing some consequential problem seven functions later

17:32 TimMc: gfrlog: Yay for nil-propagation... :-/

17:33 Of course, it's not as bad as languages where what would normally be a NullPointerException comes out as evaluation-to-null.

17:33 gfrlog: yeah. I'm sure it's consistent with a lot of other functions...it's just what makes dynamic typing and such tiring...

17:33 what languages are those?

17:37 kzar: Anyone use couchdb from clojure here? Is clutch any good?

17:37 gfrlog: kzar: I have used it a small bit. I don't remember having trouble.

17:48 kzar: thanks I'll give it a shot

19:30 bpr: I'm tring to play with swank-clj, and when i execute lein swank-clj I get this exception: Exception in thread "main" java.lang.ClassNotFoundException: com.sun.jdi.VirtualMachine (jdi.clj:1)

19:30 does anyone know anything about that?

19:32 this is the jvm i'm running: https://gist.github.com/998244

20:29 bendlas: hi

20:47 gfrlog: bendlas: hello

Logging service provided by n01se.net