#clojure log - Nov 03 2009

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

0:00 tomoj: huh

0:00 not for max or +, right?

0:01 hiredman: no

0:01 not for operations over sequences

0:01 but just for functions that take a lot of args

0:01 tomoj: ah

0:02 hiredman: http://gist.github.com/178350

0:03 (sched/fixedrate {:task #(dump-dict-is config) :start-delay 1 :rate 10 :unit (:minutes sched/unit)})

1:35 adityo: ~max people

1:36 hiredman: wow

1:37 clojurebot is flipping out

1:41 oh

1:44 j3ff: ,(. Math abs (/ 5 2))

1:44 oops

1:45 saw ato do that ;P

1:45 anyone know why the math abs function doesnt work on a fraction?

1:46 ,(. Math abs -5)

1:46 clojurebot: 5

1:46 _ato: Math is a java library and doesn't know anything about fractions

1:46 ,(. Math abs (float (/ 5 2)))

1:46 j3ff: ic

1:46 clojurebot: 2.5

1:46 j3ff: thanks

1:46 _ato: though

1:47 that doens't help if you want a fraction

1:47 j3ff: no i just need the value

1:47 _ato: hmm.. I wonder if...

1:48 ,(clojure.contrib.math/abs (/ 5 2))

1:48 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.math

1:48 j3ff: ,(use 'clojure.contrib.math)

1:48 clojurebot: nil

1:48 j3ff: ,(clojure.contib.math/abs (/ 5 2))

1:48 clojurebot: java.lang.ClassNotFoundException: clojure.contib.math

1:49 _ato: ,(abs (/ 5 2))

1:49 clojurebot: 5/2

1:49 _ato: yeah

1:49 there we go

1:49 j3ff: haha cool

1:49 tomoj: ,(abs (- (/ 5 2)))

1:49 clojurebot: 5/2

1:49 tomoj: ~def abs

1:50 I just searched youtube for "did clojure kill god"

4:44 ordnungswidrig: hi all

4:47 zefhemel: hello

5:59 krumholt: hi i am using emacs with clojure-mode and i have a java application i like to extend from clojure. this application will create a window and call exit on close when closed. This will also terminate slime. does anyone know a way to prevent this? it's very annoying in testing

6:02 raek: don't call exit?

6:02 maybe you could just close/hide the window

6:03 krumholt: raek, the application will call exit. it's a java application and i can't change that

6:04 i want to "capture" it or something if possible :)

6:09 CalJunior: I trying to port some Java code to Clojure and have rather basic question. I would like to declare a new variable 'client' of type 'EClientSocket' (a class from the API I am implementing). The Java code is: EClientSocket client = new EClientSocket(this);

6:11 I tried (let [client (.EClientSocket this)]) which throws an exception. Unable to resolve symbol: this in this context (NO_SOURCE_FILE:19)

6:11 rfgpfeiffer: what is this in this context?

6:11 CalJunior: (typo: I AM trying to port …)

6:11 good question

6:12 rfgpfeiffer: this refers to an object, which class are you in?

6:12 CalJunior: The class is called Wrapper

6:13 rfgpfeiffer: you have to pass the instance of wrapper explicitly

6:13 CalJunior: This is what I did. (ns TestJavaClient.Wrapper

6:13 (:gen-class

6:13 :name TestJavaClient.Wrapper

6:13 :implements [EWrapper]

6:13 )

6:14 rfgpfeiffer: that's not what i mean

6:14 what does 'this' refer to in the java version?

6:15 CalJunior: That's one of the problems. I do not know. I think it refers to an object in the API library.

6:15 Did I already tell you I am a Java newbie? Now you know.

6:16 krumholt: CalJunior, May I ask why you want to port that Java Code?

6:16 CalJunior: I would like to implement a Java API in Clojure.

6:17 I have the code of a demo test client in Java.

6:17 I am trying to port this to Clojure so I can learn how to interop with Java.

6:18 I am more than a bit out of my depth here.

6:19 krumholt: CalJunior, I am not sure porting something you don't fully understand will provide a very good learning experience.

6:19 CalJunior: You might be right.

6:22 Last try: I found the 'this' object in the ESocketClient source file: m_reader = createReader(this, new DataInputStream(

6:22 socket.getInputStream()));

6:24 raek: CalJunior: (.Class x) and (Class. x) is not the same thing

6:24 (Class. x) becomes (new Class x)

6:25 CalJunior: So I should do: (let [client (EClientSocket. this)])

6:25 ?

6:26 Same exception, I tried: (let [client (EClientSocket. [])]). Now I get java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to com.ib.client.AnyWrapper (NO_SOURCE_FILE:0)

6:26 krumholt: no you must replace this with an object you are refering to. In java "this" refers to the class itself

6:26 CalJunior: aha

6:27 krumholt: you might wanna read http://java.sun.com/docs/books/tutorial/java/javaOO/thiskey.html

6:27 CalJunior: thanks krumholt.

6:27 and raek

6:27 and rfgpfeiffer

6:28 raek: CalJunior: (let [client (EclientSocket.)])

6:28 CalJunior: raek: with that I get: java.lang.IllegalArgumentException: Unable to resolve classname: EclientSocket (NO_SOURCE_FILE:23)

6:29 raek: oops, EClientSocket

6:29 capial C

6:29 *capital

6:29 CalJunior: oops. now I get: java.lang.IllegalArgumentException: No matching ctor found for class com.ib.client.EClientSocket (NO_SOURCE_FILE:24)

6:29 raek: what arguments does the constructor of EClientSocket take?

6:30 CalJunior: give me a second ...

6:31 public EClientSocket( AnyWrapper anyWrapper) {

6:31 m_anyWrapper = anyWrapper;

6:31 }

6:31 This is AnyWrapper

6:31 public interface AnyWrapper {

6:31 void error( Exception e);

6:31 void error( String str);

6:31 void error(int id, int errorCode, String errorMsg);

6:31 void connectionClosed();

6:31 }

6:31 hope this helps

6:33 the 'public EClientSocket(…' method (?) is part of the EClientSocket class: public class EClientSocket {

6:33 if that makes any sense.

6:35 krumholt: it means it is a constructor not a method

6:35 CalJunior: ok. thanks.

6:36 cemerick: anyone here use clojure.contrib.logging? I'm getting logger names like "clojure.contrib.logging$fn__2450$impl_write_BANG___245", as warned in the ns docs.

6:36 raek: (let [wrapper (proxy [AnyWrapper] [] (error [e] ...) (error [id error-code error-msg] ...) (connectionClosed [] ...))]

6:37 or something similar

6:37 pass that to the constructor

6:37 CalJunior: ok, thanks raek.

6:38 raek: you have to create something that implements the AnyWrapper interface

6:38 proxy does that

6:38 CalJunior: OK, it is becoming a lot more clear now. I think I will have to chew on this for a while. Will get back if I make progress.

6:38 raek: (let [client (EClientSocket. wrapper)] ...)

6:39 CalJunior: Couldn't I just call (proxy [AnyWrapper]) as an argument to ESocketClient.?

6:40 Guess I can't: java.lang.Exception: Can't take value of a macro: #'clojure.core/proxy (NO_SOURCE_FILE:29)

6:41 raek: ,(doc proxy)

6:41 clojurebot: "([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, must be first. If not provid

6:41 raek: you have to provide an implementation of the methods specified in the interface

6:42 CalJunior: ok, that's clear. thanks again.

6:42 So this means I would need to port (parts of) the API libary to Clojure as well.

6:43 Was hoping to avoid this.

6:43 AnyWrapper.java is part of this API.

6:44 Chousuke: you should be able to call proxy directly to get an instance :/

6:44 I don't see why (Foo. (proxy ...)) wouldn't work. Maybe there's something wrong with your form?

6:45 CalJunior: I've done (Foo. [proxy …])

6:46 Chousuke: well, no wonder :)

6:46 CalJunior: (let [client (EClientSocket. (proxy AnyWrapper))])

6:47 yason: CalJunior: I've never needed anything but a proxy for java class/interface interop.

6:47 CalJunior: that's good news yason.

6:47 Chousuke: CalJunior: the interfaces need to be in a vector, but an empty proxy like that doesn't make sense.

6:47 raek: CalJunior: you'll have to give some instance of AnyWrapper to the constructor

6:48 what did you pass in your java code?

6:48 Chousuke: CalJunior: why would you proxy AnyWrapper if you're not defining any of its methods?

6:50 CalJunior: The ESocketClient class contains the ESocketClient constructor (AFAI understand it). public EClientSocket( AnyWrapper anyWrapper) {

6:50 m_anyWrapper = anyWrapper;

6:50 The constructor takes AnyWrapper as its argument.

6:51 raek: to use that class, either in java or in clojure, you'll have to pass a AnyWrapper as an argument

6:51 so how did you implement AnyWrapper in java?

6:51 CalJunior: There is no reference to AnyWrapper in the demo client code that I am trying to port to Clojure here.

6:52 raek: can you post a link to that code?

6:52 Chousuke: maybe it's indirectly used.

6:52 CalJunior: private AnyWrapper m_anyWrapper; // msg handler

6:52 Chousuke: ie. the demo code inherits/implements something that implements/extends AnyWrapper

6:53 CalJunior: public EClientSocket( AnyWrapper anyWrapper) {

6:53 m_anyWrapper = anyWrapper;

6:53 }

6:53

6:53 Chousuke: that's not the interesting code

6:53 CalJunior: Chousuke: exactly

6:53 oh

6:53 Chousuke: is there no place where the EClientSocket constructor gets called?

6:54 but I suppose you'll want to proxy AnyWrapper and implement its methods in your clojure code.

6:55 that'd be similar to creating a class and having it extend AnyWrapper in Java

6:55 CalJunior: Chousuke: yes: that's the line of java I am trying to port. EClientSocket client = new EClientSocket(this);

6:55 Chousuke: ah. so the class you're reading implements AnyWrapper

6:55 CalJunior: Yes

6:56 If you want/like to have a look, the code is all public. So you can see the bigger picture. I realise I am asking a lot.

6:57 Chousuke: yeah, then you'll want to use proxy so that (defn make-my-whatever [arg arg2] (proxy [AnyWrapper] [] (anywrapperMethod1 [foo bar] (dostuff)) (anywrapperMethod2 [foo bar] (domorestuff arg1 arg2))))

6:57 then (ESocketClient. (make-my-whatever foo bar))

6:58 the make-* is a factory function for creating instances of your proxy, and the proxy closes over the arguments to the factory function, so you can use them in the method implementation if you need to

6:59 CalJunior: ,(doc make-)

6:59 clojurebot: It's greek to me.

6:59 Chousuke: I just defined it :)

6:59 CalJunior: ,(doc make-*)

6:59 clojurebot: Excuse me?

6:59 Chousuke: it's make-my-whatever. it's not a core function :P

6:59 it's just a whatever name

7:00 CalJunior: Oh, sorry. Thought it was a Clojure expression.

7:00 Chousuke: and I was too lazy to type so I abbreviated it to make* :P

7:00 +-

7:00 CalJunior: Clear

7:00 Chousuke: didn't save me much typing in the end though :D

7:01 (moral of the story: don't abbreviate out of laziness)

7:01 CalJunior: Would you want to have a look at the code I'm porting?

7:01 Chousuke: I don't have the time right now. Class starts in 15 minutes.

7:01 krumholt_: what time is it?

7:02 Chousuke: here? 14:02 :P

7:02 CalJunior: OK, thanks for the advice Chousuke. Very helpful.

7:02 krumholt_: i am always forgetting differnet time zones

7:02 CalJunior: also krumholt and raek.

7:03 I think I have my work cut out for me for the afternoon. :-)

7:29 AWizzArd: Strange, my clojure-contrib does not compile to .class files. I do ant -Dclojure.jar=../clojure/clojure.jar and this produces the clojure-contrib.jar, and that jar contains many .clj files. When I give a wrong part to the clojure.jar I get warning. Is there something else I need to do to aot-compile?

7:29 I am using the NEW branch of Clojure.

7:33 It contains *some* .class files, but by far not everything. The clojure-contrib.jar has a size of 567 kb.

7:34 Anyone else here who has a fresh checkout of Clojures NEW branch and master of Contrib?

7:37 gerry`: my clojure-contrib.jar is 3252kb

7:38 AWizzArd: Yes, sounds realistic, as it should be.

7:40 gerry`: i have setup clojure-new and clojure-contrib-new dirs

7:40 new branch use the two dirs

7:41 last compile was after deftype case are out

7:42 it worked

7:42 _ato: AWizzArd: sure you're not looking at the slim jar?

7:43 gerry`: what's wrong with slim.jar?

7:43 AWizzArd: _ato: yes, I am sure. I also have the slim, and that file is even smaller (as expected).

7:43 _ato: ah wait, new branch, I didn't see that

7:43 AWizzArd: I am inspecting the build file of Contrib.

7:44 The clojure.jar file looks as expected, that's fine.

7:44 gerry`: clojure-contrib-slim.jar is 284kb on my box

7:45 _ato: ah yes

7:45 I get the same with HEAD of new branch

7:45 guess (compile) is broken

7:46 AWizzArd: So, _ato, I interpret from what you said that you also get a smallish clojure-contrib.jar when you give the path to NEW clojure.jar during ant'ing it?!

7:46 _ato: no wait

7:46 I'm being stupid

7:46 had the path wrong

7:47 no I get a full 3.3MB clojure-contrib.jar

7:47 AWizzArd: did you ant clean ?

7:48 AWizzArd: yes, I did a clean

7:49 It says it compiles: pprint.ColumnWriter pprint.PrettyWriter fnmap.PersistentFnMap condition.Condition jmx.Bean

7:49 in compile_classes

7:49 _ato: then there should be a seperate compile_clojure task

7:50 which takes a while

7:50 it doesn't print out the name of everything it compiles

7:50 just says: [echo] Locating namespaces to compile ...

7:50 then: [echo] Compiling Clojure namespaces ...

7:50 AWizzArd: yes

7:50 but this guy seems to be doing nothing for me

7:51 _ato: weird

7:52 AWizzArd: Are you on Windows XP?

7:54 _ato: Ubuntu x86 with Sun Java 6 update 16

7:55 AWizzArd: XP x86, also with that JDK

7:56 It‘s this compile_clojure step which does not compile anything for me.

8:00 gerry`: i'm update new branch now

8:02 _ato: AWizzArd: you could try compiling manually. try something like: java -cp /path/to/clojure.jar:clojure-contrib/src:clojure-contrib/classes clojure.main -e "(compile 'clojure.contrib.seq-utils)"

8:03 (with paths and whatever appropriately adjusted to however you'd write that on windows)

8:03 gerry`: it worked perfectly

8:05 AWizzArd: _ato: well yes, manual compilation works.

8:06 39 .class files for seq-utils were produced.

8:06 _ato: hmm, guess it's probably an ant problem then

8:06 AWizzArd: gerry`: are you also under Windows XP?

8:06 _ato: I've got ant 1.7.1

8:06 gerry`: no,i'm using ubuntu 9.10

8:06 why use winxp?

8:07 winxp sucks :)

8:09 AWizzArd: I also use ant 1.7.1 and XP is installed at my computer for work.

8:09 _ato: ant -v -Dclojure.jar=../clojure/clojure.jar compile_clojure

8:09 ^ makes it print out all the files it finds to compile

8:13 AWizzArd: yes, but it only finds those 5 which I reported above.

8:14 very strange

8:19 gerry`: AWizzArd: delete them and reinstall

8:20 to see if it work

8:20 AWizzArd: Works fine for compiling clojure.jar

8:22 1823 kb for me (NEW branch)

8:23 gerry`: here is 1740

8:23 oops, New is 1834 right

8:24 AWizzArd: very comparable

8:29 gerry`: AWizzArd: are you using jre or jdk?

8:29 AWizzArd: I can manually add all namespaces to the compile_classes task.. that works *sigh*

8:29 jdk

8:30 gerry`: ant problem?

8:31 AWizzArd: seems so

8:31 Or at least the build file needs something to work under Windows as well.

8:38 weissj: i'm trying to write my own "primes" function that returns an inf seq. i wanted to implement it so that it uses its own earlier primes to calculate later primes. the implementation in contrib doesn't do this though, and there's a comment saying that it can't be done efficiently that way. can someone explain a) how to do it that way, even if it's slow, and b) why its not efficient? i thougght lazy seqs were great for this sort of thing

8:44 chouser: weissj: I think that comment may be referring to the fact that you'd need to store all of the previous primes somewhere anyway, so there's not much value in making it a function vs a lazy seq. But I'm not quite sure.

8:46 weissj: chouser: i was thinking that a lazy seq should cache its results so that the function that returns primes could call itself efficiently, as long as it only wanted values that had already been calculated

8:46 don't clojure lazy seqs do this?

8:47 halloway's book implies that they do - let me find the paragraph

8:47 chouser: yes, clojure lazy seqs cache their values, which the contrib primes definition takes advantage of.

8:48 weissj: chouser: what do you have to do to take advantage of the caching? it seems like my function that returns a lazy seq of primes, there's no caching between calls to the fn

8:48 AWizzArd: don't lose the head of the seq

8:48 chouser: well it has to be the same seq for it to find the cache

8:49 weissj: AWizzArd: i see - so clojure doesn't realize that my fn returns the same seq every time, i have to use literally the same seq

8:50 AWizzArd: It's important that lazy-seqs can be GCed. Imagine you map over a lazy seq that contains 100 GB of data. I have similar cases, and my program runs with constant memory needs.

8:50 chouser: which I think is what the comment before contrib primes is talking about -- it's got to hang on to the same seq object anyway, so might as well store it in a var name 'primes' rather than making a function public.

8:50 AWizzArd: weissj: there is already something for memoization, in Contrib. So, with that there would remain a pointer to the seq that you created the first time.

8:52 weissj: chouser: AWizzArd: ok, so my mistake was to call primes a fn, i could just call it a var.

8:52 AWizzArd: yes!

8:52 weissj: ok, i'll see what i can do with that. thanks!

8:53 Chousuke: storing an infinite lazy seq in a var is generally bad style though.

8:53 since it'll never be gc:d, and might grow massive :P

8:54 weissj: Chousuke: well, if you suppose that any consumer of this 'primes' var really needs to know these primes, the gc will never know when the consumer is done asking for them, so it kinda makes sense

8:55 seems like the only other choice is to recalculate the seq

8:55 AWizzArd: ,(doc if-let)

8:55 clojurebot: "([bindings then] [bindings then else & oldform]); bindings => binding-form test If test is true, evaluates then with binding-form bound to the value of test, if not, yields else"

8:55 AWizzArd: What is oldform?

8:55 ,(if-let [x 1] :a :b :c)

8:55 clojurebot: java.lang.IllegalArgumentException: if-let requires a vector for its binding

8:58 cgrand: AWizzArd: in distant times, (if-let [x y] a b) was written (if-let x y a b)

9:00 AWizzArd: i see

9:00 cgrand: are you using Windows XP?

9:02 cgrand: AWizzArd: no, why?

9:04 AWizzArd: Would be great if someone with Windows XP and ant 1.7.1 could confirm that clojure-contrib won't aot-compile everything, resulting in a smallish clojure-contrib.jar file.

9:12 rhickey: can we maybe have a without-exception macro? :)

9:12 (defmacro without-exception [& body] `(try ~@body (catch Exception _# nil)))

9:16 something like CLs ignore-errors

9:16 rhickey: AWizzArd: sounds evil

9:17 chouser: looks like the checked-exception hacks in nearly every bit of Java example code out there.

9:18 AWizzArd: Maybe this is more domain specific when writing a web app with Compojure *shrugs*

9:18 rhickey: except we don't have checked exceptions to work around in Clojure

9:19 AWizzArd: this ignore-errors is nice when working with when-let or if-let

9:19 chouser: AWizzArd: why?

9:19 oh, to get 'nil' instead of an exception. hm.

9:21 cemerick: oh, dammit, I got caught by not explicitly capturing the value of a bindable var before returning a lazy seq. :-(

9:22 AWizzArd: In Compojure for example a request could get stopped by exceptions, returning debug output to the enduser. Trying to parse json can result in an exception or lots of error checking code. It's nice when the json parser just returns nil (for my case).

9:22 _ato: it's not something you'd want to do commonly enough to justity shortening with a macro IMO

9:23 and it's bad to be in a habit of catching all exceptions rather than just the ones you want to deal with

9:26 AWizzArd: For the general case I agree.

9:26 djork: so my friend says: "so why would you use a language that no one else is taking seriously"

9:26 chouser: bait

9:26 AWizzArd: yup ;)

9:27 I'm fast outta here

9:29 krumholt_: does clojure need an installed jdk to work or is a jre enough?

9:29 chouser: krumholt_: jre is sufficient unless you want to build clojure itself.

9:29 krumholt_: chouser, ok thanks

9:30 djork: chouser: he's baiting me

9:31 chouser: djork: yes

9:31 djork: k

9:31 just didn't want people to think I was baiting the channel

9:31 AWizzArd: good

9:31 chouser: djork: did you run away? or ask who's opinion is so important he didn't question it?

9:31 djork: heh heh

9:31 chouser: djork: oh, yes, I didn't think that. You've been here enough. :-)

9:31 djork: I don't know of many people who aren't taking Clojure seriously

9:32 AWizzArd: Anyone here who worked with Contribs logging module?

9:32 aatifh: I have a hash map like {"bar" {"foobar" "foo"}} and to convert into {"foobar" "foo", "name" "bar"}

9:32 cemerick: AWizzArd: I was just looking at it now.

9:33 if one is AOT-ing code, that's when "macro-expansion-time" is, right?

9:33 chouser: I see posts from people who dismiss Clojure pretty easily, but those strike me more as matters of taste than not taking it seriously.

9:33 AWizzArd: cemerick: oh good, I had a short look yesterday and would now like to check it out.

9:33 chouser: cemerick: yes, macro expansion happens more or less during compilation (slightly before for each form)

9:34 aatifh: your input map always has only one pair?

9:35 cemerick: eh. let me try that again -- during AST-generation (slightly before for each form), all of which is before bytecode generation.

9:39 cemerick: chouser: that's what I thought.Means that one has to be careful not to AOT clojure.contrib, lest logging gets locked into a logging subsystem that isn't in the deployment environment.

9:39 aatifh: ?

9:39 cemerick: I'd be happy to be proven wrong, of course.

9:39 _ato: aatifh: where does "name" come from?

9:39 or you mean that's hardcoded?

9:39 AWizzArd: cemerick: what is clojure.contrib.logging/*impl-name* for you?

9:39 aatifh: _ato, that key has to be added

9:39 _ato: ,(into {} (map (fn [[k v]] (assoc v "name" k)) {:bar {:foobar :foo}}))

9:39 clojurebot: {"name" :bar, :foobar :foo}

9:39 _ato: ,(into {} (map (fn [[k v]] (assoc v "name" k)) {:bar {:foobar :foo}, :baz {:quox :kaboom}))

9:39 clojurebot: Unmatched delimiter: )

9:39 _ato: ,(into {} (map (fn [[k v]] (assoc v "name" k)) {:bar {:foobar :foo}, :baz {:quox :kaboom}}))

9:39 clojurebot: {"name" :baz, :foobar :foo, :quox :kaboom}

9:39 aatifh: chouser, yes

9:40 cemerick: AWizzArd: java.util.logging

9:40 AWizzArd: cemerick: for me it's "org.apache.commons.logging" and (impl-get-log "my.namespace") returns a Jdk14Logger. And I would love to know how I can set the current log level, or turn logging off completely.

9:41 cemerick: AWizzArd: setting log levels and such is totally orthogonal to c.c.logging -- for that, you need to configure the in-use logging subsystem.

9:42 aatifh: _ato, Thanks

10:00 patricius_: Hey. Very simple question: How do I make a string out of the contents of a seq? I thought that (str x) where x = ["Peter" \, "George" \, "Jack"] would yield the string "Peter,George,Jack"?

10:00 AWizzArd: (apply str your-seq)

10:01 ,(apply str ["Peter" \, "George" \, "Jack"])

10:01 clojurebot: "Peter,George,Jack"

10:01 patricius_: ahr!

10:01 thanks!

10:02 The-Kenny: (I think there should be str* for that in core, writing apply is a bit annoying sometimes)

10:03 patricius_: yeah... I just misread the definition of str

10:03 _ato: mmm perhaps better would be string/str to match vector/vec

10:04 chouser: that'd be a breaking change for str

10:04 _ato: I know

10:05 AWizzArd: in the http-agent lib (contrib) there already is a function string

10:05 _ato: it's just sad it'll get stuck as the odd one out :(

10:10 AWizzArd: cemerick: do you happen to know if all these logging libs do have ways to turn logging on/off?

10:11 cemerick: AWizzArd: log4j and java.util.logging both have roughly similar control mechanisms

10:11 The former is probably more powerful.

10:14 AWizzArd: And how do you get the logger object? Is it really (def my-logger (.getLogger (impl-get-log "my.namespace")))?

10:15 cemerick: AWizzArd: you'll have to look at c.c.logging's docs, etc. It's rolled off my stack.

10:16 AWizzArd: k

10:18 * rhickey experimenting with inline caching of (:k x) calls - same speed as (.k x) for deftypes!!

10:22 AWizzArd: rhickey: without compiling the namespace?

10:22 oh, I see

10:23 chouser: rhickey: what do you mean by inline caching?

10:25 rhickey: chouser: swapping in a class-specific stub at (:k x) call points. Basically every deftype defines stub per field. Keyword callsites can obtain these stubs and swap them in, replacing lookup with direct call

10:26 patricius_: there should be no problem in having one agent creating a promise, and sending it to another agent that at some point delivers? this is one of its usage scenarios, right?

10:26 chouser: patricius_: sounds good to me

10:27 rhickey: patricius_: just remember that dereferencing an undelivered promise blocks

10:27 chouser: rhickey: That doesn't sound like the Keyword invoke method, but instead special Compiler support (:k x) calls?

10:27 patricius_: rhickey: yes, that is exactly why I use it

10:27 :)

10:28 _ato: rhickey: ah... that's a great idea. I had been defaulting to (x :k). I should get into the habit of (:k x) instead.

10:28 rhickey: chouser: yes, a ton of compiler support, still trying to access if it's worth it - case dispatch is surprisingly very good

10:28 assess

10:28 chouser: surely would be easier with cinc

10:30 rhickey: chouser: it's done, but there are some overheads - more classes being generated, some cost when not a deftype lookup (although they still trounce any more generic lookup, e.g. struct/arraymaps)

10:34 djork: what's going on with this...?

10:34 '`[:foo :bar]

10:34 ,'`[:foo :bar]

10:34 clojurebot: (clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat (clojure.core/list :foo) (clojure.core/list :bar))))

