#clojure log - Aug 29 2010

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

0:28 cansado: i work primarily with web applications. would clojure be at all useful for me to learn?

0:30 JamesGecko: I'm having trouble getting started with Clojure in Eclipse with counterclockwise. I keep getting EOF and "unable to resolve symbol" errors.

0:30 technomancy: cansado: definitely; Clojure helped me transition from working with web applications to backend work. =)

0:31 cansado: just kidding. there are several good tools for doing web applications with Clojure, but there isn't the same richness of libraries as rails or django yet. depending on what you're doing that may or may not be an issue.

0:33 cansado: technomancy: i'm not really looking to do web development in clojure, i was just wondering if learning it would be helpful... like, maybe there's a distributed hoobajoob or something that's written with clojure in mind, i don't know :)

0:33 i've been trying to understand the problem domain, but it seems (to my ignorant eyes) just to be another general purpose programming language

0:34 technomancy: the closest thing to a killer app for Clojure is Incanter, for stats

0:34 my favourite web library for Clojure is enlive. fantastic tool, though I found it a bit tricky to get started.

0:35 cansado: ooo, incanter seems cool

0:40 Scriptor: cansado: another thing is that you could use it anywhere there's a jvm

0:41 cansado: Scriptor: right, but i was wondering what differentiated clojure from, say, scala or groovy

0:41 apart from its syntax :)

0:41 Scriptor: well, huge difference from scala, especially regarding the type system, as well as scala embraces oop more

0:42 not sure about the details of the differences from groovy

1:03 ihodes: i'm playing with Enlive right now. it's freaking awesome. i used it a while back, too; my impression of it has held. the problem is it's kinda been left alone since 1.1

1:04 it also mangles thing like <time datetime="2010-8-29" pubdate> i'm finding

1:34 wei_: hello, i have a newbie question

1:34 ihodes: shoot

1:34 wei_: why doesn't this produce the output I expect?

1:34 (do

1:34 (println "start")

1:34 (map #(println (+ % 1)) '(1 2 3))

1:34 (println "done"))

1:35 i expected start 1 2 3 done-- but the actual output is start done

1:35 hiredman: ~map

1:35 clojurebot: map is *LAZY*

1:36 ihodes: you need to wrap map with a (doall

1:36 to force the evaluation, because, as clojurebot helpfully pointed out, map is lazy

1:36 wei_: so, doall instead of do?

1:36 ihodes: and so won't compute (evaluate) anything unless it needs to. and it doesn't think it needs to, as you're doing nothing with what it returns (it'd return (nil nil nil) so you don't want to do anything with it

1:37 nah, keep do

1:37 doall needs to go just around map

1:37 wei_: ahhh i see

1:37 ihodes: e.g. (doall (map #(println (+ % 1)) '(1 2 3)))

1:37 cansado: is clojurebot written in clojure?

1:37 wei_: thank you! and.. how does clojurebot work?

1:38 ihodes: cansado: yes, by hireman

1:38 it's on github

1:38 hiredman*

1:38 http://github.com/hiredman/clojurebot

1:38 Raynes: sexpbot is another bot written in Clojure. Just to toot my own horn.

1:38 :>

1:39 $whatis sexpbot

1:39 sexpbot: sexpbot = http://github.com/Raynes/sexpbot

1:39 cansado: very cool. i'll check these bots out

1:40 thanks!

1:40 wei_: cool!

1:40 ihodes: for sure :)

3:50 LauJensen: Good morning all

4:39 lenw: morning all

4:39 quick moustache question - when defining routes, how do i express the route for "/" ?

4:52 LauJensen: [""]

4:52 @ lenw

5:02 lenw: thanks LauJensen - trying that

5:07 LauJensen: lenw: Actually Christophe put a lot of work into the README.md on the Github page, so if you want to work seriously with Moustache you should check that out :)

5:10 lenw: LauJensen: i have the capacity to easily confuse myself so thanks for always being helpful - trying the smallest working solution now

5:10 LauJensen: thanks that is working

5:11 LauJensen: np :)

5:51 Is there a clever way to get a unique machine ID from within Clojure?

5:55 Bjering: LauJensen, I installed ubuntu at home, and I learned that for my usage scenario epoll is simply worse than IOCP, both my epoll based C++ version and the "old NIO" jvm version performed much worse than the IOCP based versions on Windows 7 on the same hardware. An unexpected result.

5:55 lenw: LauJensen.getHardwareAddress() ?

5:55 oops lol

5:56 NetworkInterface.getHardwareAddress()

5:56 LauJensen: hehe

5:56 Bjering: Thats surprising

5:56 lenw: Yea I think that might be good

5:56 Bjering: yes, I agree. Makes me question the result, but I should beleive it, its easy enough. I'll chat on #boost about it with the IO gurus there, its their lib too that was better on windows than linux for me.

5:57 raek: LauJensen: what lenw said... http://en.wikipedia.org/wiki/UUID#Version_1_.28MAC_address.29

5:59 it would probably be a good idea to run the MAC address though a hash function or something as privacy might be an issue

6:01 LauJensen: Hard to get more unique than this

6:01 (->> (enumeration-seq (java.net.NetworkInterface/getNetworkInterfaces))

6:01 (map #(hash (.getHardwareAddress %)))

6:01 (apply str))

6:01 Thanks for the tip lenw

6:01 lenw: np

6:32 Bjering_: I am sorry to say, but these OS hangs with JDK7/aio on windows together with the x10 memory usage of the jvm version (its a naive impl, doing naive stupid things, but so is the C++ one, and worse visualvm dont tell me what is using the memory, I could optimize blindly) makes my technology choice single-threaded C++. A dead end I know, hopefully I can come back here in 3 years and rewrite version #2 of my engine. As it is I cannot defend not going with the

6:32 C++ version. Thanks to all helping me in my evaluation, this community is the worst part to leave. (well, that and the STM ;) )

6:33 AWizzArd: Bjering_: thanks for your report

6:33 So, there is a valid reason then why most games are written in C++. You really tried hard to get this working on the jvm.

6:33 fliebel: Bjering_: So… you're going to use java, or C++ for your game?

6:35 Bjering_: Ah, read it again, so C++

6:35 LauJensen: Bjering_: One thing. When I said that allocation was important, you said that it was the same in C++, its not. Since Clojures data is immutable, everytime you work on a collection you're allocating a new one, so keeping allocation low 10x as important in Clojure. With that said though, Im sorry you didn't reach an acceptable performance level. I think its possible.

6:35 fliebel: Bjering_: Good luck :)

6:35 Bjering_: C++, java performed no better than clojure (infact the AIO was only tested with java, never finished the Clojure version) Bottleneck was never Clojure (well atleast not after LauJensen helped me add some type-hints)

6:36 LauJensen: Bjering_: If you're Europe, consider coming to the next Conj Labs in October :)

6:39 Bjering_: fliebel: Also I hate Java as a language (but I must admit I am impressed with the tools, visualvm was awesome and the codecompletion etc you get with Eclipse is hard to get for a non-reflective language like C++). My C++ style is always one of alot of immutable value-objects, java doesnt really promote that style. Clojure does ofc, in the most extreme (and good way).

6:42 I thnk I was on the right tack before in C++, I am convinced I am even more so, this short adventure into Clojure (mostly reading, and then som small tests like this one) definly made a better C++ programmer. And in the end reinforced some of my earlier thoughts on things that C++ does much better than Java. (such as easy of value-oriented programmer rather than dabbling with identities all the time)

6:42 right track

6:43 hircus: Bjering_: I'd recommend exploring the Boost libraries -- there's a lot there to make your C++ programming more functional (including lambda!)

6:45 Bjering_: hircus, #boost is awesome, its core to all my things. One can get overboard with metaprogramming imho (I much prefere ANTLR to spirit for instance), but for the bsic stuff like expressing iterations they get it right. Even though imho boost::bind is enough 95% of the time, lambda is cool but not really essential.

6:47 AWizzArd: Bjering_: can you summarize your issue to a core problem? Is it the way the JVM is implemented under windows which lets you simply not have more connections open at the same time?

6:48 Bjering_: AWizzard: Core problems are 2.

6:49 . To reach CPU peroformance I need AIO, AIO needs JDK7, to me it seems in itself a little bad as much of the goodness of java goes away then, for instance I couldnt profile on CPU udage with visualvm on JDK7, I suspect many tools/libs dont support it yet, and any troulbe I have could be dismissed as "well its not released". One such problem I have is that my Windows machine hangs hard sometimes when I run my tests very hard.

6:50 that was 1

6:50 2. Memorywise my Java-version takes x10 of my C++ version.

6:51 AWizzArd: Can you roughly say how much ram is involved?

6:52 I don’t want to talk this away, but for example if the C++ version uses 8 MB and the JVM 100 MB, then this could still be acceptable (as your server could get over 65,000 MB RAM).

6:52 Bjering_: 100 MB in C++, 850 MB for java (when started with -Xmx500M to promote gcing, 1700MB for java when started with -Xmx3000M)

6:52 AWizzArd, sure but I do expect my server to be RAM constrained.

6:53 AWizzard: Well i want to balance RAM/CPU/Bandwidth to get the most _game_ I can out of it

6:53 AWizzArd: Yes sure.

6:54 I just thought that our perception of what "a lot of ram" means changes constantly.

6:54 Bjering_: yes

6:54 AWizzArd: Bjering_: have you tried a commercial profiler, such as YourKit?

6:56 Bjering_: AWizzArd, no I haven't. I guess there is s 3 in there too. My java experience is 2 years from year 2002 writing simple servlets for ecommerce, and 1 month this year making basic Android app. My C++ experience is 10 years, alot of it having todo with computer games. I just happens to know that infrastructure alot better.

6:57 LauJensen: Bjering_: Part of your assessment should probably include an overview of other games written in Java, with similar demands

6:59 AWizzArd: Bjering_: and which JVMs did you try? Suns/Oracles JDK 6 and 7, both on Windows, yes? Did you try the OpenJDK 7? Or IMBs JVM? And/Or did you try to run that code on Linux?

6:59 You could for example rent EC2 instances for some hours and test it on other OSes and different hardware. Both, C++ and Java.

6:59 Bjering_: LauJensen, its very hard to compare. Basically the kind of game I want to make isnt made. It has some parts from "real" MMOs such as the AAA titles, this is the syncrounous interaction etc. And some parts from the new "web/facebookMMO" that only have async interactions. The first is written by demigods who arent afaid of bending any tech to their will and have budgets way beyond what I can imagine. The latter is almost always writtien with PHP/myswl and me

6:59 mcache. But then you cant do whhat I want.

7:00 LauJensen: Ok

7:00 AWizzArd: I don't think you should be pushing OpenJDK for such a project

7:01 AWizzArd: I am sure Bjering_ knows best what to do, and when he decided to go with C++ after his hard evaluation phase this is a rational descision. I am just curious how other JVMs would have performed, and how it would have run on Linux.

7:02 LauJensen: Thats the one thing I feel thats left out, how the various versions would have performed on a new unix system. As I recall the tests were on an old machine

7:02 AWizzArd: Bjering_: the nice thing is that with some on-demand instances you can try different hardware and OSes for just a few dollars :)

7:04 Bjering_: Linux run alot abetter with old NIO then windows, but still worse than IOCP on Windows, but so did my C++ on linux, its like my problem is almost designed to be a scenario where IOCP beats epoll. Now that is a larger question and I am not sure I am prepared to go into tat and evaluate, it means understanding things deeper than "using boost::asio" and thats an abstraction barrier I am happy to stay behind.

7:04 LauJensen: I understand :)

7:05 And I guess if you have the time, writing the heavy IO bits of this program in C++ is not exactly a bad choice. Though maybe you should consider C instead?

7:09 Bjering_: I think it will be C++, C++ with the help of a domain specific language for gamelogic, and then an ANTLR generator that makes my C++ domain objects for me. It was the approach I had in mind when I decided I needed to give clojure one more serious try before going down such a heavy route.

7:10 LauJensen: Im curious why you prefer C++ to C, can you elaborate a little?

7:14 Bjering_: LauJensen, it is a good question. Part of it is heritage of my misguided OO-euphoric youth ;) But even when i try to look beyond that I thnk I prefere C++, its abstractions dont get in the way if you dont let them. Today I would also say boost is a huge reason, that library is full of win. On C it would be a much more diverse set of third-party libraries involved and it would be messier.