10:34 djork: is that what [:foo :bar] translates to at runtime?

10:35 chouser: djork: :-) what were you expection?

10:35 _ato: hehe

10:35 djork: er, evaluation

10:35 _ato: we were talking about this yesterday or so

10:35 chouser: djork: that's what `[:foo :bar] compiles to

10:35 djork: gotcha

10:35 rhickey: always scary changing something so pervasively used, OTOH, getting (:field x) as fast as possible for deftypes means that independently written protocol functions have no disadvantage vs methods, i.e. not dynamic penalty

10:36 chouser: djork: that's the code template for building a vector that can have expressions inserted via ~ or spliced via ~@ at runtime.

10:36 _ato: rhickey: is this only when x is type-hinted?

10:36 djork: ok

10:36 so the reader isn't doing that translation every time?

10:36 rhickey: _ato: nothing to do with type hints

10:37 chouser: djork: yes, that's what the reader produces when you use `

10:37 djork: well yeah, when you use `

10:37 but not for every []

10:37 ` makes a template

10:37 chouser: rhickey: does it swap back to generic lookup of x stops being the type is was before?

10:38 rhickey: chouser: yes

10:38 chouser: djork: right.

10:38 _ato: ag

10:38 ah*

10:38 rhickey: chouser: and subsequent to that is never quite as fast

10:38 chouser: oh, interesting.

10:38 rhickey: I guess hotspot backs off then

10:39 chouser: heh

10:39 rhickey: well, at that point the call site *is* polymorphic

10:40 chouser: sure

10:41 rhickey: but your basic set of functions implementing a protocol for a deftype will never be