7:14 LauJensen: Isnt there a boost lib for C as well?

7:15 Bjering_: Nope. Can also be a platform thing. If you write for Windows, you want a layer, Win32 api makes me cry. If I wrote for Linux perhaps I would be happy with the C-api.

7:16 LauJensen: Ok, thanks

7:24 Bjering_: LauJensen: Just saw your comment re old machine, well, yesterday I went and bough a new harddrive (so to get dualboot without worrying about repartitioning/backuping/reinstalliing windows) and set up a dual boot. The results was not flattering for linux, as the C++ version was better on windows. Thus my thinking my problem much more like IOCP over epoll (atleast the epoll through boost::asio's abstraction)

7:25 LauJensen: Yea I understand

7:31 AWizzArd: Bjering_: so, will your server allow for 50k simultaneous connections and guarantee a fluid game play?

7:32 Bjering_: AWizzard: It will guarantee a fluid game play, if I have to cut down the 50k I will do that.

7:33 LauJensen: Bjering_: What do you do when your game becomes a huge success and you need to handle 55k ? How will you scale it ?

7:33 Bjering_: I'll hire some demigods ;)

7:34 AWizzArd: Most MMO games seem to cap their server capacity at a few thousand sim. players

7:34 LauJensen: I was thinking something like WoW

7:34 Bjering_: Nah. True answer. 1 When I cannot scale it vertically more (nitrogen cooling isnt enough) I'll shard it. 2. I might consider trying to build it to distribute and scale horizonatally, with areas and deal with all the complexities of migrations etc.

7:35 WoW shards at ~10000 concurrent players

7:35 AWizzArd: Yeah, although I am not certain that those run on one physical machine.

7:35 Bjering_: Biggest shard has Eve Online, ~35k concurrent players iirc. They run stackelss Python.

7:36 LauJensen: Nice

7:36 Bjering_: AWizz, last I hears they used 3 machines per world. One for each continent and one for instances.

7:36 AWizzArd: Yes, but Eve Online also has 7000 "zones".

7:36 Bjering_: yes

7:36 LauJensen: Bjering_: Maybe you should consider Python? :)

7:36 Bjering_: Now my game isn't going to be "walk around in a world"

7:36 AWizzArd: In each of such zones only a few players are flying around.

7:37 So, EO can put a few zones on one physical machine and will never have to manage more than a few hundred players

7:37 Bjering_: My game will be more like a multiplayer slow realtime Civilization if you like (its really hard to decribe it). Abit like those asynchrouous WebStrategy games that are out there, but fun ;)

7:38 LauJensen: Bjering_: You designing the entire game yourself?

7:38 AWizzArd: The JVM could still be a nice plattform if you don't insist on managing more than, say, 5k sim. players on one machine.

7:38 Bjering_: Me and my business partner, a veteran computer artist.

7:38 LauJensen: Bjering_: Hang on, I'll see if I can find some protips for you

7:39 Bjering_: This was insightful: http://www.youtube.com/watch?v=ihUt-163gZI

7:40 Bjering_: AWizzArd, yes, but it is a pity to do that. Our market is more the async webgames, and they target millions, they scales thanks to beeing async and not needing communication player to player, that restricts their game design alot.

7:42 LauJensen: Cool, googletalks are usually worth seeing.

7:42 LauJensen: I think I've enjoyed about 40% of those that I've seen

7:42 That one made up for it, as I every sentence taught me something new about design, which I wasn't aware of

7:47 AWizzArd: Bjering_: you can download an early access versoin of YourKit. Maybe that will run fine on JDK 7: http://www.yourkit.com/eap/index.jsp

7:48 Bjering_: AWizzArd: I like this, you dont want me to give up ;) Well Its sunday, this is spare time. I should try it!

7:49 AWizzArd: Bjering_: if it is not too much trouble for you, because I am really interested in the results, even if your server will be in C++.

7:49 With all your evaluation stuff you produced some really interesting info

7:50 Bjering_: Its good pricing for it too, in the "startup buyable" range, not like some of those C++ tools AAA gamestudios have that cost 6 or 7 digits...

7:50 AWizzArd: I think you can evaluate it for free. Seems to be a very advanced tool.

7:51 Bjering_: EA was free

7:51 AWizzArd: yess

8:01 Bjering_: AWizzArd: You know YourKit?

8:02 AWizzArd: I tried it some time ago. They also have demos online: http://www.yourkit.com/docs/index.jsp

8:02 Bjering_: Nut sure how to read this, I have java.lang.Thread.run() taking 67%, then my method inside it takes 1%, where did the other 66% go?

8:04 AWizzArd: Bjering_: I can't promise that my idea is right, but it could be this: only when code takes a significant amount of time it will be listed. So, you could have 100 methods taking up 0.5% each. Those will not be listed, and 50% are thus not seen.

8:05 In this case I would interpret it as: this run() thing is doing well. It has no bottleneck worth fixing.

8:05 Bjering_: ok, putting some serious stres on it now, If I appear offline its my OS that hung...

8:06 AWizzArd: (:

8:06 Bjering_: I am defintly abusing the heap I as suspected, but the eden heap shows saw-teeth pattern, it comes back to 0 often enough.

8:07 AWizzArd: Bjering_: really think about renting a EC2 instance. It will cost you max 2.88$ per hour, for a fat Xeon Server with 68 GB RAM.

8:08 Bjering_: AWizzArd, can I run a Windows image on it?

8:08 AWizzArd: sure

8:09 Windows Server that is.

8:09 Just decide which testing machine(s) you want: http://aws.amazon.com/ec2/instance-types/

8:10 The quadruple box is hosted on a Xeon X5550: http://www.cpubenchmark.net/high_end_cpus.html

8:11 Bjering_: dammit I had made a decision and here is this wondertool showing me my memory is ok, ms Old Gen is about the same as C++ usage, and the other stuff is returned on GC.cpu wise all the time is in java.nio.channels.AsynchrounousSocketChannel.write, this is suspected as I use heap-byte buffer there and it myst copy it to a direct byte buffer. (10 times for 10 users, that is one bad architectural decision of NIO.2 imho, why not have an IMUUTABLE ByteBuffer that

8:11 I could share for multiple writes?)

8:13 AWizzArd: hmm

8:13 Bjering_: ok, now I'll throttle up from 25k users to 50k and see if I can learn what is happening before my machine hangs.

8:13 AWizzArd: yes

8:14 fliebel: Bjering_: Does it write to a log, or is everything los when yout hang your computer?

8:15 Bjering_: good question, I'll check options and google for it

8:17 AWizzArd: If you do CPU-sampling, then the profiler will write this data to disk I think.

8:17 Bjering_: alright lets hops so, cannot find any setting for it. here we go.

8:22 AWizzArd: Bjering_: it should tell you the path to where it saved the .snapshot file.

8:25 Bjering: no, dont see any log after the crash.

8:25 AWizzArd: Bjering: did you do a CPU sampling snapshot?

8:25 Bjering: I have a reproducable "HANG THE OS" bug though probably should contact Microsoft and/or the JDK7 people.

8:26 AWizzArd: In principle it should be nearly impossible to hang Windows 7.

8:26 Bjering: AWizzard no, Ill try that

8:26 AWizzArd: Maybe a hardware problem.

8:26 Bjering: yes, could be the network driver that is the bad guy

8:26 network card driver

8:26 AWizzArd: Bjering: watch the cpu profiling demo video: http://www.yourkit.com/docs/index.jsp

8:28 Bjering: But I wonder if the network card driver is involved as I test on localhost. Maybe.

8:28 watching video

8:28 AWizzArd: Bjering: you could rent 2 instances from Amazon. One which runs your code, the other doing requests, internally in Amazons network.

8:29 Bjering: Well, it is just adding unknowns. I dont want to test the bandwith thing yet, it shouldnt crash first.

8:36 LauJensen: AWizzArd: How many % do you get, everytime to sell an Amazon instance? :)

8:36 Bjering: the "fun" part is that I have been involved in another project ~2 years ago that also hung windows server. A server written in C# using asynch IO. I then sworde never to use a complex vm solution again as I run into problems I cannot solve, with C++ its more transperant how I have done wrong.

8:38 nothing in video on how to have it save continously

8:38 Active forum it seems, I'll post there

8:40 AWizzArd: Bjering: do you know +/- the point on which it hangs your system? 25k conns seem to go fine, but for 50k it crashes. Maybe on 35k it still is fine?

8:40 Bjering: AWizzard: It depends on how fast I add users.

8:41 LauJensen: Bjering: All of those clients are generating a random amount of network activity ?

8:42 Bjering: What I think happens is that it congests, and that the jvm handles badly when it cannot keep up with a channel, ie thu queue with work items grow much faster the threadppol can deal with it. Its odd though, as I get no warning, no visble spike.

8:43 could be a tcp buffer becomming full, but that should just close the connedction.

8:43 yes

8:44 thing is I can get that scenario with the C++ one too, ie the tcp-connection closes conections on me when their buffers gets full.

8:44 LauJensen: Bjering: You could eliminate some unknowns if you killed all traffic and just opened connections, thinking that it might expose a bad driver?

8:44 Bjering: but it dont hang.

8:45 LauJensen, yet, the C++ use the same driver.

8:45 I suspect

8:45 LauJensen: True

8:45 AWizzArd: It still is surprising that a program can do anything to crash the OS.

8:46 The kernel should be stable enough to just end that process instead of crashing.

8:46 Bjering: http://forums.yourkit.com/viewtopic.php?f=2&t=3348 :(

8:46 It doesnt _crash_ the OS. It makes it completly unresponsive

8:46 I should nice the jvm process and see if still does.

8:47 LauJensen: AWizzArd: Not too uncommon for resource issues?

8:50 Bjering: now testing with both jvm and stressbot running on below normal priority

8:52 it takes time to build up the load, havent found a way to turn of win 7 syn-flood protection so it throttles my connect/accepts to about ~100 per sec.

8:52 AWizzArd: maybe this is easier on WS 2008

8:53 Bjering: yes, could be. I think Windows 7 share alot with WS 2008 though, but this kind of things are ofc more server specific.

8:54 I will install a WS 2008 and test.

8:54 AWizzArd: you could also just test it on EC2 ;)

8:55 Bjering: Well, I just bought myself a HD yesterday, I could take a partition of it and do WS 2008 and get some value from my MSDN subscription.

8:56 AWizzArd: oh good

8:56 Bjering: I view virtualization a bit lite outsourcing, its great, but only do it with things you understand 100%. You dont wnat to track down problems remote.

8:57 LauJensen: Bjering: An instance isn't very 'remote' though. There's not much I can do with a physical linux box that I cant do via ssh

9:00 Bjering_: nice didnt help....

9:00 AWizzArd: Bjering_: again 50k?

9:01 Bjering_: ~40k actually

9:01 clojurebot: Titim gan éirí ort.

9:02 AWizzArd: btw, will your connections stay open to the client all the time, or is it closed directly after you replied to the request?

9:02 Bjering_: Oh they are open

9:03 Its a chat, I write to them

9:07 LauJensen: I has to be some kind of starvation

9:07 Bjering_: what I dont get is that the jvm gets to grab that hangs it so hard, I am not even running the jvm as admin.

9:08 ofc, i am not 100% its the jvm that hangs at all. could be anything really. It just only happens when I run this test with the jvm.

9:09 LauJensen: Bjering_: You might want to spend 10 minutes getting familiar with tweaking the GC, that can sometimes buy you as much as 20% perf and a smoother ride

9:09 There's a good chance the GC is helping you crash

9:16 Bjering_: Yes, GC is very helpful I am sure ;)

9:16 AWizzArd: Bjering_: can you setup your bot so that it will build up the 40k conns slower?

9:17 Bjering_: AWizzard yes

9:20 I'll do that, just to test, 50 per sec, means I need 17 minutes to get to 50k, then the next thing should probably be to simplify the scenario, skip the "chat" part and just play with simple request/responses and see If I can reproduce it.

9:21 AWizzArd: Bjering_: and with YourKit you can profile for GC as well.

9:21 Bjering_: LauJensen, re gc, I know what I do bad, I (almost on purpose) create massive amount of strings and have them gc:ed away. What option would you recommend to handle that?

9:22 LauJensen: Bjering_: Well, first off, String is evil as it takes 2 bytes per char