10:42 djork: ,(let [n 1000000] (do (time (dorun (take n (repeatedly #(do {:foo :bar}))))) (time (dorun (take n (repeatedly #(do `{:foo :bar})))))))

10:42 chouser: because the correct call site will be selected by protocol machinery first?

10:42 clojurebot: "Elapsed time: 1024.347 msecs" "Elapsed time: 4017.524 msecs"

10:43 rhickey: its only in non-polymorphic situations that you could expect .field-like perf, after all .field is never polymorphic

10:43 chouser: there will be one fault, swapping in the initial thunk, but after that it will never change

10:44 patricius_: perhaps I am a moron, but let's say that an agent action A creates a promise P1 and sends it off to an agent B. A then blocks until P1 is delivered, which B is responsible for. When B delivers, it sets the value of the promise to another promise P2 that it itself blocks on (by deref'ing). A then sees the new promise, performs some work and then delivers P2, which lets B continue. Is this a sure deadlock? I'm sure there is a more clever way to solv

10:44 problem, so foregive me.

10:46 djork: hah "perhaps I am a moron, but ... <highly intelligent discussion of advanced computing follows>"

10:46 ericthorsen: e72291196T

10:46 patricius_: :P

10:46 ericthorsen: sorry...wrong window

10:48 chouser: patricius_: I'm trying to follow, but that doesn't sound like a deadlock to me.

10:49 patricius_: chouser: here's what I am trying to do (follows)

10:51 cgrand: patricius_: is A awaiting P1 to be delivered in the same action where it sent P1 to B?

10:52 rhickey: patricius_: one thing is true of promise/deliver (and dataflow vars in general) - if you've got a deadlock it will always occur

10:53 djork: well that's actually quite nice :)

10:53 nothing worse than a non-deterministic deadlock

10:53 fogus_: That seems the flavor I've always experienced.

10:54 patricius_: I am creating a simulation of a system where you have a bunch of "processes" that each need to access certain cylinders on a disk. It is a requirement that when a process requests access to a cylinder, it blocks until it gets access. But when it *has* been given access, it is up to the process to release it again, before any other processes can get access to the disk and its cylinders. So a process blocks on a request promise, and when a "disk sch

10:54 agent gets to that request, it delivers the promise, effectively giving the process access to the cylinder.

10:54 *sigh* horrible explanation

10:55 in any case, clojure probably doesn't lend itself well to such a scenario - but I'm investigating concurrent languages on a single, common, concurrent problem

10:56 cgrand: yes, your understanding is correct

10:57 chouser: patricius_: if each process will only ever have access to one cylinder at a time, is this perhaps a good scenario for a simple lock per cylinder?

10:57 patricius_: chouser: hmm... maybe

11:02 for some reason, i can get the processes to block and unblock correctly, if I deliver the first promise directly from the REPL thread, but not when I get an agent to deliver the first promise

11:02 chouser: patricius_: you're using send-off not send for these agents, right?

11:02 patricius_: yes

11:03 cgrand: patricius_: actions dispatched to other agents are held until the current action is done so (do (send B some-action P1) @P1) blocks

11:03 patricius_: cgrand: ahhh.... that seems to explain it

11:03 rhickey: ,(doc release-pending-sends)

11:03 clojurebot: "([]); Normally, actions sent directly or indirectly during another action are held until the action completes (changes the agent's state). This function can be used to dispatch any pending sent actions immediately. This has no impact on actions sent during a transaction, which are still held until commit. If no action is occurring, does nothing. Returns the number of actions dispatched."

11:06 patricius_: rhickey: you're such a genius :)

11:06 rhickey: come to my university and give a talk about clojure - there are some people here that will wet their pants in excitement over clojure

11:09 fogus_: Sounds like an offer that can't be refused!

11:15 djork: wet pants are not to be missed

11:19 CalJunior: question on "new" vs. "old" branch: is 'this-name?' functionality in reify (like Java's 'this' for method bodies to refer to the current instance) also available in proxy?

11:24 chouser: within a proxy form, the symbol this refers to the instance that proxy returns

11:26 rathore: ,(.getString String)

11:26 clojurebot: java.lang.IllegalArgumentException: No matching field found: getString for class java.lang.Class

11:26 rathore: ,(.getName String)

11:26 clojurebot: "java.lang.String"

11:26 rathore: ,(.parseLong Long "12312232")

11:26 clojurebot: java.lang.IllegalArgumentException: No matching method found: parseLong for class java.lang.Class

11:30 _ato: ,(Long/parseLong "12345")

11:30 clojurebot: 12345

11:31 rathore: _ato: yes, I'm aware of that form

11:31 _ato: i'm looking at http://clojure.org/java_interop

11:31 chouser: (. Long parseLong "12312232")

11:31 ,(. Long parseLong "12312232")

11:31 clojurebot: 12312232

11:32 rathore: chouser: under member-access, there's a general form shown as - (.instanceMember Classname args*)

11:32 chouser: i know that the dot operator works as u described...

11:32 chouser: but whats this form in the documentation?

11:32 chouser: (.instanceMember Classname args*)

11:32 chouser: instance not static member

11:33 rathore: for a Classname?

11:33 what would be an example?

11:33 _ato: (. (identity Classname) instanceMember args*)

11:33 hmm

11:33 chouser: ,(.pow 2M 2)

11:33 clojurebot: 4M

11:33 chouser: oh!

11:33 Classname

11:33 hm.

11:34 ,(.isAssignableFrom Integer Float)

11:34 _ato: it is somewhat misleading

11:34 clojurebot: false

11:35 _ato: it implies it's the instance of the class rather than the instance of the Class

11:35 chouser: _ato: that's ok. rathore's book will clear it up.

11:36 rathore: chouser: funny

11:40 _ato: can you elaborate on that statement?

11:41 CalJunior: chouser: thanks

11:42 _ato: I just mean the doc is misleading. (.instanceMember Long) is like Long.class.instanceMember() in java, not Long.instanceMember()

11:42 it's not wrong, it uses an uppercasee "Class" meaning instance of java.lang.Class for that type

11:44 rathore: _ato: got you, thanks

11:45 _ato: ,(.getMethods Long)

11:45 clojurebot: #<Method[] [Ljava.lang.reflect.Method;@13cc05f>

11:45 _ato: ,(seq (.getMethods Long))

11:45 clojurebot: (#<Method public int java.lang.Long.hashCode()> #<Method public static long java.lang.Long.reverseBytes(long)> #<Method public int java.lang.Long.compareTo(java.lang.Object)> #<Method public int java.lang.Long.compareTo(java.lang.Long)> #<Method public static java.lang.Long java.lang.Long.getLong(java.lang.String,java.lang.Long)> #<Method public static java.lang.Long java.lang.Long.getLong(java.lang.String,long)> #<Method

11:55 Jomyoot: Any good new IDE for clojure?

11:56 The-Kenny: Jomyoot: Emacs + slime + swank-clojure :)

11:56 Jomyoot: not that again :(

11:56 jasapp: doesn't get any better

11:57 ericthorsen: Jomyoot: We are using and developing actively the Enclojure library for this which has a Netbeans plugin www.enclojure.org

11:57 Jomyoot: I use IDEA

11:57 So unfortunate that La Clojure is not up to that level

11:59 ericthorsen: Jomyoot: I'm playing with putting the Enclojure repls into Jetbrains clojure plugin...not sure if that is La Clojure?

11:59 Jomyoot: from here - http://git.jetbrains.org/?p=idea/clojure-plugin.git;a=summary

11:59 fanatico: ericthorsen: how integrated is Enclojure with the REPL. For example, do you have macroexpand support?

12:00 ericthorsen: fanatico: Not sure what you mean...you can call macroexpand on a form

12:01 Jomyoot: Is Compojure still THE web development tool?

12:01 Anything new than that?

12:01 Conjure?

12:02 fanatico: ericthorsen: can I expand inline? Or do I have to jump down to the REPL and reload the file?

12:03 ericthorsen: fanatico: There are hotkeys for loading files, expressions, etc. There is no hotkey for macroexpand (that is in interesting idea). Is that what you are looking for?

12:05 _ato: ericthorsen: with emacs/SLIME there's a hotkey for showing the macro expansion in a temporary buffer, as well as replacing the form the cursor is over with it's expansion. I guess fanatico is referring to those

12:06 ericthorsen: _ato: I was thinking about being able to do this from the editor...it sounds similar. We do not support that yet.

12:07 cemerick: I try to keep my macro-writing down to a dull roar. If ericthorsen is taking a tally, better Java-oriented code completion is more common thing to optimize on. :-P

12:08 chouser: macroexpansion can be useful for understanding builtin macros as well

12:08 _ato: hehe. Both are pretty handy for debugging macros, eg you can type something out, macroexpand it and then edit the expansion and then eval to see if you fix worked, then go back to your macro and make the fix there

12:08 chouser: plus Yegge asked for it

12:08 cemerick: Yegge talked about clojure?

12:08 * cemerick *faints* ;-)

12:09 chouser: no

12:09 _ato: aww

12:09 chouser: Yegge talked about wanting an editor that has a macroexpand keystroke. I don't know why he thinks emacs doesn't have that.

12:11 cemerick: hrmph. I don't use emacs, and I knew it had that. :-/

12:11 _ato: maybe (e)lisp-mode doesn't have it, I don't do enough elisp to have noticed it missing

12:12 chouser: http://steve-yegge.blogspot.com/2006/04/lisp-is-not-acceptable-lisp.html

12:12 tknudsen: hey peeps. Anyone making constructive use of a web framework implemented in clojure?

12:12 The-Kenny: I need a cheatsheet for slime-commands.. I always forget the shortcuts for them.

12:12 chouser: "If your editor knows all about macros, then you should be able to click to see the expansion, and click again to see its sub-expansions, all the way down to the primitive functions. Some editors can do this, but none of them (that I'm aware of) handle macros as cleanly or seamlessly as they do normal functions."

12:13 m0smith: hi?

12:13 _ato: The-Kenny: there's several, just google: emacs cheat sheet

12:13 tknudsen: m0smith, hello

12:13 fanatico: He wrote that ~10,000 LOC js2-mode, so hopefully he'd know.

12:13 m0smith: I have been looking at clojure and love it

12:13 There is something that is bugging me though

12:13 tknudsen: what's that?

12:13 The-Kenny: _ato: I mean a small one.. I have a big one here, but I never find the command I'm searching for.

12:14 s/small/compact/

12:14 m0smith: I want to convert a self-referential class to clojure

12:14 but I can't seem to figure it out

12:14 emit: is there a way for me to break up a long string in clojure without explicitly concat'ing fragments? like using \ in makefiles or just " " " "

12:14 AWizzArd: cemerick: this logging module in Contrib seems to be very uninteresting. It will select by random a logging facility that happens to be in the CP.

12:14 fanatico: emit: """

12:15 tknudsen: m0, how is self-referential different than private class? elementary question, perhaps...

12:15 cemerick: AWizzArd: hardly at random -- there is a defined order.

12:15 emit: thanks

12:15 AWizzArd: cemerick: the one it chose for me is not able to log :trace and :debug levels.

12:15 chouser: emit: strings can wrap across multiple lines, but the newline will be included

12:15 emit: oh ok that should be fine as well then. just an sql query

12:15 _ato: fanatico: clojure doesn't have """ does it?

12:15 AWizzArd: cemerick: yes, first commons - but commons supports 7, and commons will decide which it wants to use. In my case a very lame logger.

12:15 tknudsen: cascade or compojure? Anyone making constructive use of a web framework implemented in clojure?

12:15 fanatico: _ato: oops, my mistake.

12:15 _ato: fanatico: that's just the same as "" "

12:15 AWizzArd: Now you have to hardwire your code to exactly that logger, very stupid.

12:16 m0smith: I am looking for my example

12:16 cemerick: AWizzArd: what logger are you getting that doesn't support trace and debug?

12:17 AWizzArd: cemerick: http://commons.apache.org/logging/apidocs/org/apache/commons/logging/impl/Jdk14Logger.html

12:18 Yes yes, it lists those methods. But when I call .trace or .debug on my logger then nothing happens.

12:18 And the way how I can set the log level is completely different from how java.util.logging.Logger

12:18 is doing it.

12:19 cemerick: AWizzArd: well, I can't speak to what commons logging is doing. But c.c.logging isn't doing anything particularly special or fancy...I very much doubt it's the one swallowing your logging msgs.

12:19 m0smith: for some reason browser is not working

12:20 AWizzArd: It seems the Jdk14Logger only supports four levels.

12:20 cemerick: I do think it would be very reasonable for commons-logging to come *last* in the resolution order, rather than first.

12:20 AWizzArd: yes

12:20 m0smith: Imagine a Person that referson to mother, father and children, all of which are also Person instances

12:20 refers

12:20 cemerick: I keep commons logging far, far away from our new projects. PDFTextStream v2 bundles it, and it's been a constant source of frustration.

12:21 m0smith: In Java that is a simple construct, but what about clojure?

12:21 AWizzArd: cemerick: the problem is that I have it in my CP, cause I am using htmlunit for example which has it as a dependency *sigh*

12:21 _ato: even simpler because it's dynamically typed?

12:21 or are you talking about gen-class or something?

12:22 cemerick: AWizzArd: I'd absolutely +1 a patch to change the resolution order :-)

12:22 (not that that means a damn thing, though)

12:22 chouser: m0smith: are you trying to create a Java class or just represent the same functionality in a more Clojure-oriented way?

12:22 AWizzArd: cemerick: do you know if the Eclipse Public License lets me take Contribs logging lib, change it, and close source the changed code in my code base with my own license?

12:22 m0smith: represent the same sort of data structure in a more clojure/funtional way. The java class is trivial

12:23 _ato: m0smith: {:type :person, :name "Bob", :family [{:type :mother, :name "Jody"}]} ?

12:23 cemerick: AWizzArd: You can certainly use contrib in commercial projects without impacting the license your code is distributed under, but you can't change contrib's license itself.

12:24 or, that's my understanding. IANAL, and all that.

12:24 _ato: or you mean self-referentia as in a cycle?

12:24 so Jody would also have a pointer to Bob

12:24 m0smith: How do I then get Bob as Jody's child?

12:24 _ato: you can't with pure immutable data

12:25 either use refs

12:25 or use keys

12:25 like

12:25 chouser: one way is to put all the people in a map indexed by unique id or name or something, then the outbound links can have those uuids or names as their values.

12:25 _ato: {:type :person, :id :bob, :name "Bob", :family [:jody :phillip]}

12:25 this is also quite nice as it's easy to read and write

12:26 m0smith: so then there is a list that I look through to get :Jody?

12:27 chouser: a map, just look it up.

12:27 _ato: as in: {:bob {:type :person, :id :bob, :name "Bob", :family [:jody :phillip]}, :jody {:type :mother ...}}

12:27 chouser: {:bob [:jody :phillip], :jody [:bob :phillip] ...}

12:28 m0smith: ok that makes sense

12:28 _ato: ah yep, that's nicer

12:30 m0smith: Different but related question: Can we build a binary tree in clojure?

12:31 _ato: m0smith: as in sorted-map?

12:31 a binary search tree

12:31 or just a binary tree

12:31 chouser: sorted-maps are a binary tree, but you could build your own with vectors as nodes for example.

12:31 m0smith: just and arbitrary tree

12:31 chouser: [[[1 2] [3 4]] [[5 6] [7 8]]]

12:32 m0smith: ok

12:32 thanks for the help. I was trying to make it much harder

12:32 chouser: more efficient ways of doing this are coming. :-)

12:32 m0smith: I have been programming emacs for a while

12:40 ozzilee: I've got a question about bindings. Is there a way to bind something for an entire module? The json library in contrib will return keys as keywords if *json-keyword-keys* is true, but that means I have to either wrap every call in a (binding ...), or create a wrapper function around the function in contrib.

12:40 chouser: m0smith: fwiw, a tree of vectors like that can be navigated using clojure.zip, which can allow you to walk up, down, across sibilings, and make "modifications" as needed

12:44 cemerick: ozzilee: you can manually set a root binding on the var in question, but I'd go with a wrapper fn.

12:44 _ato: (defn read-jason [& args] (binding [*json-keyword-keys* true] (apply clojure.contrib.json.read/read-json args)))

12:44 cemerick: to answer your question directly though, no, I don't think so.

12:44 _ato: with (require 'clojure.contrib.json.read) instead of (use)

12:47 ozzilee: Hrm. Okay, that works, I guess. Is there a better way to do this sort of thing. I'm writing a couchdb library, and I want to be able to set the host and database name in one place instead of passing it to each function call. I could use a connection object and pass that every time, but I'd like to be able to just say, "In this module, the database name is foo".

12:49 cemerick: ozzilee: that's what bindings are for. You *could* set up a couple of atoms for people to set their db properties in, but that will fall over pretty quickly.

12:50 _ato: ozzilee: note that bindings are dynamic not lexical, so if you do (binding [db "somedb"] ... ) in your main function

12:50 it'll apply to everything in the program in the main thread

12:50 unforunately there's not yet a good way to make them propagate across threads

12:50 ozzilee: cemerick: Yeah, I've been using atoms, but that means the properties are set globally. Not really what I want.

12:51 _ato: Hrm, yeah, that's something to think about.

12:52 cemerick: fogus_: http://muckandbrass.com/web/display/~cemerick/2009/11/03/Be+mindful+of+Clojure%27s+binding

12:52 feedback welcome from everyone, of course

12:52 ozzilee: cemerick: So would I be better off to just use a connection object and pass it to every call? I don't want to write wrapper functions in every module that uses the couchdb library.

12:52 technomancy: wasn't clojure's artifactId going to be changed to just "clojure"?

12:52 rather than "clojure-lang"?

12:53 cemerick: ozzilee: using binding is far more idiomatic

12:54 you can provide a with-couch macro that takes db info, that makes it a little neater so people don't have to remember the name of your library's vars

12:59 lisppaste8: ozzilee pasted "bindings" at http://paste.lisp.org/display/89736

13:00 cemerick: #2 gets my vote by a country mile.

13:00 ozzilee: cemerick: I'm not sure I'm clear on exactly what you mean, is that paste pretty much it?

13:01 cemerick: Okay, that's what I thought, that's not going to use bindings though, right?

13:01 Chousuke: you can even combine #2 and #1 if you have a default argument for the connection that is some bindable global var.

13:01 requires an arity overload though

13:01 cemerick: yeah, #2 is about as straightforward as it gets. You could make get and put support using a connection object for callers that prefer that, too.

13:01 ozzilee: no, #2 does use binding

13:01 you need to write a macro that does the binding.

13:03 ozzilee: cemerick: I don't see why. couch/get would just be a function that does an http GET with the provided connection details. couch/make-connection would return a hashmap of the connection info.

13:04 _ato: cemerick is counting from 1 not 0 :p

13:04 cemerick: hah

13:04 _ato: make-connection is #3

13:04 technomancy: ozzilee: have you seen http://github.com/danlarkin/clojure-couchdb ?

13:05 lisppaste8: ozzilee annotated #89736 "untitled" at http://paste.lisp.org/display/89736#1

13:06 ozzilee: Sorry, the top part was just to clarify that host and db were just strings.

13:06 technomancy: No, I hadn't, thanks.

13:07 _ato: hehe :)

13:07 cemerick: ozzilee: you can have #1 and #2 if you'd like, but if you only want either/or, #1 is the way to go.

13:07 ozzilee: cemerick: What's the advantage of that versus just passing the info in? It's awful verbose.

13:08 cemerick: Granted, less verbose if there's multiple calls in a single scope.

13:09 cemerick: only offering #2 means that callers have to have a connection object sitting around, or create one on every action.

13:10 danlarkin: but when a connection is just a string that is not expensive :)

13:10 _ato: hmm, couchdb is stateless isn't it?

13:10 it's over http

13:10 The-Kenny: _ato: Yes.

13:10 cemerick: danlarkin: you're not saying we should be hard-coding db strings, right? ;-)

13:11 danlarkin: *gasp*!

13:11 no, but it could certainly go in a config file or something like that

13:12 _ato: ozzilee: I was thinking the usage would be like this: http://gist.github.com/225294

13:12 but as it's stateless, there's not much point

13:12 The-Kenny: http://github.com/kunley/clojure-couchdb :)

13:13 ozzilee: _ato: Yeah, it's a web app, so there will be a bunch of disconnected functions instead of a single entry point.

13:15 Am I crazy to think that there could/should be some kind of module-scoped binding? Maybe that's not possible or desirable.

13:16 cemerick: ozzilee: the question is, how is it different from normal bindings, and what would the threading semantics be?

13:16 You can't just assume that your lib has only one caller.

13:16 danlarkin: <3 non-reentrant code!

13:16 ozzilee: cemerick: Right, that's where atoms fall down, since there are multiple callers.

13:17 danlarkin: Does clojure-couchdb use your clojure-json?

13:18 _ato: hmmm... you could probably basically achieve it by having a macro that (use)s the library and automatically generates wrappers for all functions

13:19 ozzilee: _ato: Yeah, that sounds like it would work.

13:19 _ato: actually

13:19 even better

13:19 would be to custom name space it

13:19 so

13:20 danlarkin: ozzilee: it does not, it uses contrib's json

13:20 _ato: (require-with-bindings 'couchdb :as 'shop-db :host "whatever" ...)

13:20 then if you wanted to use another db

13:20 you could add

13:21 (require-with-bindings 'couchdb :as 'blog-db :host "something else" ...)

13:21 cemerick: _ato: it hurts just thinking of that, but maybe this is a matter of opinion.

13:21 ozzilee: danlarkin: Okay. Now to decide if it's worth rewriting stuff so I don't have to maintain my own library :-)

13:21 danlarkin: how is this different from bindings?

13:21 _ato: and use (shop-db/put ...), (blog-db/get ...)

13:21 danlarkin: it's module-local and propagates threads

13:21 danlarkin: ozzilee: fork it and patch 'til it's good enough :)

13:22 cemerick: danlarkin: it'd use your ns' vars to hold implicit bindings, I think.

13:22 danlarkin: le gross

13:22 ozzilee: danlarkin: Oh I'm sure it's good enough, probably better than what I've got.

13:22 cemerick: I agree.

13:22 _ato: chouser's clojure-jna does something similar

13:23 danlarkin: ozzilee: there's also http://github.com/tashafa/clutch

13:23 The-Kenny: danlarkin: Is there a reason for not-merging the view-*-functions added by kunley to your repository of clojure-couchdb?

13:24 danlarkin: The-Kenny: I started to a couple weeks ago but got distracted and have been too busy since then

13:24 ozzilee: danlarkin: Ah, a view server too. Nice.

13:24 The-Kenny: danlarkin: Oh okay.

13:27 ozzilee: I'm just trying to avoid having to pass the host and db a dozen different times in the module. Sounds like the only practical way around it is to write wrapper functions, or maybe make a macro that writes them for me.

13:28 djork: so what are the implications of using Clojure in game development?

13:28 LWJGL + Clojure = ...?

13:28 cemerick: ozzilee: seriously, bindings are *the* way to avoid having to thread arguments through various levels of fns.

13:29 The-Kenny: ozzilee: the host is already bound to a variable and isn't an argument. You can easily do the same for the database with few modifications.

13:29 djork: what about distribution?

13:29 ozzilee: cemerick: Right, it just means I have to wrap every single call with (binding ..). It's more verbose, unless I'm terribly mistaken.

13:29 _ato: djork: java web start or just one big jar that you can double click to run?

13:30 The-Kenny: djork: Distributing clojure is easy, just create a .jar and add clojure.jar to the classpath.

13:30 djork: yeah I'm more concerned with the ugly details of running it on different platforms

13:30 web start is pretty funky for most users

13:30 cemerick: ozzilee: if the caller knows what he's doing, no more than one binding form is ever necessary

13:31 djork: I can assume Java on Macs, but not on Windows or Linux.

13:31 cemerick: (assuming a single-threaded environment)

13:31 ozzilee: cemerick: Then I'm missing something. Let me paste up an example.

13:31 djork: the minimal JRE isn't too big, is it?

13:32 _ato: 8 mb or so I think

13:32 17M jre-1_5_0_21-linux-i586.bin

13:33 maybe a bit bigger than I remembered :p

13:33 djork: not too big for a larger project

13:33 as a percentage of the assets et al

13:33 _ato: yeah, if you've got 200mb of art or whatever

13:33 for smaller stuff you could just have a graphical installer that checks if they've got it and downloads it for them if they haven't

13:34 djork: yeah

13:34 so now how about architecture?

13:34 cemerick: ozzilee: I'm think here of with-db in clutch, for example

13:34 djork: I am imagining many refs being slung about

13:35 maybe I need to re-read some of the clojure presentations

13:35 I'm concerned with memory usage when the world state is kept in maps or vectors that might be quite large

13:35 doing lots of disj conj assoc operations, etc.

13:36 danlarkin: djork: prototype something and measure it

13:36 _ato: I've been fiddling with a little RPG type thing in Clojure (2d tiles, although they can be stacked so the game actually has 3d world coordinates)

13:36 djork: yeah, really that's the best way to go I guess

13:37 lisppaste8: ozzilee pasted "bindings 2" at http://paste.lisp.org/display/89737

13:37 _ato: at the moment the tile map is a sorted-map where keys are coordinates and values are game objects (which are wrapped in refs)

13:37 so you can update game objects independently

13:38 ozzilee: cemerick: I don't understand how I could do something like that with only one binding form.

13:38 _ato: but only one thing can change the map at a time

13:38 ants.clj also has an interesting way of doing it

13:39 cemerick: ozzilee: you wouldn't, but I think it's save to assume that callers aren't going to be setting db info on every db access -- the binding would be set up in the top level of a servlet handler, a JMS receive, etc.

13:39 Guest77613: hi there. What would be the most idiomatic way to walk a directory and grab the files names and paths ?

13:40 recursively that is

13:40 cemerick: e.g. not (binding [...] (save ..)) (binding [...] (load ...)), (binding [...] (save ...) (load ...))

13:40 djork: _ato: sounds pretty reasonable

13:41 The-Kenny: Guest77613: function(doc,req) {

13:41 return {

13:41 body: \"<div>42</div>\"

13:41 };

13:41 }

13:41 user=> ; The latest field is the id. It's left blank in this example

13:41 user=> (show-get "some-db" "test" "forty-two" "")

13:41 user=> ("<div>42</div>")

13:41 argh sorry.

13:41 damn c&p

13:41 Guest77613: :D

13:41 The-Kenny: Guest77613: (file-seq (java.io.File directory-string))

13:42 s/File/File./

13:42 Guest77613: thanks, i thought it looked more like javascript too :)

13:42 why couldn't i find that in the docs :/ i must be very tired

13:42 alexyk: is clojure dynamically typed, i.e. closer to Ruby than to Scala?

13:42 _ato: alexyk: yes!

13:43 :)