9:23 Bjering_: my "parse" is just splitting a string into a vector of strings. This isn't optimal in any way, I just wanted it basic, I use the same horrible approach in C++ (and you really shouldnt hit malloc/free that much in c++ either...)

9:24 LauJensen: Bjering_: http://java.sun.com/performance/reference/whitepapers/tuning.html#section4.2.1

9:25 There are some good advice on tweaking the GC. In regards to Java/Clojure performance, just avoid String as a heavy data-type as they consume a ton of memory

9:26 Bjering_: its abit worrying that the official side describes this process as a trial and error way. I always get bad feelings from gc tweaking. Actually I hate gc... I never ever had a problem with memory in C++, its just silly this... I understand now clojure needs it, but I really miss my stack objects.

9:27 LauJensen: hehe

9:28 I've had good results by tweaking the GC in the past. And I remember one heavy processing job, where I cut out Strings an doubled performance

9:29 Bjering_: sure, but it should HANG if you use them. This is my worry now. I mean I can fix _this_ problem. But I need to know why and when I crash, or I can have no confidence. I can say "well I think I fixed it with this jvm switch..." thats like coding multithreaded C++ and thing good testsuit and sprinkling locks is a good approach. it is just hiding an architectural flaw until some rainy tomorrow...

9:31 I mean, it _should not_ hang...

9:34 lenw: does anyone know if the enlive tool for htm caches the templates and snippets ? I am changin the underlying html files and still getting way old stuff ?

9:37 LauJensen: lenw: Yes, it uses its own kind of state machine, which memoizes the html

9:37 lenw: LauJensen: for dev how do i ask it to refresh ?

9:38 LauJensen: lenw: protip: Separate all of your templates into their own namespace, and define your moustache app as (def routes (app (wrap-reload '[myns.templates]) [""] ...))

9:38 If this is a Moustache project, they will refresh every time you reload the page

9:38 If its not moustache... then make some special hack, but be aware, Enlive can leak a little memory when you reload-all on it too often

9:38 lenw: cool and take the wrap-reload out for prod ?

9:38 yes it is moustache

9:38 LauJensen: Bjering_: I agree, but you didn't manage to hang Linux did you ?

9:39 lenw: yes, or simply make it check of a production? var and only attach itself if its there

9:39 lenw: LauJensen: thanks

9:39 LauJensen: np

9:46 lenw: LauJensen: thats working cheers

9:50 Bjering_: its interesting how so far EVERYtweak I do to the gc makes me drop connections earlier.

9:52 LauJensen: "Tweaking - You're doing it wrong"

9:54 Bjering_: yes, but I am lost, I am applying trial and error. I have a theory, the best gc strategy for my app is to GC all the time everything. Do you know the switch for that?

9:58 LauJensen: sec

10:00 Bjering_: Im reading the docs as though you want the Throughput Collector and a fixed memory size (xms = xmx)

10:01 Bjering_: the 4.2.1 ?

10:01 LauJensen: The 5.2

10:02 Bjering_: ?

10:02 LauJensen: http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html#0.0.0.The%20Throughput%20Collector%7Coutline

10:07 AWizzArd: Bjering_: you can profile the GC at 30k conns. Perhaps it already shows strange behaviour at that point, or it may be very harmless.

10:09 Bjering_: Here is what I learn, all tweaks that leads to postponing GC, that so far all tweaks do i can see my eden live for a long time in YourKit, they all disconnect stressbots when they do finally do their gc.

10:09 wow that sentence got garbled

10:11 All tweaks I have made seems to postpone gc. And all such fail when they eventually DO their gc. Fail as in my stressbots gets their sockets closed.

10:14 LauJensen: Clojure code of Java code?

10:14 Bjering_: java

10:14 LauJensen: hehe, OR java code.. I need a new keyboard, AWizzArd when can you deliver?

10:15 Bjering_: This is puzzeling, I wont be able to sleep before you figure out why it hangs.. Could you try to limit the amount of data my ridding the strings?

10:16 Bjering_: here is a funny fail I get. I did the "NO DONT DO THAT" as a half depserate thing, that is call system.gc all the time. That causes disconnect right away.

10:16 This is a path I should pursue, shouldnt disconenct just because something takes alittle time

10:18 Ill see how it feels about a sleep

10:20 AWizzArd: LauJensen: did you already order one?

10:21 LauJensen: AWizzArd: No I didn't yet - I cant decide if I should wait for Conj Labs Frankfurt or not :)

10:21 AWizzArd: better not wait

10:21 LauJensen: You're probably right

10:23 Bjering_: Well, I have my app failing in two ways, the nice way with "connections dropped" I can get that by adding a sleep in my completion handlers, or by "tweaking" the gc in such a way that it does few (but long) runs. Then it is the evil way of failing, the hard hang. I do not know what that is from.

10:24 LauJensen: Bjering_: And running that exact code in your Ubuntu box, fails the exact same way ?

10:25 Bjering_: No on Ubunto it fails the "nice way" but much earlier.

10:25 LauJensen: ok, same memory allocation for the jvm ?

10:27 Bjering_: well, I havent checked. Actually the ubuntu trials I did wasnt this code, it was all "old NIO" code, not this JDK7/nio.2 code. I suspect I wont see any massive benifit from NIO.2 on linux as its native op is epoll which doesnt map as good to async io.

10:28 LauJensen: ok

10:28 I think the trick is to determine why GC causes drops

10:29 Bjering_: Agree, and it doesnt have to be gc, I can get it with a sleep in my completion handler

10:29 10 ms sleep is enough

10:29 LauJensen: oh ok

10:29 And no exceptions are being thrown anywhere?

10:31 * Bjering_ was just handed a beer by the nice Funcom employee across the hall, great they take pity on me... I should try drinking beer, I have tried most other things ;)

10:34 Bjering_: LauJensen: I'll keep looking at this. But it will be a backburner/sparetime project, I'll go with C++ I think.

10:35 if anyone wants a .rar of all my source email me at d e p i c t i v e l o g i c ( at ) g m a i l . c o m (see if that keeps the spam at bay....)

10:37 LauJensen: I might need a copy just to do a blogpost and demo a 50k client version in Clojure :) Or get ridiculed trying

10:47 Bahman: Hi all!

10:48 LauJensen: Bada-bahman! :)