13:43 alexyk: so how are you supposed to do big projects?

13:43 can I supply type annotations throughout?

13:43 ozzilee: cemerick: I don't follow. Are you saying I should be calling the (binding ...) in the client to the module I posted?

13:43 alexyk: can I insist they're enforced?

13:43 _ato: no

13:43 alexyk: :(

13:43 _ato: you can specify them

13:44 but they're for a performance optimisation

13:44 not for bondage and discipline :p

13:44 cemerick: alexyk: clojure is strongly typed -- any type conflicts will result in an error

13:44 alexyk: cemerick: now I'm confused... strongly typed dynamic??

13:44 djork: you can be strong and dynamic

13:44 like a CEO

13:45 no

13:45 _ato: haha

13:45 alexyk: so what's dynamic here?

13:45 cemerick: alexyk: there are 2 axes: strong vs. weak, dynamic vs. static

13:45 djork: like Spiderman

13:45 Guest77613: _ato : If i'm not wrong though , type hints will throw exceptions if you don't use the right types no ?

13:45 alexyk: what's an example where something is strongly typed but dynamic, hence different from Java/Scala?

13:46 _ato: dynamic means you don't specify types when eg declaring a local

13:46 cemerick: alexyk: that is clojure

13:46 _ato: so like: (let [x 5] ... )

13:46 cemerick: perl is weakly typed and dynamic

13:46 java is strongly typed and (sorta) static

13:46 alexyk: _ato: Scala infers the type. so you don't have to declare it either

13:46 cemerick: as is scale

13:46 scala*

13:46 alexyk: but it always knows what it is

13:47 the question is, does clojure know always what a type of x is?

13:47 Guest77613: no

13:47 _ato: sometimes

13:47 cemerick: oh goodness

13:47 _ato: in that case yes

13:47 Guest77613: well i mean there is boxing right ?

13:47 _ato: but it doesn't *need* to know

13:47 cemerick: alexyk: yes, just like any other JVM lang, you can get the type of an object

13:47 alexyk: so say I want always to insist a parameter of a function is Int. Can I enforce that, so you won't pass strings into it?

13:48 cemerick: alexyk: No, that's the dynamic part.

13:48 _ato: alexyk: yes, by explicitly checking

13:48 but not as in java

13:48 alexyk: cemerick: _ato: make up your minds guys :)

13:48 Chousuke: they're both right :)

13:48 cemerick: I think _ato is trying to make the hard sell :-)

13:48 Chousuke: no, you can't and yes you can.

13:48 hiredman: cemerick: you can get at type information at runtime, sure

13:49 _ato: hehe

13:49 alexyk: _ato: do I have to check myself, or can I annotate and make clojure check for me?

13:49 cemerick: I don't think manual assertions are ever what someone is talking about w.r.t. type enforcement.

13:49 hiredman: but clojure does not always know the type of an object

13:49 that is what *warn-on-reflection* is about

13:49 alexyk: hiredman: you're messing around with clojure too?

13:49 :)

13:49 _ato: alexyk: you originally mentioned Ruby, it's just like that from the type enforcement perspective

13:50 alexyk: _ato: I'm scared as heck of Ruby. I wonder if I can make annotations work for me.

13:50 hiredman: alexyk: I've only ever written a few lines of scala

13:50 cemerick: _ato: I'm not certain, but Ruby coerces values, so it's far more lax in that regard

13:50 lisppaste8: ozzilee annotated #89737 "Maybe this is what I want?" at http://paste.lisp.org/display/89737#1

13:51 hiredman: alexyk: why is ruby scary?

13:51 alexyk: Ruby degenerated into testing frameworks because of the lack of type safety. Hence the whole "agile testing" industry... recreate type system via unit tests.

13:51 cemerick: alexyk: this is worth a read re: type systems: http://www.pphsg.org/cdsmith/types.html

13:51 Guest77613: When you type hint a Clojure func, and you provide it with different types arguments

13:51 it will try to cast them

13:51 if the cast doesn't work

13:51 you get a cast exception

13:51 it's pretty straightforward

13:51 alexyk: so the question is how clear are the casting rules then

13:51 Chousuke: I recall Rich mentioning that he wouldn't oppose an optional "type system" based on predicates, but I don't think he (or anyone else) has any solid ideas about implementing something like that yet.

13:52 hiredman: alexyk: plenty of typed languages use testing frameworks

13:52 alexyk: hiredman: right, yet in Scala you can get by without one, while in Ruby you really have to have one.

13:52 Guest77613: it's pretty confusing with strings

13:52 rfgpfeiffer: Chousuke: datalog is also based on predicates and will always terminate

13:52 hiredman: alexyk: I think the divide is less typed/dynamic as functional/imperative

13:52 Guest77613: because everything in java can be casted to string

13:52 so if you type hint a func so it only accepts strings

13:52 it will actually accept anything

13:52 Chousuke: Guest77613: huh, they can?

13:53 hiredman: alexyk: functional code is more transparent and easier to reason about

13:53 Chousuke: what happens?

13:53 rfgpfeiffer: weren't there plans for embedding datalog in clojure?

13:53 Chousuke: do they just get .toString calleD?

13:53 rfgpfeiffer: something like that. or at least some handwawing :)

13:53 alexyk: toString would be a massive fail

13:53 Chousuke: waving*

13:53 hiredman: rfgpfeiffer: there is something called datalog in contrib

13:53 Guest77613: I don't think that is true

13:54 cemerick: Guest77613: that's very not true

13:54 _ato: hmm