11:02 Bahman: Yo LauJensen!

11:02 What's that 'Bada' LauJensen?

11:07 stacktracer: what's the best way to get "lein repl" to start in the user ns, instead of clojure.core?

11:12 slyrus: morning y'all

11:17 Bahman: Morning slyrus!

11:30 LauJensen: Bahman: I dont remember, some TV show with a scientist who said "BadaBING, BadaBOOM" repeatedly, so I just thought it went alright with Bada-Bahman! :)

11:31 Bahman: LauJensen: I never ever thought that my name could be source of so many imaginations :-)

11:49 slyrus: anyone have any examples of non-trivial deftypes (besides defrecord) in the wild?

12:01 bobo_: i wonder how Bjerings stuff would work out in erlang, or scala+akka. sounds like alot of messaging and so on...

12:13 mfex: slyrus: there's the priority map proposal on the clojure dev ml, perhaps not in the wild but certainly non-trivial

12:22 slyrus: ok, thanks mfex

12:23 lenw: whats does the syntax [:somekey :> something-else] mean - specifically the :> ?

12:24 AWizzArd: It is a vector of three keywords.

12:24 lenw: :> is a keyword !

12:24 AWizzArd: ,(class :>)

12:24 clojurebot: clojure.lang.Keyword

12:24 lenw: is that a convention like the underscore

12:25 AWizzArd: did you try (find-doc ":>")?

12:25 lenw: duh me - thanks AWizzArd !

12:26 AWizzArd: I would guess that a function or macro just handles this :> keyword in some special way

12:27 lenw: yes i see that now - not been at this long and everytime i see a new piece of code i jump to the conclusion that it must be a new keyword that i have not seen yet cause that the way it is in java ...

12:27 my mind is reorganising !