13:54 cemerick: ,((fn [#^java.util.ArrayList s] (.floatValue s)) 6)

13:54 clojurebot: 6.0

13:54 _ato: ,((fn [#^String s] s) 5)

13:54 clojurebot: 5

13:54 _ato: ,(type ((fn [#^String s] s) 5))

13:54 clojurebot: java.lang.Integer

13:54 cemerick: The hint is just that, a hint. No type enforcement at fn boundaries

13:54 Guest77613: (defn repeat-2 [#^String a]

13:54 (str a a))

13:55 #'user/repeat-2

13:55 user> (repeat-2 "apo") |"apoapo"

13:55 user>(repeat-2123)

13:55 |"123123"

13:55 user> (repeat-2 [1 2 3 4])

13:55 "[1 2 3 4][1 2 3 4]"

13:55 Chousuke: Guest77613: it's not being cast to string; the type hint is just ignored.

13:55 cemerick: right, str is converting your parameters into strings.

13:55 Guest77613: Chousuke: how can it be ignored ?

13:56 ozzilee: cemerick: Sorry to keep hounding this. Could you take a look at my last paste? Is that at all idiomatic? Or can you point me towards some code that does things idiomatically?

13:56 lisppaste8: Chouser pasted "Java does not convert non-strings to strings automatically." at http://paste.lisp.org/display/89740

13:57 Chousuke: Guest77613: because it's just a hint

13:57 Guest77613: ok got it

13:57 Chousuke: Guest77613: Clojure uses it to avoid reflection when the type is correct, but will fall back to using reflection if it's not.

13:57 _ato: ,((fn [#^Long s] 5 + s) "foo")

13:57 Guest77613: did another test function that made more sense ..

13:57 clojurebot: "foo"

13:57 cemerick: ozzilee: no, bindings only hold within the scope of the binding.

13:57 Guest77613: ok

13:57 _ato: hmm.. that's weird

13:57 Chousuke: 5 + s?

13:57 Guest77613: so in theory it would be possible to make clojure throw an exception instead of just using reflection

13:57 _ato: oh wait

13:57 brain dead

13:57 Chousuke: you mean (+ 5 s) :P

13:58 Guest77613: when a type hint isnt being respected ?

13:58 _ato: all this talk of ruby is confusing me :p

13:58 ,((fn [#^Long s] (+ 5 s)) "foo")

13:58 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

13:58 chouser: Chousuke: no, it doesn't fall back on reflection if the type hint is wrong

13:58 alexyk: ,(+ 5 "4")

13:58 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

13:58 cemerick: ozzilee: you need to let your caller establish the binding themselves. If they're doing things in the right way in general, they'll establish the binding *once*, do all of their couch stuff, and be done.

13:58 alexyk: well this fails at least

13:58 chouser: it falls back to reflection if there is no type hint.

13:58 _ato: ,((fn [#^Long s] (+ s 5)) "foo")

13:58 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

13:58 _ato: ,((fn [s] (+ s 5)) "foo")

13:58 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

13:58 cemerick: alexyk: right, clojure is strongly typed

13:58 _ato: hmm

13:59 Guest77613: chouser : well then what does it do when there is a type hint, but it's not respected at runtime ?

13:59 _ato: alexyk: yeah, if that worked, it'd be an example of "weak typing"

13:59 Chousuke: ,((fn [#^Integer s] (.floatValue s)) 5.0)

13:59 clojurebot: java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer

13:59 chouser: if casting to the hinted type wouldn't help (say when calling a clojure fn rather than a Java method) then no casting is done regardless of whether a type hint was supplied or not

13:59 Chousuke: ah, I see.

13:59 cemerick: alexyk: you're looking for static typing, which is decidedly not clojure's approach, though it does avoid reflection when you provide it with type hints appropriately.

13:59 ozzilee: cemerick: Bah. Okay, I give up, I'll just do things verbosely. Thanks.

13:59 cemerick: ozzilee: I'm unclear as to what you think is verbose...?

14:00 saml: hey, did anyone write mp3 encoder purely in clojure?

14:00 or is there lisp/scheme implementation so that i can easily translate?

14:00 alexyk: interesting... just gauging stuff... are all Lisps like this?

14:00 chouser: mosts lisps don't run on top of a OO runtime like the JVM

14:00 _ato: alexyk: most, but there are some that are statically typed

14:01 Guest77613: alexyk : i think that there is a strong tradition of dynamic typing among lisps

14:01 alexyk: true, but in terms of dynamic and strong?

14:01 ozzilee: cemerick: I want to write a library that hides the couchdb access from its clients. Every function in that library has to either pass in or bind the hostname and the database name. I can't just set them in one place.

14:01 alexyk: how cal clojure be dynamic if Java is not, and JVM is made for Java originally?

14:01 can

14:01 _ato: saml: why would you want write one instead of using a library? just for fun?

14:01 cemerick: alexyk: most schemes do not have an object system built-in, so it's less of an issue.

14:01 chouser: alexyk: When I think I want a static type system it's because I'd like to catch a certain class of errors at compile time. You have a similar desire?

14:02 saml: _ato, to package into applet or web start instead of doing JNI with lame and including lame for windows,mac,linux....

14:02 cemerick: alexyk: Java *is* dynamic under the covers, but javac and the Java language don't provide an easy mechanism to access it.

14:02 alexyk: chouser: exactly. I'm am OCaml/Scala addict in terms of long and painful compile cycle, but when stuff compiles, it usually works.

14:02 chouser: alexyk: as it turns out, the Java language is static as processed by javac, but the JVM is quite dynamic internally.

14:02 alexyk: chouser: interesting

14:03 cemerick: chouser: hah, beat you this time. :-P ;-)

14:03 chouser: cemerick: :-)

14:03 _ato: saml: ah fair enough. I can't even find a pure java one, so there'd be no chance there's a pure Clojure one ;)

14:03 cemerick: alexyk: I used scala for about 8 months before coming to clojure. I don't miss it one bit :-)

14:04 alexyk: so with clojure, is there a similar experience that once stuff compiles it works, or is it Ruby-like, lots of unit testing?

14:04 saml: _ato, yup :P i was just wondering

14:04 Chousuke: chouser: heh, I read John Rose's post about continuations on the JVM today :P Scary stuff.

14:04 _ato: saml: looks like there's a pure java vorbis encoder though, if you don't need specifically mp3

14:04 Chousuke: (old post, but I was looking through the archives)

14:04 alexyk: cemerick: can you summarize your pain/pleasure points for Scala vs clojure?

14:04 technomancy: John Rose is the man.

14:04 _ato: alexyk: hehe.. I don't find in java that once stuff compiles "it works"

14:04 saml: i found a C implementation. i might port it: http://www.mp3-tech.org/programmer/sources/shine.zip

14:05 cemerick: alexyk: I'm not at all into the TDD stuff, but judicious testing is invaluable IMO.

14:05 chouser: alexyk: I have come to believe that required static type systems are an obstacle to a lot of interesting design work. I'm hopeful about the possibility of an optional static type system, but I'm not sure what that would look like.

14:06 saml: _ato, yah currently, our "reader" client is flash plugin. so it should be mp3 or flv. i found pure java speex encoder. so our "creator" (web start) client can convert to speex, but "reader" client can't read spx directly. it should be flv.

14:06 alexyk: cemerick: true. But what's the largest project in clojure so far? Also, I've just started reading the book... so pardon me for asking, does it have objects? (I don't really need them.)

14:06 cemerick: alexyk: Scala's type system is incredibly complicated, as is the language. Implicits are scary as hell. The impl. of traits similarly so. The easy mixing of mutable and immutable state makes it easy to turn things into a mash IMO.

14:06 chouser: alexyk: I would also contend that if the only errors in your program can be caught by a type system, then the program's not doing much of interest.

14:07 saml: so, i have 2 choices: implement mp3 encoder in "publisher" client. or implement flv encoder on client. or make swf with embedded speex

14:07 so 3 choices haha

14:07 chouser: alexyk: conversely, if you write tests that check the logic of your program, they will tend to catch type errors as well, making the effort of correct typing superfluous.

14:07 alexyk: chouser: true. Yet you can't deny the strange experience of forcing a Haskell/OCaml/Scala program to compile and then seeing it work *correctly* the first time it runs.

14:07 cemerick: alexyk: The largest projects are almost certainly not public at this point. Ours is getting pretty sizable, nearing the scope of our existing Java 'legacy' codebase from the past 5 years.

14:07 chouser: alexyk: happens to me in clojure all the time ;-)

14:07 _ato: alexyk: Clojure isn't object-oriented in the java classes sense. You can use and make java classes if you really want to, but you normally would just use data structures and functions instead

14:07 saml: or forget about fattening "publisher" client.. and convert everything in the server

14:08 cemerick: alexyk: and yes, "there's objects", but that's really not the interesting question.

14:08 alexyk: _ato: that's good, I didn't need no stinking objects in OCaml

14:08 although it was *O*Caml, nobody used the O

14:08 so I guess you package functions and their data into... what? closures? :)

14:09 chouser: that's one way, though not the most common

14:09 alexyk: what's an equivalent of ML/OCaml module?

14:09 cemerick: alexyk: there's proxy and gen-class currently; this is what's coming down the road, but it might be more than you're ready for yet: https://www.assembla.com/wiki/show/clojure/Datatypes

14:09 djork: data is data, and code is data :)

14:09 cemerick: alexyk: namespaces are modules, roughly

14:09 chouser: it's probably more common to group related functions (that possibly operate on similar data collection) into a namespace. Then your data is held in Clojure persistent collection (nested vectors/maps as needed)

14:10 alexyk: chouser: ah ok, makes sense. Those I see in REPL.

14:11 chouser: there's real power in using the same core collection types for all or most data

14:12 vs. each lib having it's own objects with its own fields and methods that can't operate on anyone else's data.

14:13 gbt: alexyk: I'm not sure how far your clojure goes? (I'm new too) but the common interface to all the datatypes is very cool :)

14:13 alexyk: so, what's the biggest open-source clojure project folks are aware of? I want to see me some githubbin'!

14:14 chouser: though as we speak rhickey is hard at work adding the ability to create efficient app-specific data objects with related methods.

14:14 alexyk: gbt: my closure is 1 day old. :) But my Scala is 6 months, and OCaml is a couple years... I also read 1/3 of the Practical Lisp book. :)

14:14 hiredman: http://github.com/languages/Clojure

14:14 chouser: probably contrib. :-P

14:15 alexyk: hiredman: ok, I should say, doing something else but self

14:15 cemerick: alexyk: yeah, those are all projects *using* clojure

14:16 alexyk: btw Scala tries to standardize all the fields via traits, it's really complex but seems to work in 2.8

14:16 technomancy: alexyk: the altlaw project is the biggest open codebase probably.

14:16 rhickey: chouser: but people *will* be able to use existing code on that app-specific data - it is both app-specific and generic

14:16 chouser: rhickey: ah, good point.

14:16 rhickey: I'm working hard on making the generic use fast

14:16 chouser: esp. if (:k x) is just as fast as (.k x)

14:17 rhickey: and the specific data dynamic

14:17 _ato: alexyk: altlaw is at: http://github.com/stuartsierra

14:17 alexyk: technomancy: _ato: thanks

14:17 _ato: the actual running version is: http://www.altlaw.org/

14:18 alexyk: rhickey: performance is another thing I wanted to ask, not to start any flames, but to understand JVM better. Is there any reason why Scala or Clojure would be faster or slower due to type system differences?

14:19 rhickey: alexyk: yes

14:20 alexyk: rhickey: which way?

14:20 Licenser: aloa good evening everyone

14:22 alexyk: I mean if JVM is dynamic enough, that shouldn't slow things down, especially if you don't incur casts by designing things carefully, right?

14:23 (also saw something about JVM designed to support dynamic languages better)

14:23 rhickey: alexyk: the more type information you have the faster things can be, potentially. Note that you can give Clojure type information. Also, if a system is designed to be dynamic, it will likely be faster at dynamic things then one that wasn't (or you will be rolling your own dynamic things, with perf on your head)

14:23 but there are no general answers applicable to specific problems, thus the futility of the exercise

14:24 alexyk: rhickey: yeah, I'll play with things like JSON parser/database insertions... I generally parse Twitter JSON stream then mine it.

14:25 are there good JDBC and/or Berkeley DB interfaces?

14:25 Licenser: A question, did someone ever started to put problems from language shootout / benchmarks in clojure code?

14:25 technomancy: what do folks think about clojure.test/report's :summary method returning true or false depending on if all the tests passed or not?

14:25 that would also cause run-tests to return a useful value

14:25 easy 1-liner

14:25 Licenser: alexyk: someone is developping a nice driver for mongodb, which would allow to store json directly in the database

14:26 alexyk: Licenser: thx for the idea!

14:26 Licenser: I use it for a pet project of mine, it's still alpha (the driver) but it works stable for me

14:29 _ato: alexyk: but yes SQL/BDB are easy enough. For BDB: http://github.com/gcv/cupboard

14:29 there's a couple of different SQL libraries, there's a simple one in contrib

14:30 alexyk: _ato: looovely cupboard, thx

14:30 Licenser: One thing I noticed while writing clojure, it is damn hard to write functional functions. I nearly always end up having sideeffects - is that a general problem or is it because I work on a web app?

14:31 _ato: Licenser: if it's a typical database-backed webapp, yes probably because it's a webapp

14:31 chouser: Licenser: the difficulty varies between different domains. I'd be a bit surprised if web apps were particularly hard, though.

14:31 alexyk: the clojure book lists contrib under google code, while here it's referred to via git. Which one is current?

14:31 chouser: alexyk: git

14:32 alexyk: why is it called contrib when in fact it's a stdlib? :)

14:32 Licenser: okay that makes me feel better, I was a bit frustrated that I don't manage to write pure functions, I nearly always end up with either a query, a commit or rendering in the function :/

14:33 chouser: Licenser: if you think of the input being the http req + the user's state (database, session, etc.) and the output being the page to render + new user state, then your whole app is a function. :-)

14:33 alexyk: Licenser: web it notoriously impure, downright dirty stuff :)

14:33 _ato: alexyk: there's sort of two "standard libraries" for clojure. There's "core" which comes with the language but is very small

14:33 Licenser: chouser: it's not about beeing hard to write the app - it's incredible easy I love clojure - I am just wondering if the fact that I don't get pure functions comes from he tasks or my incapability :P

14:33 _ato: alexyk: and "contrib" which has lots of handy but absolutely necessary stuff

14:33 Licenser: chouser: I like that vew ^^

14:33 _ato: err

14:33 not absolutely*

14:34 chouser: right. only seq-utils and repl-utils are absolutely necessary

14:34 :-)

14:34 oh, and str-utils2

14:34 alexyk: _ato: right, that's why my first reaction is, that's how contrib might have started, but if everybody is using it, it should be called something like stdlib, with contrib usually having kinda-nice things you can live without somebody bothered to upload

14:35 just a newbie's feedback, I know you guys got used to it

14:35 chouser: it's an interesting thought. might be useful to split contrib.

14:35 * technomancy is strongly in favour

14:35 technomancy: "experimental contrib" vs "tried-and-true, everyone uses"

14:36 * Licenser to

14:36 Licenser: I find some things in contrib very confusing

14:36 chouser: The hard line is between core and contrib: rhickey approves every commit to core individually, but not for contrib.

14:36 Licenser: coming form ruby I'm used to have a huge stdlib with all kind of nifty stuff

14:36 chouser: Licenser: We're still very early for that.

14:36 Licenser: chouser: then just rename it from clojure.contrib to clojure.stdlib :P

14:37 chouser: i know I know, but tings like seq-utils really could be in somet kind of stdlib

14:37 chouser: but there's definitely experimental stuff in contrib that's not necessarily recommended yet.

14:38 Licenser: I agree but some things are a defacto standard right?

14:38 chouser: there's also a hard line between contrib and non-contrib -- if it requires an external dependency or doesn't fall under the Clojure license or hasn't been approved (at least the broad strokes) by rhickey, then it's not in contrib.

14:38 so there may be value in splitting contrib itself, but it might be hard to define the line there. Could get political. :-(

14:39 Licenser: I don't know I find the whole license stuff a bit radical

14:39 _ato: mm.. I thought the initial idea was stuff would start off in contrib and could be "promoted" to clojure (not necessarily core) if it was tried and true and everybody used it

14:39 chouser: and I don't think we want any extra structure or policy unless it's needed -- such things generally come with hidden cost

14:40 Licenser: Not sure if it is because I was looking at licenses the moment I found clojure but I lately got the feeling that OS licenes at time make it harder to provide stuff as open source

14:40 chouser: _ato: the licensing allows for that

14:41 _ato: chouser: yeah, I was just talking about splitting contrib, not in reference to licenses

14:41 chouser: Licenser: yes, requiring a CA surely discourages some contributions, but has its benefits as well.

14:42 Licenser: It's a broader feeling, like alone choosing a license is a tasks that kind of discurages me from releasing stuff as OS

14:42 if I keep it closed source I just can say: leave me alone

14:42 chouser: Licenser: ah, I see. yeah, I can certainly see that.

14:43 Licenser: That's not even related with clojure

14:43 chouser: I once took a fair amount of abuse for trying charge for an upgrade to something I originally released as open source. :-P

14:43 Licenser: I've a ruby project I hope to be OS one day but when I set down to find a fitting license, I got hugely frustrated after a day and decided screw OS for now I keep it closed untill It calls for it :P

14:43 heh

14:44 yes it's horrible, open source is a jungle and event he liceses are hating eachoterh - at least partially

14:44 djork: anybody ever written a memory usage macro?

14:44 like time, but for memory

14:44 Licenser: call it mime

14:44 djork: I like it

14:45 I'm just not sure if it's right

14:45 (my macro)

14:45 _ato: how would a memory usage macro work?

14:46 it gives you the change in memory usage so you can see if you're leaking memory?

14:47 djork: yeah

14:47 just to see how much memory changes while evaluating & exprs

14:48 chouser: I think so -- you might check the google group. It's hard to be accurate on the JVM though.

14:49 _ato: it'd be hard to do accurately as the GC may not have collected everything even if you do (System/gc)

14:49 yeah

14:51 djork: yeah the GC makes it kind of suck

14:51 but it sort of works

14:51 jasapp: that'd be nice to have something like common lisp's time

14:51 one that reported bytes

14:52 I don't know if that would make sense in a jvm context though

14:53 djork: I think it's pretty accurate right now

14:53 [] is 8 bytes

14:53 ?

14:53 or is that 8 8 byte blocks

14:53 no it's bytes

14:55 chouser: arohner: are you here? just looked at your Scriptjure README -- looks quite useful.

14:55 djork: http://gist.github.com/225372

14:56 it's not too accurate...

14:56 chouser: arohner: I wondered if you knew you could tweak your js macro to treat ~ and ~@ specially, for example to do what your 'clj' does now.

14:57 arsatiki: ohh

14:57 _ato: (mime []) => -3256 bytes used

14:57 hmm

14:57 arsatiki: scriptjure made my head asplode out of happiness

14:57 because it's precisely what I've been looking for

14:58 djork: _ato: it has to "warm up"

14:58 it's certainly not perfect since the VM makes it kind of fuzzy

14:58 hence the voodoo 5 System/gc calls :)

14:58 _ato: yeah (mime (vec (range 1000))) gives something more sensible looking

15:00 unless clojure is so efficient that each empty vector *reduces* memory usage by 3k. :-P

15:01 djork: heh

15:01 chouser: I think rhickey has wanted something like scriptjure too.

15:02 djork: by golly I think it works

15:15 alexyk: Licenser: is this the clojure-mongo thing you mentioned? http://github.com/gilbertl/mongo-clojure-wrapper

15:15 Licenser: alexyk: nope this one I'm talking about: http://github.com/somnium/congomongo

15:17 alexyk: cool

15:17 jasapp: Licenser: are you using mongodb?

15:17 Licenser: jasapp: yes

15:17 jasapp: have you been using it for awhile?

15:18 Licenser: it has a few issues I see and it kind of seems as the server is still is in a development phase but it's very nice to use

15:18 jasapp: a week or so, no production use just developping with it

15:18 but it integreates very nicely in clojure

15:18 jasapp: I'm using it for a work related project right now

15:18 Licenser: (save for the few issues it has :P)

15:18 jasapp: I'm awaiting the addition of the or operator.

15:18 Licenser: heh

15:19 jasapp: they say it's supposed be out on November 11th

15:19 Licenser: update is a tricky thing, it isn't yet doing all I want

15:19 jasapp: *nods* they are still in heavy development

15:19 did you ask the $in question on the mailinglist? ^^

15:19 alexyk: I wonder how much can I stuff into mongodb... I get a Twitter feed, about 2 million tweets/daily. Each tweet is a JSON string with ~20 fields (with a nested user field). Could it handle 100 million such tweets?

15:20 duncanm: technomancy: is your branch of swank-clojure the canonical one now or should i stay with the jochu branch?

15:20 jasapp: alexyk: did you see that nosql benchmark?

15:20 alexyk: jasapp: no, which one?

15:20 fanatico: Good question came up on news.yc. Why doesn't memoize use java.lang.ref.SoftReferences?

15:20 technomancy: duncanm: use the "maven" branch of my fork to be most up-to-date.

15:20 jasapp: I want to say they looked at mongo, couchdb, and tokyo cabinet

15:20 let me see if I can find it

15:20 technomancy: duncanm: I'm about to release a 1.0, would love to get some more eyes on the latest version. hop on the mailing list if you have any problems.

15:20 Licenser: alexyk: I use it with 1 million fields at the moeent eats up about 2 GB of hdd but works very fast with good indexes so I think it sould be fine if you've the HW to back that up

15:20 duncanm: technomancy: and if i want to run start a swank server from within another app, do you have a snippet ready for doing that? (I had one before, but I lost it)

15:21 technomancy: i used to have a jar file of swank-clojure and i'd launch it from my app, and use M-x slime-connect from emacs to connect to it

15:21 technomancy: duncanm: I will make sure it gets into the readme before 1.0; in the mean time take a look at drewr's clot project on github; it's a good example

15:21 alexyk: Licenser: yeah, HW is no prob. Berkeley DB eats about as much per 1 mil/twits.

15:21 duncanm: but i lost that script ;-(

15:21 technomancy: nice, thank you

15:22 Licenser: alexyk: if you want a word of advice, don't use BDB it does not stand for berkeley but for braking DB in my experience

15:22 I really hate BDB

15:22 I hade huge problems both with near data lass due to some stupid updates without backwards compatibility

15:22 alexyk: Licenser: well, I've managed to stuff it allright from Scala... was pain though

15:22 duncanm: technomancy: http://github.com/drewr/clot/blob/master/src/com/draines/clot/main.clj is it 'swank!' that's the key part there?

15:23 technomancy: yep

15:23 duncanm: technomancy: and if i have maven installed, and i use your maven branch, mvn install will make me a jar file of swank-clojure?

15:23 technomancy: duncanm: yeah, that's the idea

15:24 alexyk: Licenser: I had to write Scala classes in a Java way and convert Scala types to Java's so that BDB would know how to store them... Is it the same in clojure?

15:24 Licenser: no you can store most of clojures objects directly in mongodb

15:24 and retreive them

15:25 alexyk: right, but about BDB -- can you store clojure structs as is in BDB, are they like Java classes for that purpose?

15:25 Licenser: as long as it are native types (hashmaps, arrays, ints, stirings lists

15:25 duncanm: technomancy: should i be using your version of slime too? right now i have the boinkor.net version checked out

15:26 technomancy: duncanm: yes, and there's a "from source" install instructions section in the readme

15:26 Licenser: alexyk: never worked with BDB and never will unless someone places a gun on my head and forces me too and even then I#d have a hard time to make a call

15:27 alexyk: Licenser: well, JE is not that bad, actually

15:27 Licenser: JE?

15:27 drewr: duncanm: it doesn't quite work flawlessly

15:27 alexyk: BDB Java Edition

15:27 drewr: I need to get sldb support in there

15:27 Licenser: don't care, I care about the fact that it has a huge design flaw with bacwards incompatibility

15:28 which makes it a no go for me

15:28 _ato: alexyk: yeah, if you use cupboard it'll automatically marshall the clojure data types

15:28 duncanm: drewr: ahh

15:28 technomancy: i don't see swank-clojure in elpa

15:28 technomancy: duncanm: look further down in the readme to the "from source" intructions

15:28 Licenser: I like things that don't have a auto-brake-and-delete-my-data feature

15:28 technomancy: I'm waiting for more people to give feedback and test before I submit it

15:29 hiredman: fanatico: it's come up on irc before

15:29 alexyk: _ato: the problem is, you don't want to store class info more than once... JE provides for that, wonder if cupboard takes advantage of that.

15:29 duncanm: ahhh

15:29 drewr: technomancy: I'm running the latest, but haven't tried the mvn stuff

15:29 alexyk: drewr: what is clot? :)

15:29 drewr: alexyk: IRC client

15:29 alexyk: ah ok

15:30 drewr: it's more of a bot though

15:30 Licenser: likely the cl(ojure b)ot

15:30 technomancy: I like clot, but I really don't like the fact that cd ~/src/cl TAB no longer completes to clojure. =(

15:31 drewr: I haven't been able to do that in quite some time

15:31 technomancy: heh

15:31 drewr: clojure-contrib, clj-*, etc.

15:31 clabango

15:32 technomancy: drewr: I meant to ask you, do you know why swank's start-server must be wrapped in a clojure.main/repl call?

15:32 alexyk: oh, another noob's question: is there a jline option for REPL?

15:32 technomancy: (I should know this, but there are vast swaths of swank that I haven't really dug into yet)

15:32 drewr: technomancy: I can't give you a detailed answer, but I found that swank really wants a repl set up before it can do anything

15:33 slime apparently starts a repl, runs swank, and then connects to it

15:33 technomancy: drewr: it seems like it'd be nice to have it be able to set up one for you. maybe that could be added to swank-clojure if everyone who wants to embed swank is going to need it.

15:33 drewr: definitely

15:34 there's an abstraction there waiting to be codified

15:34 technomancy: I'll try to sneak that in before 1.0 escapes.

15:34 _ato: alexyk: apparantly "java -cp jline-0.9.91.jar:clojure.jar jline.ConsoleRunner clojure.lang.Repl" I just use emacs though

15:35 alexyk: _ato: nice... I also use Emacs but log into a remote box where I find console-level jline useful. If the darn thing could only do C-r. I know about rlwrap, too, and the fact that jline can't search backwards makes me mad at it.

15:36 technomancy: alexyk: I prefer launching it inside rlwrap

15:38 _ato: alexyk: if there's no firewall in the way you can start a swank server inside your remote process and use M-x slime-connect in emacs to connect over a tcp socket

15:39 spuz: Question about iteration: Is map the only way to iterate through items in a list? Say I want to print each of the items in a list, I could say (map println mylist) but this would map each item to nil, return a new list and print each item as a side effect which doesn't seem to really fit conceptually with what I'm doing.

15:39 alexyk: _ato: hah! now I start to understand what swank is :)

15:39 _ato: spuz: (doseq [x mylist] (println x))

15:40 spuz: _ato: that's much nicer :)

15:40 _ato: evaluates eagerly (returns nil)

15:41 tknudsen: hey, are compojure/cascade stable enough for me to rely upon for simple apps? comments appreciated

15:42 hiredman: spuz: also, seqs are immutable so mapping print over a seq will make a seq of nils, but not change the source seq

15:43 spuz: yep, I get that but even so, map is wasting my time if I'm just relying on side effects :p

15:46 wasting its time rather*

15:47 duncanm: Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.util.regex.PatternSyntaxException: Illegal/unsupported escape sequence near index 4

15:47 eek

15:47 i can't build swank-clojure

15:51 StartsWithK: hi

15:52 if i want to use xml security from clojure (jsr 105), what is the best lib for that?

15:52 Licenser: StartsWithK: that is not true StartsWithK starts with S

15:52 StartsWithK: Licenser: by my name does

15:52 can clojure.xml do that?

15:53 _ato: KresimirStartsWithK

15:53 Licenser: sneaky person you should raname yourself to Steward then you could use StartsWithS

15:53 StartsWithK: :)

15:53 Licenser: and sorry I don't know about clojure.xml

15:54 StartsWithK: i looked at jdom and clojure.xml, clojure.xml dosn't use standard dom api, so i think that will not work, and jdom has some problems with xml security

15:54 is there some other lib?

16:01 ordnungswidrig: re

16:02 duncanm: bah

16:03 technomancy: util/class_browse.clj doesn't support windows ;-P

16:06 oh, this is a nasty bug

16:15 dum de dum

16:27 drewr: ping?

16:28 drewr: duncanm: pong

16:28 duncanm: drewr: i'm having problems building swank-clojure because my paths are in Windows style

16:28 Compiling swank.commands.completion to c:\Users\Duncan\git\swank-clojure\target\classes

16:28 and then it dies on \U

16:29 i'm trying to define file.separator to "/", but to no avail

16:29 drewr: with "ant -Dfile.sep..." ?

16:29 I'm not sure if that should work or not

16:29 I haven't looked at the latest swank build

16:29 duncanm: drewr: mvn has a -D flag too

16:29 drewr: I just use it out of src

16:30 duncanm: and i saw that you can write something like <configuration><file.separator>...</...>

16:30 drewr: probably so

16:30 duncanm: drewr: yeah, so do i, but right now i wanna embed it inside another app, so i need to give it a jar

16:31 drewr: ( cd src; jar cvf ../swank.jar swank )

16:31 duncanm: oh

16:31 drewr: ;-)

16:32 duncanm: drewr: doesn't that include all the files, and not just the class files?

16:33 drewr: yes, but in this case it's just clj files

16:33 duncanm: that's enough?

16:33 that's great

16:34 drewr: clojure looks in its classpath for .class or .clj

16:35 hiredman: was there ever a 1.1.0-alpha-SNAPSHOT download available from clojure.org?

16:39 chouser: I don't think so

16:42 http://github.com/richhickey/clojure/tarball/9bde10d

16:42 duncanm: drewr: beautiful, i got it working, thanks

16:44 drewr: duncanm: great!

16:46 ordnungswidrig: how do I test for a function

16:47 I mean how do I test if a value is a function?

16:47 hoeck1: ordnungswidrig: ifn? or fn?

16:48 ordnungswidrig: hoeck1: there I go. I search for function?

16:48 hoeck1: what's the difference?

16:49 chouser: ,[(ifn? {}) (fn? {})]

16:49 clojurebot: [true false]

16:49 hoeck1: ordnungswidrig: ifn? also returns true for keys, maps symbols and everything that implements IFn

16:49 chouser: ,(juxt {} [ifn? fn?])

16:49 clojurebot: #<core$juxt__4916$fn__4926 clojure.core$juxt__4916$fn__4926@7e8bd9>

16:49 * chouser reads the docs for juxt again

16:49 ordnungswidrig: ,((juxt {} [inf? fn?]))

16:49 clojurebot: java.lang.Exception: Unable to resolve symbol: inf? in this context

16:50 ordnungswidrig: ,((juxt {} [ifn? fn?]))

16:50 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentArrayMap

16:50 hiredman:

16:50 ordnungswidrig: give up

16:50 hiredman: ,((juxt ifn? fn?) {})

16:50 clojurebot: [true false]

16:50 chouser: hiredman: thanks!

16:51 ordnungswidrig: good night for now

16:51 cu all

16:51 hoeck1: ordnungswidrig: n8

16:52 hiredman: juxt is my new favorite function

16:53 chouser: is it a superset of partial?

16:53 hm, no but has some overlap

16:53 hiredman: not really

16:54 chouser: oh. no -- would if partial allowed a single (fn) arg.

16:54 hiredman: it's, uh, sort of map+repeat

16:54 but not really

16:55 update-in+vec+repeat

16:55 ,(repeat 2 {})

16:55 clojurebot: ({} {})

16:55 hiredman: ,(vec (repeat 2 {}))

16:55 clojurebot: [{} {}]

16:55 hiredman: ,(update-in (vec (repeat 2 {})) [0] ifn?)

16:55 clojurebot: [true {}]

16:55 hiredman: ,(update-in (update-in (vec (repeat 2 {})) [0] ifn?) [1] fn?)

16:55 clojurebot: [true false]

16:56 hiredman: ,((juxt ifn? fn?) {})

16:56 clojurebot: [true false]

16:57 hiredman: ,(-> {} ((partial repeat 2)) vec (update-in [0] ifn?) (update-in [1] fn?))

16:57 clojurebot: [true false]

16:57 javucci: hello

16:57 Chousuke: I still don't like that ((partial foo bar)) form

16:58 javucci: please, an easy way to install clojure with emacs on linux

16:59 hiredman: Chousuke: I don't mind, obviously

16:59 ~emacs

16:59 clojurebot: emacs is best configured for Clojure with instructions at http://technomancy.us/126

17:03 duncanm: drewr: hey, i think there's a little bug in the swank startup script?

17:03 No value supplied for key: true in 19: swank.commands.basic$eval__1000$load_file__1002.invoke(basic.clj:133)

17:04 does it have something to do with this line? (swap! stop (fn [_] true))

17:04 hmm

17:04 drewr: duncanm: likely, I haven't tested it with any recent swank

17:05 this is the version I'm using with that code you saw: 20090804201540+bfb55c4

17:06 The-Kenny: I really dislike the installation process of swank-clojure... I managed to set up my own environment, but I'm afraid to update swank-clojure because I don't want to break it.

17:08 rhickey: ok - keyword call sites are in place in new branch

17:12 duncanm: cool

17:13 * duncanm likes keywords in CL, and wishes more Schemes supported the DSSSL keywords

17:14 technomancy: The-Kenny: you dislike M-x clojure-install or the new process from the maven branch?

17:14 The-Kenny: technomancy: M-x clojure-install

17:15 technomancy: The-Kenny: you'll be happy to hear it's going away... check out the latest on my maven branch.

17:16 The-Kenny: technomancy: The best way (in my opinion) would be to just put the emacs-files together with the clojure-files somewhere, load the files in emacs and configure some of the variables (path to clojure.jar etc.)

17:16 javucci: The-Kenny, i use debian lenny and package-list-packages doesn't exists

17:16 The-Kenny: javucci? I think you want to talk to someone else here :)

17:17 javucci: how to make package-list-packages avaiable in emacs?

17:18 technomancy: javucci: http://tromey.com/elpa/install.html

17:19 javucci: thanks technomancy

17:25 patricius_: are there anyone here using VimClojure?

17:28 hiredman: I'm using the static part of vimclojure

17:28 patricius_: ok

17:28 Well, for one thing, I can't get indenting to work

17:29 it detects the filetype, but when I write "(defn function-name [] <ENTER>" it doesn't indent

17:30 perhaps there is a more suitable channel for this? maybe a forum?

17:30 couldn't find one tho

17:32 hiredman: patricius_: do you have all the thing it recommends setting?

17:32 syntax on

17:32 filetype plugin indent on

17:32 from the README.txt

17:32 patricius_: let me double check

17:33 hiredman: I haven't actually messed with vimclojure since I installed whatever version I am using many months ago

17:36 patricius_: those options are set as suggested in README.txt. Syntax highlighting seems to work fine.

17:37 hiredman: *shrug*

17:37 the author is in here from time to time

17:38 patricius_: darn it

17:38 hiredman: do you have any other indeinting options set?

17:38 patricius_: but do you use vim for your day to day clojure programming?

17:38 hiredman: yes

17:38 patricius_: I don't think I do

17:39 hiredman: for I think the gvim window on my netbook has tabs with clojure, c, sh, llvm ir, and maybe latex

17:40 :P

17:40 patricius_: :)

17:40 hiredman: you're thinking about 'lisp' and 'autoindent' options perhaps=

17:40 hiredman: patricius_: no idea

17:40 patricius_: :)

17:41 hiredman: I was just asking without thinking of anything specific

17:41 patricius_: thought so

17:41 but as I said, I don't think I have any other options set... not from looking at my .vimrc and gvimrc

17:42 technomancy: hiredman: so when are we going to start up the Seattle Clojure group? =)

17:42 hiredman: patricius_: what does :set filetype say on a clojure file

17:42 patricius_: filetype=clojure

17:42 hiredman: technomancy: it's more of a duo with just the two of us

17:42 patricius_: hiredman: syntax hilighting works it seems

17:43 technomancy: yeah, "group" might be a bit of a stretch

17:43 actually the clojure users' map lists two others

17:43 patricius_: i talked to two mormon girls from Seattle today... in Denmark (Northern Europe) - aren't you happy to know that?

17:44 hiredman: and what would we do? I could give a presentation on why "->" is awesome which will just be a bunch of confusing code wrapped in several layers of parens

17:44 technomancy: we could work on the Grande Unified Clojure Dependency Mechanism

17:45 hiredman: clojurebot: translate to fr: Grand Unified Clojure Dependency Mechanism

17:45 clojurebot: Grand Unified Clojure dépendance Mécanisme

17:45 hiredman: :/

17:45 technomancy: cd sa-safe

17:46 bah; wrong window

17:46 rsynnott_: slightly less than impressive

17:46 does its 'translate to french' function just entail adding random accents? :)

17:46 hiredman: rsynnott_: it uses google translate

17:46 clojurebot: translate to de: Grand Unified Clojure Dependency Mechanism

17:46 clojurebot: Grand Unified Clojure Dependency Mechanismus

17:47 technomancy: rsynnott_: that would be random accents using Markov Chains, thankyouverymuch!

17:47 hiredman: clojurebot: translate to de: grand unified Clojure dependency mechanism

17:47 clojurebot: Grand Unified Clojure Abhängigkeit Mechanismus

17:47 hiredman: zounds

17:48 clojurebot: translate to de: great unified Clojure dependency mechanism

17:48 clojurebot: großen einheitlichen Clojure Abhängigkeit Mechanismus

17:48 lpetit: translate from fr to en: bonne nuit

17:48 hiredman: GECAM

17:48 lpetit: :)

17:48 whoops

17:48 clojurebot: translate from fr to en: bonne nuit

17:48 clojurebot: to in: good night

17:48 rsynnott_: heheheh

17:49 hiredman: clojurebot: translate from de großen einheitlichen Clojure Abhängigkeit Mechanismus

17:49 clojurebot: large, single Clojure dependent mechanism

17:49 hiredman: nice

17:51 Chousuke: clojurebot: translate to fi: great unified Clojure dependency mechanism

17:51 clojurebot: suuri yhtenäinen Clojure riippuvuuden mekanismi

17:51 Chousuke: nice try :P

17:52 hiredman: clojurebot: translate from fi suuri yhtenäinen Clojure riippuvuuden mekanismi

17:52 clojurebot: high dependence on a single mechanism for Clojure

17:52 Chousuke: that's closer to "Large unified mechanism of Clojure addiction"

17:52 hiredman: Chousuke: haha

17:52 perfect

17:52 SYCRM

17:52 Chousuke: though even that is fairly liberal

17:54 hiredman: LUMOCA

17:54 Large Unified Method Of Clojure Addiction

17:54 Chousuke: "unified dependency handling system" would be something like "Yhtenäinen riippuvuuksienhallintajärjestelmä" which Google translate will no doubt fail to translate because of the huge compound word :P

17:56 The method GT uses for translation doesn't map very well between English and Finnish :/

17:56 because it isn't capable of breaking compounds into their constituents

17:57 hiredman: ah

17:57 the statistical translation bits

17:57 clojurebot: translate to kr hello

17:57 whoops

17:58 clojurebot: translate to ko hello

17:58 clojurebot: 안녕하세요

17:58 hiredman: nice, don't have the right fonts

17:58 Chousuke: I do, but I can't read korean ;/

17:58 hiredman: but pasted else where that looks about right

17:59 Chousuke: clojurebot: translate from ko: 요

17:59 clojurebot: John

17:59 Chousuke: ??? :D

17:59 hiredman: weird

17:59 more like Yo

17:59 or Yoh

18:00 korean as a bunch of dirrent yo sounds that I could never tell apart that are always transliterated slightly differently

18:00 I mean, they all sounds like "yo" to me

18:01 Chousuke: I don't know much about Korean but I hear it's quite similar to Japanese, structurally at least.

18:01 spuz: clojurebot: translate from ko: 녕

18:01 clojurebot: Goodbye

18:02 spuz: heh, awesome, "Hello" has "Goodbye" encoded within it in Korean

18:02 Chousuke: I really got a good laugh out of the "John" :P

18:02 spuz: I can't even see these characters which makes it all the stranger

18:03 clojurebot: translate from ko: 하

18:03 clojurebot: Summer

18:03 hiredman: putty shows them as little boxes

18:03 spuz: clojurebot: translate from ko: 세

18:03 clojurebot: 3

18:03 spuz: clojurebot: translate from ko: 요

18:03 clojurebot: John

18:04 spuz: wow, all that just to say Hello :)

18:04 Chousuke: well, korean writing is phonetic :P

18:04 hiredman: each of those boxes is actually comprised of multilple characters too

18:04 some combination of consonant and vowel

18:04 Chousuke: you have goo in good morning too :)

18:07 the usual Japanese word of hello is interesting. It's actually an abbreviation of some sentence that probably was something like "Today is a good day" originally.

18:07 but it's been abbreviated to just "today (is)" and lives as its own word :P

18:09 I think it might be the only word that has a grammatical particle permanently affixed to it :/

18:18 cemerick: is anyone else getting this building the new branch: java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (PrettyWriter.clj:17)

18:18 hiredman: cemerick: typically it means you need to rebuild contrib

18:19 cemerick: hiredman: yeah, I'm clean-building it :-/

18:21 hrm, maybe not. I've got this nifty rebuild-clojure target, but it doesn't specify clean + jar for the contrib subant, only jar.

18:22 yeah, nevermind. Damn stupid operator error.

19:38 oh, no, PersistentStructMap is final now :-/

19:39 rhickey: cemerick: you weren't deriving from a concrete class, were you?

19:40 cemerick: rhickey: I was for my über-struct macros.

19:40 rhickey: it needn't be final, just a remnant from some perf tweaks... hang on

19:41 cemerick: rhickey: I wouldn't bother...there's more to it than the final.

19:41 There was also the constructor, and the makeNew (or whatever it was called) method that allowed for polymorphic assoc, etc.

19:41 rhickey: like what?

19:41 cemerick: constructors*

19:42 I'm happy enough to rip out all of the über-struct garbage, and see what falls out. It'll make the porting process more interesting :-)

19:43 rhickey: cemerick: there was that stuff where?

19:44 I don't think there are any external differences at all

19:44 other than the final

19:45 I just made it so the keyslots could be an arraymap

19:46 cemerick: there was the protected constructor PersistentStructMap(IPersistentMap meta, Def def, Object[] vals, IPersistentMap ext) and the protected PersistentStructMap makeNew(IPersistentMap meta, Def def, Object[] vals, IPersistentMap ext) method.

19:46 oh, those are still there :-/

19:46 rhickey: right

19:46 cemerick: It's been a rough couple of days, sorry. :-(

19:47 In that case, I'll just twiddle it to not be final.

19:47 Pardon the interruption.

19:48 rhickey: it's fixed

19:49 cemerick: the tweaks I made make a big perf difference - there's still more to do, but I imagine people will move to deftype

19:50 cemerick: rhickey: Thanks very much. I can totally understand you wanting to make it final, though.

19:51 That's my second chicken-little-esque moment in an hour, which is a new personal record.

19:52 rhickey: no worries - did you try out deftype yet? It screams vs defstruct, 3x as fast as the improved defstruct version that's there in new

19:52 cemerick: rhickey: I'm in the process now :-)

19:53 rhickey: keyword call sites - (:field x) now same speed as (.field x) for deftype

19:53 blackdog_: i don't see a branch for deftype or is it right in git head?

19:53 cemerick: blackdog_: it's in the 'new' branch

19:54 blackdog_: ok, i need to visit github

19:54 ta

19:56 cemerick: rhickey: Not sure what you're seeing, but I think there's another tipping point falling. Lots of totally green folks in here lately, and I got my ear chewed off by two completely random programmers who aren't generally language enthusiasts over the weekend about how much they were enjoying *using* the language.

19:57 rhickey: yeah, it keeps growing

19:58 weissj: i'm doing euler probs in clojure right now. its fun

19:58 it's like i have a power tool in my hands that i know can do just about anything if i just figure out how to use it :)

20:04 churib: weissj: which problem do you currently work on?

20:04 weissj: churib: #14

20:05 churib: i am on #7

20:05 weissj: churib: cool, i just did that one last night, i can help you if you need it

20:05 churib: it really makes fun!

20:07 i am currently trying to replace the multiplications by sums

20:08 weissj: churib: #7? find the 10001st prime?

20:08 churib: hm wait :)

20:08 okay, i am #6

20:08 weissj: ah haven't tried that one

20:08 churib: but 7 is already solved :)

20:20 weissj: churib: can i see your solution for #7

20:22 srader: just tried out the new deftype :field perf improvement. Wow! Almost the same as .field now.

20:23 rhickey: srader: it is the same as field on my tests

20:23 as .field

20:25 srader: I ran my tests individually now and get = perf. Not sure why when running as a batch they were slightly different.

20:25 rhickey: although every now and then hotspot does less with it than most other times

20:27 srader: you have to make sure you are getting a non-polymorphic call path, the cache will only fully inline if the call path has only seen one type, once more than one type you get a slight reduction from then on

20:28 srader: ok, thanks

20:29 rhickey: i.e. if you have a fn that reads :a :b and :c of its args, and flow a ton of the same deftype through it, it will be fastest. Then send some structs or arraymaps with :a :b :c keys through the same fn, will be slower (as expected) but going back to the original deftypes will also be slower

20:30 hiredman: does hotspot ever re-inline?

20:30 rhickey: hiredman: I don't know why it couldn't, but I didn't see it

20:31 * hiredman files that under misc.

20:31 rhickey: but that's really a non-use-case of this, since .field isn't polymorphic ever

20:32 so, in cases where you are defining methods of a protocol for some deftype Foo, that code will only ever see Foos

20:32 hiredman: uhhuh

21:00 weissj: can i get a hint how to convert '(\2 \1 \3) char seq into the number 213 ?

21:02 tomoj: ,(Integer/parseInt (apply str '(\2 \1 \3)))

21:02 clojurebot: 213

21:02 rlb: weissj: maybe not the best approach, but (Integer/praseInt (apply str x)) should work

21:02 s/praseInt/parseInt/

21:03 weissj: thx tomoj and rlb for your near simultaneous and identical solutions :)

21:03 rlb: I just assume there's some awesomely clever clojure solution I don't know about yet...

21:03 tomoj: read-string looks more clojure-ish but can be dangerous I think

21:04 I mean if you don't have control over the chars coming in

21:04 weissj: tomoj - i do - i am trying to basically right-circular shift a number

21:05 ie 321 -> 132

21:06 hiredman: ,(-> 321 Integer/toString)

21:06 clojurebot: "321"

21:07 hiredman: ,(-> 321 Integer/toString cycle ((partial take 4)))

21:07 clojurebot: (\3 \2 \1 \3)

21:07 hiredman: rmmm

21:08 ,(-> 321 Integer/toString cycle ((partial repeate 2)) ((juxt first (comp reverse second))))

21:08 clojurebot: java.lang.Exception: Unable to resolve symbol: repeate in this context

21:08 hiredman: ,(-> 321 Integer/toString cycle ((partial repeat 2)) ((juxt first (comp reverse second))))

21:08 uh oh

21:08 clojurebot: ping?

21:09 ,(-> 321 Integer/toString ((partial repeat 2)) ((juxt first (comp reverse second))))

21:09 hmmm

21:09 ,(repeat 2 "321")

21:09 huh

21:11 tomoj: you killed him

21:11 hiredman: thats just odd

21:12 user=> (repeat 2 "321")

21:12 ("321" "321")

21:14 ,(repeat 2 "321")

21:14 clojurebot: ("321" "321")

21:14 hiredman: ,(-> 321 Integer/toString ((partial repeat 2)))

21:14 clojurebot: ("321" "321")

21:15 hiredman: ,(-> 321 Integer/toString ((partial repeat 2)) ((juxt first (comp reverse second))))

21:15 clojurebot: ["321" (\1 \2 \3)]

21:15 hiredman: ,(-> 321 Integer/toString ((partial repeat 2)) ((juxt first (comp reverse second))) ((partial apply concat)))

21:15 clojurebot: (\3 \2 \1 \1 \2 \3)

21:16 hiredman: huh, thats not helping

21:16 dysinger: ls

21:16 lol oops - emacs!

21:17 tomoj: ,(+ (* (mod 321 10) (reduce * (take (dec (.length (str 321))) (repeat 10)))) (quot 321 10))

21:17 clojurebot: 132

21:17 hiredman: ((fn [x] (Integer/parseInt (apply str (last x) (butlast x)))) "321")

21:17 ,((fn [x] (Integer/parseInt (apply str (last x) (butlast x)))) "321")

21:17 clojurebot: 132

21:18 tomoj: ooh nice

21:18 hiredman: hmmm

21:19 ,(+ 132 9)

21:19 clojurebot: 141

22:14 tomoj: I'm considering writing macros that communicate with an external server when compiled

22:14 is this evil

22:14 ..seems like it is probably evil

22:20 robink: Anyone know of a Gentoo ebuild for Compojure?

22:22 dysinger: http://build.clojure.org :)

22:23 danlarkin: tada!

22:24 rhickey: cool

22:28 dysinger: you can download the latest jar straight from the site

22:28 or you can use it for a maven repo

22:29 rhickey: sign up and I'll admin you

22:30 rhickey: I'm in

22:30 dysinger: your name ?

22:30 rhickey ?

22:30 rhickey: richhickey

22:30 dysinger: 1 sec

22:31 done

22:32 rhickey: thanks

22:33 dysinger: you can add yourself to the build notifications at the bottom of the project "configure" screen

22:35 rhickey: will it build branches?

22:36 dysinger: I think so

22:36 there's a spot to configure branches in there

22:36 we'll have to fiddle with it

22:37 rhickey: found it

22:38 dysinger: do you want */new or just new ?

22:39 I don't know - just curious

22:39 rhickey: got me

22:41 dysinger: oh when you save it changes new to */new

22:41 I put lazy in there too just for kicks

22:41 rhickey: lazy is over

22:41 only master, new and par are active

22:42 hiredman: :D

22:43 my clojure hello world appengine app is up

22:43 now to figure out the facebook api

22:44 dysinger: rhickey: http://build.clojure.org/job/clojure/13/ :)

22:45 par didn't work http://build.clojure.org/job/clojure/14/console

22:45 rhickey: par needs support lib

22:46 http://cloud.github.com/downloads/richhickey/clojure/jsr166y.jar

22:46 and to be built for java 6

22:46 so, I'm happy with master and new

22:47 dysinger: this is ubuntu karmic - I think it only has java6

22:48 rhickey: then it just may be matter of having jsr166y.jar next to clojure.jar

22:53 and in classpath

22:54 dysinger: rhickey: current bug in hudson https://hudson.dev.java.net/issues/show_bug.cgi?id=4422

22:54 we'll have to watch for that

22:54 and not go crazy with branches right now

22:56 rhickey: new would be the only one I care about, as I'd like people to try it. It builds, tests, and builds contrib + tests before I check it in

22:57 dysinger: I fixed it - so it's new and master for now

22:57 rhickey: great

22:57 I wish it showed the branch more prominently in the views

23:01 Thanks again, I don't intend to muck with it

23:02 * rhickey usually has a fresh build :)

23:02 dysinger: heh

23:05 qed: how does clojure clean up old versions of persistent tree structures?

23:05 rhickey: qed: gc

23:08 qed: rhickey: im having a little trouble wrapping my mind around persistence and the idea of tries-- structural sharing and all of that

23:09 it just seems sort of...well...impossible

23:09 how does the garbage collector know when it can safely prune a version of the tree?

23:10 notallama: same way it knows when it can prune anything else

23:10 solussd: I want an infinite lazy seq of random ints, but this produces "less than random" looking ints: (iterate rand-int 100)

23:10 qed: how's that, notallama?

23:11 hiredman: new versions of the datastructure don't keep references to the entire previous version, just the parts that it needs

23:11 tomoj: solussd: think about what iterate does

23:11 solussd: ,(take 10 (iterate rand-int 100))

23:11 clojurebot: (100 98 49 12 6 0 0 0 0 0)

23:11 notallama: when you make a 'change' to a tree, you're really making a new root, which is an almost-copy of the old root. one of the nodes is another new almost-copy, etc.

23:11 solussd: oh, i see tomoj

23:11 tomoj: you're getting s0=(rand-int 100), s1=(rand-int s0), s2=(rand-int s1),...

23:11 what you want is probably (repeatedly #(rand-int 100))

23:12 solussd: thanks

23:12 tomoj: (actually s0=100, and then on from there)

23:12 notallama: and the garbage collector can walk from the roots of all the trees (which share nodes). anything that it can't reach can be freed. (it uses tricks so that it doesn't have to walk the trees all the time, though)

23:13 tomoj: I would like to know what the expected length of (take-while (complement zero?) (iterate rand-int n)) is, though

23:13 solussd: i like this: (take 50 (distinct (repeatedly #(rand-int 100)))) *being able to specify I want an infinite list of distinct items. :)

23:13 even though there are only 100

23:14 hangs ... forever?

23:14 ,(take 101 (distinct (repeatedly #(rand-int 100))))

23:14 clojurebot: Execution Timed Out

23:14 solussd: heh

23:25 tomoj: hmm, seems to be about log(x)+1.6 (if you count the first zero as well)

23:34 the answer appears to be about log(n)+0.575

23:36 oops, wrong channel

23:38 hiredman: http://mrepo.happyfern.com/sites/facebook-java-api/facebook-java-api/apidocs/index.html this is horrible

23:40 somnium: hiredman: it always helps when everything is piled into one package. have you graphed it?

23:40 tomoj: what pisses me off is that we can't send messages through the API

23:40 only read them

23:42 hiredman: facebook seems to wnat to make it as hard as possible to write a facebook app in a language other than php

23:42 somnium: :)

23:47 hiredman: I'm still trying to figure out their login model

23:47 or whatever it would be called

23:47 solussd: what's wrong with this? It's throwing an illegal argument exception: (take 10 (distinct (repeatedly #([(rand-int 100) (rand-int 100)]))))

23:48 tomoj: you can't put a vector like that in a #()

23:48 you could use vector instead

23:48 solussd: I want 10 vectors of 2 random ints

23:49 tomoj: ,(take 10 (distinct (repeatedly #(vector (rand-int 100) (rand-int 100)))))

23:49 clojurebot: ([67 79] [85 41] [84 62] [54 26] [90 77] [68 27] [15 93] [14 5] [25 13] [30 33])

23:49 solussd: ah- i was trying to use vec, but that takes a coll

23:49 thanks

23:50 tomoj: it's because of what #() is

23:50 what is it again?

23:50 solussd: macro?

23:50 tomoj: ah, yeah, #(foo) is (fn [] (foo))

23:51 so #([foo]) is (fn [] ([foo])) which is wrong

23:51 you could write (fn [] [foo]) as well

23:51 or #(vector foo)

23:59 Puzzler: ?

23:59 G0SUB: I am not sure if Tim Bray criticised or appreciated Clojure in his blog post http://www.tbray.org/ongoing/When/200x/2009/11/03/Clojure-N00b-Advice

Logging service provided by n01se.net