12:49 jlf`: anyone know of a solution to the conjure/clojure 1.2 incompatibility described at http://groups.google.com/group/clojure-conjure/msg/67547c5c0edd0928 ?

12:50 the error is "java.lang.IllegalArgumentException: Metadata must be Symbol,Keyword,String or Map (scriptjure.clj:70) " and that line in scriptjure.clj contains "(def infix-operators (set ['+ '- '/ '* '% '== '=== '< '> '<= '>= '!= '<< '>> '<<< '>>> '!== '& '^ '| '&& '||]))"

12:55 seems like the '^ is guilty

12:55 LauJensen: lenw: :body :> :div means the 'div' tag directly under the body tag

12:55 Its a CSS selector which ensures that your styles don't leak

12:56 Enlive always adheres strictly to CSS standards

14:33 arnorhs: g'day

14:33 scala?

14:33 clojurebot: Unfortunately the standard idiom of consuming an infinite/unbounded resource as a stream can be problematic unless you're really careful -- seen in #scala

14:39 * arnorhs is configuring gedit to play nice with clojure

14:42 LauJensen: lenw: did you catch that ?

14:43 lenw: LauJensen: yes i did thanks

14:43 LauJensen: its starting to make sense !

14:43 LauJensen: Good, you'll also see that stuff in quality CSS files like div#content > h1 { something }

14:46 lenw: LauJensen: the thing that I am getting used to is the fluidity of the parameters and how easy it is to map a lisp into the solution domain - i guess thats the dsl idea

14:52 That the syntax is more fluid is prob a better way to say it

15:10 bobo_: how do i add more to a existing key in the session in ring/compojure?

15:10 ie :session {:tasks (str task)}})

15:11 i want to append task to whatever is in :tasks already

15:17 LauJensen: bobo_: Decide upon a data format which makes sense, vector, hashmap, set?

15:21 ,(let [session {:task "first task"}] (assoc session :task (if (vector? (:task session)) (conj (:task session) "second task") (vector (:task session) "second task"))))

15:21 clojurebot: {:task ["first task" "second task"]}

15:22 LauJensen: And then make some kind of function, which appends to it, and run that on your response, so (assoc response :task helper-fn)

15:29 Raynes: LauJensen: What was it you asked me to whitelist? DateTime?

15:29 technomancy: stacktracer: that's fixed in git for lein

15:29 LauJensen: Raynes: Yea I sent you a mail

15:29 technomancy: should be released in a few days

15:29 LauJensen: a $mail

15:30 Raynes: LauJensen: Yeah, I was in the middle of a bit of a refactor and it screwed up, but raek told me later on what you said.

15:31 LauJensen: oh alright - Basically I'll send you a mail everytime something harmless doesn't eval

15:31 Raynes: Sounds good. :>

16:01 krl: how do i make a variable binding work across a map-call (or equivalent)?

16:04 AWizzArd: krl: can you describe what you want in other words?

16:05 LauJensen: krl: also note, that a map call isnt the same as a pmap call in this context

16:07 silveen: where did clojure.contrib.seq-utils/indexed go in 1.2? after updating (to RC2) I get Var unbound errors on it

16:08 krl: AWizzArd i need an incrementing variable across the map-call. i guess it's a problem in that map might have undefined execution order?

16:09 LauJensen: ,(map #(vector %1 %2) (range) [1 2 3 4 5])

16:09 clojurebot: ([0 1] [1 2] [2 3] [3 4] [4 5])

16:09 LauJensen: krl: would that work ? where %1 is the incrementor

16:10 chouser: there's now map-indexed and keep-indexed

16:10 krl: no, the increments are non-regular

16:11 LauJensen: chouser: map-indexed looks very complex, given that it only does what I did with map above

16:12 chouser: its implementation or its usage?

16:13 LauJensen: implementation

16:13 chouser: yeah. It's a performance thing.

16:14 it is sometimes a bit simpler to use and also a bit faster.

16:14 LauJensen: chunks :(

16:15 chouser: yours was chunked too

16:15 danlarkin: chunks!!!!!!!!!!!1111111

16:15 LauJensen: chouser: I know - I just dont like them chunks

16:16 I thought when cells first arrived, that they were going to take away the chunks :[

16:19 chouser: they might yet

16:21 LauJensen: You'll replace them with fingertrees?

16:21 How's that going btw, sorted out that perf problem ?

16:21 hiredman: I've been playing with writing clojure to generate a class file with a bunch of static methods as a replacement for c.l.Numbers

16:43 fuchsd: I'm using Leiningen 1.3.0, and I have a brand new project. When I type 'lein repl' from within my project directory, it seems like my project is not on the classpath. Do I have to do something else to get my project on the classpath?

16:44 (for example, if my project is called test-project, (ns test-project.core) puts me in an empty namespace)

16:45 technomancy: fuchsd: that's correct behaviour; nothing to do with leiningen

16:45 you need to (require 'test-project.core) first

16:45 or (doto 'test-project.core require in-ns) if you're feeling fancy

16:47 and let's be honest: feeling fancy is fine.

16:48 fuchsd: Heh

16:48 Awesome, thanks!

17:00 Ahh, I get the fanciness now; thanks for the tip.

17:19 LauJensen: Does this mean Im famous now? http://twitter.com/smashingmag/status/22441977953

17:20 technomancy: Internet Famous!

17:21 ska2342: Hm, quitting coffee. actually I thought about it just a few days ago. Really worth it?

17:21 technomancy: http://images.google.com/images?q=don%27t%20worry%2C%20I%27m%20from%20the%20internet

17:21 LauJensen: ska2342: Trust me, its the way to go

17:21 technomancy: ska2342: there's a middle ground between three cups a day and swearing off it.

17:22 LauJensen: technomancy: its poison- Im convinced now that Im off it, that its incredibly bad for your body and your mind, it just needs to go

17:22 ska2342: technomancy: on bad days I think I'm at 3 days before and after midday eacht, on normal days it's more like to cups in the morning and one in the afternoon

17:22 technomancy: anything is deadly if you take enough of it.

17:22 LauJensen: And honestly, Ive been off it for a while now, and I dont think Ive ever been as mentally sharp as I am now, theres still a tangible difference

17:22 technomancy: even H2O

17:22 chouser: I'm pretty sure caffine effects different people in different ways.

17:23 seangrove: Hey all, this blows out the heaps space in clojure: http://paste.lisp.org/display/114032

17:23 LauJensen: chouser: And Im pretty sure thats its bad for all of them

17:23 seangrove: Seems like none of it is really calculated until the final line when it's output

17:23 LauJensen: Anyway, you can drink what you like, Im not concerned about what you guys drink, Im just saying for me it was a very good thing to get rid off

17:24 seangrove: Which is actually quite cool, but I'm wondering if I should be doing it in some more efficient way

17:25 chouser: I've been off caffine for months at a time before and haven't noticed much difference.

17:25 getting off sugary sodas has had various benefits.

17:25 technomancy: chouser: same here

17:25 LauJensen: chouser: How much coffee/caffeine did you usually intake?

17:26 ska2342: getting off chocolate would have benefits, too :-)

17:26 hircus: seangrove: filter, and most sequence-processing functions in Clojure, is lazy -- so yes, until you try printing, the final sequence is not computed

17:26 seangrove: hircus: Thought so

17:26 LauJensen: hircus: depending on the range

17:27 hircus: LauJensen: ah. I guess at some point the overhead of storing all the delayed computations is too much, and some of the pending computation is actually computed?

17:27 tomoj: seangrove: remember what I said about holding the head?

17:27 LauJensen: ,(take 1 (map #(print %) (range)))

17:27 clojurebot: (nil)

17:28 LauJensen: $(take 1 (map #(print %) (range)))

17:28 hircus: On my system, that will print up to 31

17:28 kotarak: chunkiness

17:28 LauJensen: Exactly

17:28 seangrove: tomoj: Ah, that's right

17:28 LauJensen: hircus: So like kotarak, Clojure is chunky and will compute in chunks of 32

17:28 hircus: aha. right. so once a sequence is realized, it's done in blocks

17:29 chouser: some seqs and chunked, some are not. chunks can be of differing sizes

17:29 hircus: but the problem here is that to get 32 results out of the final sequence, you have to get > 32 results out of the previous sequence, and so on

17:29 chouser: s/and/are/

17:29 sexpbot: some seqs are chunked, some are not. chunks can be of differing sizes

17:29 LauJensen: chouser: really? do tell

17:32 tomoj: ,(take 1 (map println (range)))

17:32 clojurebot: (nil)

17:32 tomoj: hmm, no output?

17:32 well, compare to (take 1 (map println (iterate inc 0)))

17:38 chouser: LauJensen: https://gist.github.com/ca94967979ba35dcc39d

17:39 LauJensen: chouser: why 16?

17:39 chouser: half of 32

17:40 LauJensen: but why not 32?

17:40 chouser: filter took one chunk of 32, filtered just the odd numbers, and returned one chunk.

17:40 filter doesn't combine chunks (though I suppose it could)

17:41 LauJensen: ooh

17:41 Insightful, thanks Chris

18:13 ihodes: ,(java.util.Calendar.)

18:13 clojurebot: java.lang.IllegalArgumentException: No matching ctor found for class java.util.Calendar

18:14 ihodes: ah protected…

18:14 ,(.get (java.util.GregorianCalendar.) GregorianCalendar/MONTH)

18:14 clojurebot: java.lang.Exception: No such namespace: GregorianCalendar

18:15 raek: ,(.get (java.util.GregorianCalendar.) java.util.GregorianCalendar/MONTH)

18:15 clojurebot: 7

18:15 ihodes: got it. thanks clojurebot :)

18:15 yeah forgot my qualification – moved back to my repl anyway

18:15 :)

18:39 tcrayford: Has anybody got a good solution for mocking out functions used inside other functions made using def rather than defn?

18:40 hiredman: uh

18:40 defn is the same thing as def + fn

18:40 tcrayford: there's an interesting weirdness here though

18:41 hiredman: I doubt it

18:41 tcrayford: if I have a definition: (def foo (comp bar baz bat)), and I want to replace bar using binding, things seem to be weird. Maybe I'm just being dumb though

18:42 (the tests pass when I define foo as (defn foo [x] (bar (baz (bat x)))), but fail when I use comp

18:43 hiredman: because come is a function, and it's arguments are evaluated before they are passed in, just like the arguments to any function

18:43 comp

18:43 tcrayford: exactly, was wondering if there was a solution to that

18:44 (sorry, probably failed at explaining it)

18:45 (currently I'm just using the defn form, but it feels uglier than using comp)

18:47 ihodes: tcrayford: i think defn is the way to go here. why do you want to use def?

18:47 ah, prettiness.

18:47 fair enough

18:48 (defn foo [x] ((comp foo bar bat) x))

18:48 works?

18:48 clojurebot: http://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png

18:48 tcrayford: works, but ugly compared to using def with comp

18:49 ihodes: comp is a functional form, and using a global binding is gonna get you uglies when you try to mix it with the beauty of functionality

18:49 *philosophy*

18:49 i also don't think it's too ugly, myself

18:50 Raynes: Why would you defn a comp'd function?

18:50 It's not as ugly as it is silly.

18:50 ihodes: read up to see why it's not working for him, Raynes

18:50 though now that i read up, i may have misunderstood him

18:51 tcrayford: I think you understand here

18:51 Raynes: Oh.

18:52 ihodes: anyway, i've got a question regarding running a swank swank on a remote server, and connecting to it with slime via emacs and ssh. how do i go about doing that?

18:53 swank server* not swank swank...

18:53 tcrayford: you have ssh access?

18:54 set up an ssh tunnel and slime-connect through it

18:55 ihodes: ah of course…thanks haha

18:55 was thinking there was a emacsy way of doing it.

19:58 stacktracer: technomancy: thanks!

20:02 ihodes: looks like rlwrap isn't working on archlinux/something to do with leiningen? http://cl.ly/2AFA

20:14 for some reason i'm unable to get slime to bind to the port i have open to my remote swank server… anyone familiar with ssh tunneling and using swank remotely?

20:16 rmarianski: ihodes: i've never tried it with swank, but i tunnel using ssh -NL <local_port>:localhost:<remote_port> <remote_host>

20:18 ihodes: i was using ssh -f user@machine -L <local_port>:remotehost:<remote_port> -N

21:00 florianjunker: Is there a limit for the number of refs? I'm currently trying to make about 2 million of them and clojure doesn't seem to like it.

21:01 And, how much memory does one ref consume?

21:02 danlarkin: florianjunker: in what sense does something with no emotion not "like" it?

21:02 florianjunker: danlarkin: Slowness.

21:02 ssideris: eidika sthn teleytaia photo fainetai poly hot

21:02 oops

21:02 wrong window

21:03 florianjunker: I guess there's some philosophy there, but it's 3:00 here, and I'm not going to think about that.

21:05 danlarkin: just creating refs does not involve the stm, so it's probably the JVM having memory issues?

21:05 florianjunker: danlarkin: Yeah, going to increase max memory.

21:06 danlarkin: how much heap space are you allocating

21:06 also, what data structures are you putting into the refs

21:06 and are you just creating them, or manipulating them as well?

21:07 florianjunker: So, Xmx at 1024m. Just creating right now. And there are maps in there.

21:14 So, one cannot fit 2 million refs into 1GB of RAM. Does anybody know how much overhead one ref has?

21:21 seancorfield: been playing with lein this afternoon (writing plugins and hooks - just for fun) and wondering whether lein questions are on-topic, given that there's also a #leiningen channel?

21:23 florianjunker: seancorfield: Non authorative answer: leiningen is that central to clojure, that discussion about it should be on-topic here.

21:25 seancorfield: florianjunker: thanx :)

21:26 ihodes: seancorfield: yeah people often ask lein questions here. what's your issue?

21:34 seancorfield: i asked it on the clojure list but i'll try to restate succinctly... i'm writing a hook for leiningen and i can get the basic stuff working but i want to wrap compile with a binding of *load-tests* to false (in clojure.test)

21:34 but i can't figure out how to get clojure.test/*load-tests* to resolve

21:35 if i add :require or :use, i get an error that Warning: problem requiring hooks: java.lang.NoClassDefFoundError: Could not initialize class clojure.test__init (notests.clj:1)

21:36 it's not a big deal... just curious if i can make it work so i can write tests in my regular source files and then have lein omit them when it compiles for production :)

21:38 ihodes: i can't help you there–lein's tests are pretty foreign to me. you can hang around for technomancy to show up, as he invariably does. he's quite helpful, and the creator of lein

21:40 seancorfield: yeah, i'm just scratching an itch right now :) pleased i managed to create a working hook and a working plugin already... leiningen is pretty neat!

21:41 really enjoying learning clojure too... just trying to find some project i can use it on for real!

21:44 ihodes: i know the feeling :) took me a while to find one

21:45 now i'm working on the second iteration of my first project, with one big one behind me. love the language :)

21:45 cansado: seancorfield: do you do clojure or any other jvm languages from within your cf framework, or do you just work outside of cf entirely?

21:45 ihodes: also, should you dig into lein some more,p contributing is a breeze and feels good, too :)

21:47 seancorfield: i'm currently using scala with cfml (running on railo, the free open source cfml engine - a jboss community project)

21:47 i previously used groovy with cfml (also on railo, back before it went open source)

21:47 i like to learn a new language every year so 2008 was groovy, 2009 was scala and 2010 is supposed to be clojure

21:48 i like to mix'n'match languages in projects (on the jvm)

21:49 cansado: you're running out of jvm languages. what's slated for 2011? :)

21:49 seancorfield: hahaha... don't know yet

21:49 i haven't - yet - used more than two languages together so maybe that'll be 2011's challenge ;)

22:04 amaevis: Hi... It seems idiomatic to use agents to update a database upon completion of a dosync. What if you wanted the database updates to be synchronous, i.e. ordered the same way that dosync blocks are ordered (actually being executed)?

22:09 seancorfield: that raises another question in my head: what are most folks using in clojure for basic database access?

22:17 Raynes: cansado: Maybe Ola Bini's new Seph language will be usable in 2011.

22:18 Might be an interesting 2011.

22:23 ihodes: seancorfield: i think clojure.sql gets some use: but i haven't used it any.

22:25 seancorfield: just looking at it now - it's low level but it'll handle my needs for now i think

22:48 bortreb: anyone have recommendations for th best way to deal with images? both in terms of speed and also ease of use?

22:50 right now I'm using a hash map with keys like [30 50] for 30 pixles right and 50 pixels down, which map to {:r 255 :g 255 :b 255} to describe colors, it's elegant but far too slow and memory hungry

23:03 seancorfield: cool, i just read data from mysql with clojure.contrib.sql - i feel such a sense of achievement!

Logging service provided by n01se.net