0:07 rlb: chouser: I think he's written a recursive func to do it -- see the link above.
0:07 (if I understand correctly)
0:09 technomancy: anyone want to test out a release candidate for slime that I'm going to submit to elpa?
0:09 chouser: ah, I see.
0:09 technomancy: http://
0:09 chouser: djork: you maybe be able to essentially wrap lazy-seq around the body of the function.
0:10 then use cons instead of conj and () instead of [] -- and you get a lazy seq that won't overflow the stack.
0:14 GenericUser1: Hello.
0:15 tomoj: technomancy: is it modified at all or just packaged for elpa/
0:16 chouser: GenericUser1: an appropraitly generic greeting. Welcome!
0:16 GenericUser1: I'm trying to learn clojure, and I'm having a bit of trouble figuring out the details of refs, agents, and vars. In particular, if I wish to refer to a ref from the value of another ref, is this safe to do?
0:17 Thanks :)
0:17 technomancy: tomoj: it's a slightly later version of trunk than the one that M-x clojure-install uses, but the only modifications I made myself were for elpa.
0:18 GenericUser1: To be a bit more concrete, I'm trying to model the states of various rooms, and I'd like to be able to keep a mapping of exits from one room to another, which may change at a later point in the room's existance.
0:18 chouser: GenericUser1: yes, a ref can contain a ref (though that would be a bit silly) or contain a collection ...
0:19 yes, a ref with a collection that includes another ref is perfectly safe.
0:19 GenericUser1: Ok. Is there any way I can stop the repl from evaluating circularly linked refs? :)
0:19 chouser: heh.
0:20 set your *print-depth*
0:21 sorry, *print-level*
0:21 (set! *print-level* 15) is what I usually use, though you may find that to be too deep or too shallow depending on what you're doing.
0:21 GenericUser1: ok
0:22 chouser: another option would be to store your rooms in a single top-level map, each keyed by some kind of unique identifier.
0:22 then instead of a ref pointing directly to another room, it could point to that room's key, avoiding direct loops.
0:23 GenericUser1: Ok.
0:23 Yes, that may be a nicer option.
0:23 tomoj: GenericUser1: I think there's an example of just that kind of program on github somewhere
0:24 yeah, http://
0:24 technomancy: GenericUser1: gosh, that sounds awfully familiar... =)
0:25 tomoj: I have a similar problem trying to make representations of directed graphs
0:25 GenericUser1: Hmm, thanks.
0:25 technomancy: ?
0:26 technomancy: GenericUser1: the link tomoj pasted
0:26 GenericUser1: ah ;)
0:26 technomancy: it's a tutorial-type project of mine
0:28 GenericUser1: Does anyone else have problems with the API page in Firefox?
0:29 It seems that the page rendering gets cut off about half way down the list
0:29 tomoj: someone else complained about something like that before, too, I think
0:29 doesn't happen to me in any browser
0:31 GenericUser1: I'm in Firefox 3.5.3 on Vista, currently, although I've had issues with it on several other computers (I can't remember their configurations though).
0:31 Is there a good place to file a report about it?
0:32 technomancy: tomoj: I've got some ideas about the next version of swank-clojure if you've got a minute for feedback
0:32 (or anyone who's interested really)
0:34 tomoj: sure
0:35 GenericUser1: What is the meaning of "Experimental" in the API docs with regards to watchers?
0:35 technomancy: I'm going to submit swank-clojure as an elpa package too so it can depend on clojure-mode and slime
0:35 tomoj: GenericUser1: I guess it means it could change?
0:35 technomancy: and I'm trying to decide if I should get the Clojure code itself (Clojure, Contrib, and Swank) installed via git or some other mechanism
0:35 currently I'm leaning towards downloading jars into ~/.swank-clojure
0:36 but maven deps are also an option
0:37 tomoj: I dunno anything about maven
0:38 technomancy: I'm not really sure it supports this use case anyway
0:38 tomoj: by "downloading jars into ~/.swank-clojure" do you mean cloning the git and building like clojure-install does?
0:38 technomancy: (downloading dependencies without actually having a project checked out on disk)
0:38 tomoj: that seems fine to me
0:38 technomancy: I'm thinking downloading pre-build jobs
0:38 *jars
0:39 tomoj: oh, I dunno anything about that either :(
0:42 technomancy: tomoj: you mean you don't know if it's a good idea?
0:43 tomoj: I don't even know what a pre-build jar is
0:43 technomancy: just a jar that has been compiled by someone else
0:44 rlb: chouser: if you need to traverse a source collection and generate varying number of result items per-input, is that kind of lazy-seq approach one of the better ones in clojure?
0:44 technomancy: the only reason M-x clojure-install even performs a git checkout is that it was written before Clojure had turned 1.0
0:44 tomoj: oh, I thought "pre-build" meant it hadn't been built yet, english is funny :)
0:45 technomancy: hehe
0:45 I just want to reduce the number of working parts
0:45 tomoj: yeah I have had problems before with git/ant
0:45 technomancy: this would also make it a non-issue that OS X refuses to honor $PATH for gui-launched apps since git wouldn't be involved.
0:45 tomoj: and windows people have problems too I think
0:45 technomancy: that's like the #1 source of "bug" reports for me
0:46 tomoj: and if I want to use edge clojure I can just dump my own jars into .swank-clojure?
0:46 technomancy: yeah
0:46 tomoj: sounds good to me
0:47 technomancy: maybe have a defvar to tell it to look in a given dir so you don't have to manually drop the jars in there
0:49 chouser: rlb: depends on if you want a lazy seq or not, I suppose. If you don't, you'd have to convert your non-tail-recursive function into a tail-recursive one by adding an accumulator for your output collection (see "on lisp")
0:51 to avoid stack overflow, I mean.
0:53 rlb: Right -- I just didn't know if there was some clever clojure map-like function that I hadn't heard of yet.
0:53 (optionally destructuring map-like function)
0:54 GenericUser1: Is there a way to change how the print functions treat a value?
0:54 rlb: ...and I ask because it seems like often there often is some clever clojure function...
0:55 anyway, thanks.
0:55 piccolino: technomancy: was changing the checkout command the right fix?
0:58 technomancy: piccolino: it should be, though I don't understand why "git checkout clojure-1.0-compatible" failed
0:59 piccolino: did you catch the discussion above about removing the checkout/compile part and just downloading precompiled jars?
0:59 piccolino: Yeah, I don't either. Especially since it works for clojure itself. Is this not something that happens for you too?
0:59 I did see that. That sounds better, but I didn't know there was a pre-built release of clojure-contrib 1.0.
0:59 I asked about that in here about a week ago because I was trying to get a MacPorts portfile made for clojure-contrib.
0:59 technomancy: well I would build it and upload it myself; there's not an "official" one
1:00 piccolino: Oh, I see.
1:01 GenericUser1: Am I supposed to see stacktraces on exceptions?
1:02 I keep getting relatively useless errors saying things like Wrong number of args passed to <some function> (NO_SOURCE_FILE:0)
1:04 tomoj: GenericUser1: did you compile or just enter the functions into the repl?
1:05 clojure stacktraces seem to me to be generally more cryptic than some other languages
1:05 but your files should show up with line numbers if you do it right (e.g. C-c C-k with slime)
1:05 GenericUser1: At the moment, I'm calling a function in the repl that I loaded from a file
1:05 tomoj: how'd you load it?
1:06 GenericUser1: from the command line (DOS cmd)
1:06 piccolino: technomancy: let me know if I can help at all. Maybe if you put up a pre-built jar I can use that for MacPorts as well.
1:06 GenericUser1: java -cp clojure.jar clojure.lang.Repl model.clj
1:06 tomoj: hmm
1:06 technomancy: piccolino: I'll be sure to announce on the mailing list
1:06 piccolino: Thanks.
1:07 The clojure mailing list, right?
1:07 technomancy: piccolino: yup
1:07 piccolino: k
1:07 technomancy: man... maintainership is a lot easier once you realize you can respond to patches with "this looks great; can you rebase cleanly on top of my latest?" =)
1:07 instead of merging yourself.
1:07 GenericUser1: I also get very cryptic errors when I screw up using derive
1:08 For example, if I do something like (derive :foo :bar) instead of (derive ::foo ::bar), I get the error "Assert failed: (namespace parent) (model.clj:0)"
1:08 tomoj: I don't even get stacktraces or NO_SOURCE_FILE at all with clojure.lang.Repl
1:09 GenericUser1: (Not that I'm any stranger to cryptic errors... I've spent a enough time dealing with templates in C++ ;))
1:10 tomoj: are you happy using the repl from cmd? O_o
1:10 chouser: GenericUser1: (.printStackrace *e)
1:10 technomancy: piccolino: are you the David Santiago that emailed me about this contrib problem, or was that just a random coincidence?
1:10 piccolino: One and the same.
1:10 chouser: GenericUser1: (.printStackTrace *e)
1:10 GenericUser1: I've been going back and forth between cmd and Clojure Box emacs
1:10 But I don't know emacs at all, so emacs is constantly getting on my nerves :)
1:10 technomancy: piccolino: ok cool, I will delete this email then. =) thanks for the heads up.
1:11 piccolino: technomancy: No problem. Just trying to help out a little.
1:11 technomancy: piccolino: yup... too many moving parts right now.
1:11 tomoj: ah
1:11 technomancy: hard to find a moment to sit down and make sense of it all right now though
1:11 piccolino: Yeah, I still can't believe how young clojure is.
1:11 tomoj: GenericUser1: learning emacs is a good investment :)
1:12 GenericUser1: (When I keeping doing things like ctrl-z and it minimizes, and ctrl-f and it just moves forward one character, and ctrl-s and it tries to search instead of save... I get annoyed :p)
1:13 Yes, I know I should learn it, and I'm slowly learning pieces, but years and years of programming in various Windows editors has trained me with lots of things that I haven't yet unlearned.
1:14 *trained me to do lots of things that I havent' yet unlearned
1:14 yay grammar!
1:14 technomancy: unlearning is often harder than learning
1:15 GenericUser1: indeed.
1:18 piccolino: I also think Emacs could make a little more effort to blend in with what have become the widespread UI conventions over the past few decades.
1:18 But then that's why I use Aquamacs.
1:19 * technomancy wishes the past few decades' widespread UI conventions would take a little more effort to learn from Emacs
1:19 technomancy: but that's why I browse with Conkeror. =)
1:20 tomoj: I use conkeror too but I wish it were written in clojure
1:20 been investigating embedding gecko or webkit in java but I can't get anything to work
1:20 GenericUser1: Hrm
1:21 technomancy: tomoj: it's useless without access to the DOM
1:21 very few if any engines expose that in anything other than JS or C++. =(
1:21 tomoj: I would hope javaxpcom gives you that
1:21 GenericUser1: So, I have an agent 'john'... and when I do (@registry (:location @john)), it gives me the result I want, but if I do (-> @john :location @registry), I get the core$deref error
1:22 technomancy: ah... possibly.
1:22 GenericUser1: What am I doing wrong?
1:25 Oh... but if I don't deref registry, then I get it works again.
1:26 tomoj: I bet it's trying to do (deref (:location @john) registry)
1:26 GenericUser1: Hmm... Does that mean that -> treats @registry as (deref registry) and is really doing something like (deref (:location @john) registry)?
1:26 ah
1:27 tomoj: but a ref used as a function automatically derefs itself
1:27 maybe this is why?
1:27 so e.g. you can do just (registry (:location @john))
1:27 GenericUser1: Ah
1:27 tomoj: or even (registry (john :location))
1:28 == (-> :location john registry)
1:28 GenericUser1: So, it auto-derefs a mutability type if it's used as a function?
1:28 I've been wondering about that,
1:28 since if I have something like (:location john), I get nil
1:28 but (:location @john) --> correct answer
1:28 tomoj: I think clojure.lang.Ref implements the interface for functions and invokes whatever the ref points to
1:29 GenericUser1: huh, ok. Thanks.
1:29 tomoj: e.g.:
1:29 (let [foo (ref 3)] (foo))
1:29 ,(let [foo (ref 3)] (foo))
1:29 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
1:30 GenericUser1: I have maps in my refs and agents
1:30 ,(let [foo (ref {})] (foo))
1:30 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentArrayMap
1:30 tomoj: yeah, so invoking a ref/agent to a map will invoke the map
1:30 GenericUser1: ,(let [foo (ref {:a :b})] (foo :a))
1:30 clojurebot: :b
1:30 GenericUser1: there
1:30 ok
1:31 tomoj: also:
1:31 ,@john
1:31 clojurebot: java.lang.Exception: Unable to resolve symbol: john in this context
1:31 tomoj: err
1:32 ,'@john
1:32 clojurebot: (clojure.core/deref john)
1:32 tomoj: so -> sticks the previous value in the middle there and screws things up
1:33 GenericUser1: ,(-> @john :location '@registry)
1:33 clojurebot: (clojure.core/-> (clojure.core/deref john) :location)
1:34 GenericUser1: I'm not really sure what I just did there. O_o
1:35 Where did (clojure.core/deref registry) go?
1:36 ,(quote a b)
1:36 clojurebot: a
1:36 tomoj: you quoted it
1:36 GenericUser1: Ah, I see.
1:37 tomoj: so (quote (deref (:location (deref john))) (deref registry)) I guess
1:37 GenericUser1: I wonder when we'll see an obfuscated clojure contest :P
1:37 Yeah, so quote's dropping the deref registry, and just returning the first thing
1:37 ,(quote (deref (:location (deref john))) (deref registry))
1:37 clojurebot: (deref (:location (deref john)))
1:37 GenericUser1: yep
1:38 tomoj: that is pretty odd
1:40 just found this at imagine27.com
1:40 ,((fn [x] (list x (list (quote quote) x))) (quote (fn [x] (list x (list (quote quote) x)))))
1:40 clojurebot: ((fn [x] (list x (list (quote quote) x))) (quote (fn [x] (list x (list (quote quote) x)))))
1:40 tomoj: hah, crazy
1:40 GenericUser1: O_o
1:40 arsatiki: cool
1:41 GenericUser1: Nice quine.
1:41 chouser: (-> @john :location (@registry))
1:41 tomoj: aha
1:41 chouser: (-> :location (@john) (@registry))
1:42 not sure either of those are better than (@registry (:location @john))
2:41 GenericUser1: What's the proper way to specify custom exception types in clojure?
2:48 tomoj: if you want a custom exception type I think you need to gen-class it
2:49 or proxy
2:49 GenericUser1: I assumed that was the case, but I can't seem to get it to work right. Could you give me a quick example? I keep getting errors about the class not existing.
2:50 tomoj: well gen-class only does anything when compiling
2:55 GenericUser1: How do I compile this then? :P
2:56 If I try to do (compile 'model) I get an error about "can't find the path", and "model.clj" instead of 'model gives a type error (can't cast string), and I can't load the file (Can't find my custom exception class, because it hasn't been generated...)
2:57 At this point, I think it'd be easier to just write the damned exception class in Java :P
2:57 tomoj: well
2:57 what's your classpath?
2:57 G0SUB_: hmm, how do I get new agents to work after I have called (shutdown-agents) once? do I have to re-launch the JVM?
2:58 tomoj: if your file is model.clj, the path to the directory that model.clj is in should be in your classpath
2:58 GenericUser1: I'm just running everything in the same directory at the moment, with the one file model.clj from the command line
2:59 starting the repl with the same command as before;
2:59 tomoj: yes, but is that directory in your classpath?
3:00 GenericUser1: *shrug*
3:01 I don't think I've explictly put it there
3:01 tomoj: if you're doing like -cp clojure.jar, try -cp clojure.jar:.
3:01 GenericUser1: I just tried that, but same thing.
3:01 or actually, I used ;
3:01 I'm on Windows
3:02 : gives me NoClassDefFoundError for clojure/lang/Repl :P
3:03 I think I will just try to write the exception in Java and see if I can load that.
3:04 tomoj: adding . to the classpath didn't help?
3:04 GenericUser1: It didn't seem to
3:04 Unless I am misunderstanding what I was supposed to do after that
3:05 tomoj: (compile 'model)
3:05 that gives some blah blah.clj not found?
3:07 maybe the problem is that you're not supposed to have namespaces with only one segment?
3:07 I dunno
3:07 GenericUser1: java.io.IOException: The system cannot find the path specified (model.clj:5)
3:08 I've tried it with and without namespaces
3:08 tomoj: that's odd
3:08 GenericUser1: (ns model) at the top
3:09 line 5 of my file doesn't make much sense for the error either, since it's just " (dosync "
3:09 Unless :5 is supposed to mean something else ?
3:09 O_o
3:20 Well, I finally got it, using java classes.
3:22 I wrote an empty class 'CantMoveThatDirection' that extended Exception
3:22 put it in package model
3:22 then did
3:22 (import '(model CantMoveThatDirection)) in my model.clj
3:22 keeping CantMoveThatDirection in ./model
3:22 no ns for model.clj at the moment
3:24 I think I've had enough hacking on this for the time being though.
3:24 Thanks for the help. :)
3:24 cya.
4:51 AWizzArd: Moin
4:52 ~max people
4:52 clojurebot: max people is 191
4:52 AWizzArd: oho :)
5:12 elimisteve: I think I've found an error but I'm not certain http://
5:13 At line 6, "user=>" should have shown up but didn't
5:14 Chousuke: elimisteve: I guess your erroneous string just confused the reader :/
5:18 elimisteve: Chousuke: yes but I still think I should get the prompt back after the exception, which is what has been happening until this particular error. More here: http://
5:22 Chousuke: yeah, the reader is a bit weird I guess.
6:06 esj: anybody mind a noob question on lazy sequences and memoization ?
6:06 if I have the following setue
6:06 (def base (atom '[1 2 3 4 5]))
6:06 (defn cumsum [coll]
6:06 (reduce (fn [o, i]
6:06 (conj o (+ (last o) i)))
6:06 '[0]
6:06 coll))
6:07 If I swap! the atom and deref cumsum is the entire lazy sequence reevaluated ?
6:07 say, (reset! base (conj @base 26))
6:07 (nth (cumsum @base) 5)
6:08 and then, in the case of a memoized cumsum, and the same swap! and deref, what is the behaviour ?
6:11 too early in the am I guess.... wake up America !
6:15 adityo: ~max people
6:15 clojurebot: max people is 192
6:21 tomoj: esj: if cumsum is memoized, it will return the cached result whenever you pass in something it's already seen
6:21 since you're passing in a deref'd value, I don't see where the confusion lies
6:21 esj: well, I just want to make sure
6:21 tomoj: if you did (cumsum base), and cumsum was memoized, that would be really bad
6:22 (and derefed inside cumsum)
6:22 esj: yes, I think I understand that
6:22 in the un-memoized case it does traverse the the entire calculation ?
6:24 I was just wondering, in the case of the memoized function, where, under the hood, Clojure noticed that @base was different, and hence the output of the function could be different
6:24 tomoj: naturally
6:24 the memozied cumsum doesn't know it's being passed a deref'd atom
6:24 it only sees the value
6:24 esj: excellent, this is terrific
6:25 tomoj: I don't think there is any auto-memoization
6:25 so if you don't memoize cumsum it will do the full calculation every time
6:25 (as far as I know)
6:25 esj: yeah, i figured it had to, or else it couldn't do the calculation
6:25 tomoj: clojure can't do automemoization like haskell would in some circumstances because clojure doesn't know whether your function is pure or not
6:26 esj: thanks for your help tomoj
6:28 how about something like (last coll)
6:28 how does it know its at the last element ?
6:28 ok, that's a stupid question, I take it back
7:34 avital: ,(+ 2 2)
7:34 clojurebot: 4
7:37 shmichael: Good afternoon I'm studying macros and have a question about the fundamentals. I wrote a simple macro that calls a function during macro expansion. I passed to it a parameter-less function, but it did not get called as expected. The code is as follows:
7:37 ,(defn j [] 0)
7:37 clojurebot: DENIED
7:37 shmichael: (defmacro log [f] (f))
7:38 (log j)
7:38 I recieve an exception: Wrong number of args passed to: Symbol
7:38 AWizzArd: and (f) outputs a list?
7:39 shmichael: no, a value
7:39 AWizzArd: You need to quote that list...
7:39 what if you do `(f) ?
7:39 avital: AWizzArd: I think shmichael wants the macroexpansion of (log j) to be 0
7:39 shmichael: What do you get when you run (macroexpand '(log j))?
7:39 shmichael: avital, you are correct
7:40 avital: I still get the exception
7:40 avital: I'm not sure why it's treating f within the macro as a symbol instead of as a function
7:43 shmichael: If i do: (defmacro log [f] (j)) then the macro expand behaves correctly
7:44 rhickey: a macro gets passed unevaluated forms, so (log j) is passed the symbol j
7:45 shmichael: Is there a way to "unsymbol" it?
7:46 avital: I think eval will work
7:46 something like (defmacro log [f] ((eval f)))
7:46 AWizzArd: When you have (defn j [] 0) and (defmacro log [f] `(~f)) and then call (log j) ==> 0
7:47 avital: AWizzArd: Yes, but the macroexpansion will still return (j) and not 0 as shmichael wants
7:48 shmichael: using ((eval f)) solves the problem
7:49 AWizzArd, avital, rhickey: Thank you
7:49 AWizzArd: Then maybe (defmacro log [f] (let [x# ((resolve f))] x#))
7:49 shmichael: Is resolve preferable to eval?
7:49 avital: AWizzArd: Oh yes, resolve also works, but why not just (defmacro log [f] ((resolve f)))
7:50 ,(eval '(+ 1 2))
7:50 clojurebot: DENIED
7:50 AWizzArd: shmichael: eval is expensive and should only be used when you write code at runtime.
7:50 avital: AWizzArd: His eval is running within a macroexpansion - it happens during compile time so it doesn't really matter
7:52 vy: Clojure complains that "Wrong number of args passed to: user$eval--2371$fn" for (swap! foo #(rand)) while (swap! foo (fn [_] (rand))) works without a problem. Shouldn't `swap!' allow functions with [& rest] arity?
7:53 jdz: RFC http://
7:53 avital: vy: the second arg of swap! must be a function that gets at least one argument i believe
7:53 rhickey: vy: #(rand) is a function that takes no arguments, while (fn [_] (rand)) takes one and ignores it
7:53 avital: I think a function defined as #(rand) implicitly has 0 arguments
7:54 AWizzArd: vy: does (swap! foo #(do % (rand))) work?
7:55 vy: rhickey: I didn't know #() was counting arguments inside its body. Yup, (swap! foo #(let [_ %1] (rand))) works without a problem. Thanks.
7:55 avital: jdz: typo s/cojure/clojure/
7:55 rhickey: vy: (fn [_] (rand)) is much clearer though
7:56 jdz: avital: thanks!
7:59 tomoj: I would say (reset! foo (rand)) is even better
8:59 AWizzArd: rhickey: when I (deref *my-db*) and do this again, and no operations on *my-db* took place (reads are okay), will then = return instantly true?
9:00 that is, do the Clojure datastructures have some kind of version number under the hood that is used by =?
9:11 tomoj: no version number necessary
9:11 the value doesn't need to know it's the value of a ref
9:16 chouser: http://
9:19 tomoj: AWizzArd: but it seems list equivalence, at least, is linear
9:20 chouser: AWizzArd: I believe = on collections starts with 'identical?' so if it's unchanged should be very fast.
9:21 no version numbers in collections
9:21 AWizzArd: ok
9:21 tomoj: seems very fast, but not constant time
9:21 oh, constant if it's the same value
9:21 AWizzArd: ,(let [x (ref {:a 1, :b 2})] (identical? @x @x))
9:21 clojurebot: true
9:21 tomoj: er, identical value
9:22 AWizzArd: In my case x may contain some million k/v pairs.
9:22 And I need a diff. But before running the diff function I would like to see if it is needed.
9:24 tomoj: = on anything starts with java ==, it appears
9:24 so if it's the very same object, it will be very fast, as chouser says
9:24 chouser: AWizzArd: don't use = then. Start with 'identical?' and if that fails then just do your diff.
9:24 tomoj: no need, I think
9:25 clojure/lang/Util.java L19 does this, it seems
9:26 chouser: yes, but if they're not identical it'll go off on a full walk of the collection looking for a difference (though I suppose it will short-circuit when it finds one)
9:26 any work it does there would be a waste, since the diff will have to do it again anyway
9:28 tomoj: ah, yes
9:28 I had this idea that collections kept some sort of hash or something so that non-identical but same-valued collections could be compared for equality quickly
9:28 I wonder where I got that idea, because it seems totally wrong
9:29 AWizzArd: 99.9% of the operations on *my-db* are reads. So, an extremly fast check for equality is helpful. identical? does the job, good.
9:29 And what is the L19 thing tomoj?
9:29 tomoj: basically = does an identical? check before it starts crawling the collection
9:30 AWizzArd: yes, i could use =, but it won't give me more information than a boolean value.
9:30 tomoj: I just meant that = is already fast on identical objects
9:30 AWizzArd: The only danger is that they are not identical.
9:31 tomoj: right
9:31 AWizzArd: while a full check is perfectly fine when the map contains a few hundred elements it may not be so nice if it needs to crawl through 5gb of data.
9:31 although this might average out on 2.5 gb then
9:32 tomoj: damn
9:33 what the heck are you doing with all that in memory?
9:34 AWizzArd: It's the db.
9:34 a 12 gb server costs only 100 Euro per month
9:34 ambient: im wondering if I'm doing something wrong when im implementing my own type-system
9:35 AWizzArd: Why should I use a lame sql db system when I can have everything in-ram and in Clojure? :-)
9:35 ambient: somehow mixing multimethods and macros could also work
9:35 tomoj: AWizzArd: the D in ACID?
9:35 AWizzArd: tomoj: full snapshots written on disk + transaction log.
9:36 tomoj: did you hack clojure's STM?
9:36 I didn't think that was possible
9:36 AWizzArd: Why hack?
9:36 tomoj: are you using watchers to write the snapshot?
9:37 AWizzArd: no
9:37 tomoj: when, then?
9:37 AWizzArd: you can have a (dosync ...) and then deref all your toplevel vars that contain the data.
9:37 This can be done within a millisecond. Then I have snapshots, and one agent can write them out to disk.
9:37 tomoj: sure, but if the plug is pulled after the dosync but before the snapshot is written? :)
9:37 AWizzArd: Clojure supports Multiversion Concurrency Control.
9:38 tomoj: transaction log
9:38 tomoj: same problem
9:38 fro0g: maybe slightly OT, but how does the IBM and Sun JVM compare?
9:38 AWizzArd: same with the db
9:38 a relational db system may also have the problem
9:38 tomoj: no, mysql for example is really ACID
9:39 AWizzArd: i can wait until my data is on disk for a transaction and only then proceed
9:39 but even mysql won't write it out and then check if everything was written correctly
9:40 it will pass the data to the disk controller, and when the controller has some time and is in the right mood, it will write out the data.
9:40 After the data was given to the controller there could be an electrical cut
9:41 tomoj: well
9:41 I don't actually know shit about mysql internals
9:41 AWizzArd: If I wanted I can write out to disk, read it back in and see if all arrived and only then proceed.
9:41 tomoj: but there are certainly some databases that are ACID compliant
9:41 no, you can't
9:41 AWizzArd: yes, mine :)
9:41 tomoj: because once the transaction completes, other readers will be able to read
9:41 unless you're single threaded?
9:42 AWizzArd: i don't have to update the main ref
9:42 chouser: need a disk sync or close the file between write and read or the OS will trick you
9:42 tomoj: otherwise you've got to have a lock that says "hey you can't read this yet because I haven't made sure it's on disk"
9:42 AWizzArd: The db has a version number. The server takes a snapshot and remembers its current version.
9:42 The server operates on the snapshot and only writes data back when needed to the global db.
9:42 All other readers would get the old version.
9:43 I can have many snapshots and then atomically update the db when all data arrived on disk.
9:43 snapshotting the whole db will take 1 msec
9:43 and this is not needed if the version number is still the same
9:43 also I said, 99% of the operations are reads
9:44 And those are much nicer with an in-ram db.
9:44 tomoj: yeah
9:44 guess you don't need fancy relational crap?
9:44 AWizzArd: query language: Clojure
9:44 right, I want Clojure objects
9:45 I don't say that my usecase is the right thing for every db job out there.
9:45 tomoj: is this open source? :)
9:45 AWizzArd: But it works for me.
9:45 No, not yet, but maybe next year.
9:45 tomoj: ah
9:45 I had one project where I wanted a whole bunch of clojure objects in memory all the time
9:46 AWizzArd: It can be nice for *some* apps. I don't say that my solution is the silverbullet and will revolutionize how apps are written. For me it works.
9:46 tomoj: hmm.. though now that I think about it after learning some couchdb, maybe couch would be better
9:46 I wonder how far I can push couch's mapreduce without making it explode
9:47 my project is also almost entirely reads
9:48 writes are like a whole bunch twice a year and then a tiny trickle the rest of the time
9:48 and for the two big writes a year, no one's reading while that's happening
9:49 maybe I should just keep it all in memory after all
9:49 AWizzArd: It's nice in those cases to not send requests over a socket, but instead just doing a hashmap lookup and have the final object delivered.
9:49 tomoj: I wonder, how long does it take to start up, though?
9:49 I mean, to read in the db from the snapshot on disk?
9:50 AWizzArd: This depends on many factors. If there is just one snapshot, without a transaction log, then the snapshot is read via (read).
9:51 The Clojure reader reads it in and everything is at the right place.
9:51 tomoj: I wonder how long (read) takes to read a GB or so
9:51 AWizzArd: You could write a hashmap to disk {1 1, 2 2, 3 3, ...} and try it.
9:52 tomoj: I don't have any spare ram here, I'll try when I get to my bigger computer
9:52 you should write a blog post or something about your system if it's not secret :)
9:57 AWizzArd: I think in-ram DBs will get more interesting, now that 4gb bars cost just 200 Euros.
9:57 Especially with Clojure it is so very cheap to work with snapshots.
9:58 rhickey basically solved the hardest parts of the problem already.
9:58 chouser: I still think it would be interesting to have a diff algorithm that exploits the internal tree structure of the collections
9:59 AWizzArd: Yesss
9:59 sounds very useful
10:00 chouser: this has been discussed before. one significant question is what this "diff" would look like -- how to capture all possible values and also describe dissocs
10:02 tomoj: maybe if I understood the trees clojure uses I would understand why that's useful
10:13 chouser: tomoj: http://
10:14 tomoj: thanks
10:15 rhickey: hack of the week: http://
10:16 all host interop uses reflection. but method bodies in defclass* need to do host interop with themselves and instances of their own class, which doesn't exist yet
10:17 so, first generate a stub class that derives from the same interfaces and has same fields, but does nothing, hint 'this' to the stub, lop off stub prefix in generated bytecode
10:17 chouser: ahaha
10:18 AWizzArd: hmm
10:18 oh
10:18 chouser: compile-time reflection lives on!
10:18 lisppaste8: rhickey pasted "look ma, no reflection" at http://
10:19 rhickey: chouser: it won't in cinc, but changing the Java was just too much to take on now
10:20 but note that all of the auto-interface implementing can happen in defclass and deftype macros, not in Java
10:20 chouser: would it also have worked to create an object that implements the reflection interface and pretends to be like this stub?
10:20 rhickey: chouser: you can't because there are no interfaces for the reflection classes (Method etc), nor can you create instances of them!
10:21 chouser: gah. ok.
10:21 rhickey: the evils of concrete classes
10:21 chouser: in that paste you hinted 'this' in toString, but that's not necessary, right?
10:22 rhickey: right, not needed just a test
10:22 chouser: I think you said previously that cinc would use info from .class and .jar files instead of compile-time reflection. Is that still the plan?
10:22 rhickey: so the simple name of the class being defined will be an alias for the class being defined, in type hints, instance? etc
10:22 chouser: ah, right, so you can do #^Foo other
10:23 rhickey: chouser: it will use a Clojure-based representation of type info, disconnecting it from its source
10:23 #^Foo other, and self-type ctor calls will be very important
10:23 chouser: ok, so it might use .class files, reflection, or a stub like this as needed
10:24 well, not exactly like this, but info generated on the fly to solve this problem.
10:24 rhickey: chouser: exactly
10:25 tomoj: I wonder how many tech talks are as philosophical as rhickey's. enjoying http://
10:25 rhickey: so all that's left on the Java side is: needed - deal with return type covariant bridges, planned - a true switch construct
10:26 with the former, definition of deftype and defclass macros can proceed, the latter will be used to optimize field lookups
10:27 but will be a generally awesome object-based switch, useful with any constant objects like strings/symbols/keywords
10:27 chouser: the latter will be a implementation detail performance improvement, so is not blocking progress.
10:27 rhickey: chouser: right
10:28 chouser: so does that mean you're nearly out of excuses for avoiding the bridge methods?
10:28 rhickey: first impls of lookup as simple as: (valAt [k] (condp identical? k :a a :b b :c c))
10:28 chouser: I have the same excuse, pain, but nothing else to do first :(
10:30 defclass will be so much better than Java at (the better part of) Java
10:34 AWizzArd: Can I type-hint something as (primitve) bool?
10:34 rhickey: boolean
10:34 AWizzArd: thx
10:46 djork: defclass scares me
10:46 it seems like it might encourage people to write Java-style OO in Clojure
10:48 chouser: if they don't understand how to use the power of multimethods, they'll just use them to dispatch on the type of the first arg anyway
10:49 Chousuke: can you actually define your own methods with defclass? or just the stuff that the interfaces define?
10:53 * Licenser is excited, got his copy of programming clojure today :D
10:53 AWizzArd: djork: this OO style is not always very bad. And the alternative would be to use structs and dispatch on a :type slot. But this is not anywhere as efficient.
10:53 Chousuke: djork: I don't think you need to worry about that. As far as I can tell, you can only define immutable "data packages" and all the operations will actually be defined outside the class (as interfaces or protocols)
10:53 djork: so it's more for Java-Clojure interaction
10:54 Chousuke: djork: so it's not much like java at all. :P
10:54 djork: i.e. integrating Clojure with existing Java code
10:54 chouser: no, it's for high-performance Clojure
10:54 AWizzArd: For example, if you want to write a tokenizer, then in a production environment it would have to create millions of small token objects. This will be extremly much faster with simple native Java classes.
10:54 Licenser: will there be High Availability Clojure te?
10:54 to
10:54 AWizzArd: what chouser said
10:58 djork: AWizzArd: I'm not sure I understand. Why would creating a class address that tokenizing problem better?
10:58 Chousuke: djork: the object will be a lot smaller than a structmap instance.
10:58 djork: hmm
10:58 Chousuke: djork: and thus faster to create
10:58 djork: I see
10:59 well I'm all for a better Java than Java, and defclass appears to achieve that, but it just feels like *more Java* whereas the feeling I got from Clojure was *less Java*
10:59 Chousuke: I don't think it's so much about java than giving Clojure it's own way of defining such simple data structures
11:00 defclass should be fairly portable to any non-java host too.
11:00 its*
11:00 tomoj: the value-identity-state presentation makes me think that representing a directed graph as a bunch of refs which have lists of refs as their children is probably a bad idea
11:00 need to find a good persistent way to represent graphs
11:01 steiger: tomoj: why not use persistent hashmaps?
11:01 AWizzArd: Actually I wrote a lexer and use a Clojure struct. But my tokens are throw-away objects, only needed for the parser. I then exchanged the token struct with a Java class Token and it got a great speedup, because instantiation was much faster.
11:01 tomoj: steiger: because the graphs might have cycles
11:01 steiger: tomoj: if you ask me, i'd say it's a simple and elegant way to represent graphs. most importantly, simple
11:01 tomoj: so what?
11:01 Chousuke: tomoj: map of nodes to sets of nodes?
11:01 djork: so structmaps are slow
11:01 because they are generic
11:02 tomoj: so if there's a cycle... it won't work
11:02 :)
11:02 maybe I'm confused
11:03 Chousuke: tomoj: give each node an unique identity that you use as the key?
11:03 steiger: tomoj: {:1 [:2 3] :2 [:1]} . that would be a graph with a cycle
11:03 tomoj: Chousuke: yeah I guess that would work
11:04 and then you have to look up the data for a node in a separate place I suppose
11:04 Chousuke: yeah. or you can have {:1 [thenode #{:2 :3}] ...}
11:05 tomoj: oh, and then to get a node's child you just look up the key and take first, I see
11:05 oh, except I need data on edges too, hmm
11:06 {:1 [thenode theedge #{:2 :3}] ...} ?
11:06 no.
11:06 {:1 [thenode #{[anedge :2] [anotheredge :3]}] ...}
11:07 steiger: simple, eh? :)
11:07 Chousuke: hmm, that's not so easy to look up :/
11:07 steiger: tomoj: modeling graphs in computers needs planning. get a chalkboard and _think_ . it's pretty cool, designing that kind of stuff
11:07 tomoj: pretty easy when persistence isn't desired, I think
11:07 I was thinking of finding some papers on graphs in haskell and porting stuff
11:08 Chousuke: if you need that then {:1 [node-data {:2 edge-data12 :3 edge-data13}]}
11:08 AWizzArd: djork: struct maps are Persistent and offer a great bunch of features. Java classes don't.
11:08 steiger: tomoj: when i was doing a little graph library, i used {:node1 #{:node2 :node}} .... and i could add data about edges and node using metadata.
11:09 tomoj: hmm, that's an interesting idea
11:10 steiger: tomoj: something like: (def make-graph [graph] (something-to-check-the-entry-is-valid) (something-to-add-the-desired-metadata))
11:10 but, of course, there are tons of other ways to do that
11:10 that = represent graphs ;]
11:11 tomoj: I feel like my node/edge data doesn't really belong in metadata in principal, but it sounds simple to work with
11:11 s/principal/principle/
11:12 much better than the mess of refs pointing to refs pointing to refs I've got now
11:13 steiger: tomoj: yeah, i think refs are unnecessarily complicated to this kind of job
11:13 tomoj: huh there is a clojure.contrib.graph
11:13 steiger: tomoj: yeah... the approach clojure.contrib.graph uses is quite interesting, have a look
11:13 quite creative
11:14 tomoj: but don't give up, try to develop your own, too. clojure.contrib.graph has it's limitations ;]
11:17 duncanm: if i wanna have write a GUI project that can build into an executable JAR, but still get to implement it incrementally using SLIME, that means i'll have to write both an ant script and some sort of load script in Clojure, right?
11:19 tomoj: fns for children, creative indeed
11:22 ambient: duncanm i can develop swing apps perfectly fine with Emacs, just don't add any functionality to terminate the process when the window closes
11:22 duncanm: ambient: and when it comes time to deploy?
11:22 ambient: *shrug* :)
11:22 im sure i can make the whole thing a single JAR in that moment
11:23 duncanm: ambient: do you write all your code in a single file?
11:23 ambient: depends, how large it grows
11:23 i see no problem in deviding different functionality into their own files
11:24 duncanm: ambient: then how would you load it using emacs, other than writing some load script that calls load-file
11:24 ambient: you just call a function like (start-gui) and call dependencies in the file beginning like (ns my.gui.stuff (:use my.gui.stuff2)
11:25 duncanm: ah, that's another way, cool
11:25 tomoj: duncanm: curious, are you using swank-clojure-project?
11:26 duncanm: tomoj: i don't know of it
11:26 tomoj: you have clojure-mode?
11:26 duncanm: tomoj: i do, and i have SLIME
11:26 tomoj: then you should have either a swank-clojure-project or a clojure-project function
11:27 duncanm: tomoj: M-x shows me only swank-clojure-import
11:27 tomoj: ah, you probably need to upgrade
11:27 clojure-project is from the emacs-starter-kit I guess
11:27 duncanm: oh, i installed it using ELSA
11:27 ELPA
11:28 tomoj: well, if you upgrade, it makes it really easy
11:28 you put all your dependency jars (including clojure.jar and clojure-contrib.jar) into lib/
11:28 and all your source clj files into like src/com/foo/bar/baz.clj for ns com.foo.bar.baz
11:28 and then swank-clojure-project sets up the classpath and everything for you
11:29 unless you like managing the classpath manually, then that would just be annoying, I guess
11:29 duncanm: tomoj: i think i have the latest version of clojure-mode
11:29 tomoj: "latest" = from git?
11:29 duncanm: i think so
11:29 latest is 1.5
11:30 but i don't have emacs-starter-kit
11:30 tomoj: oh, swank-clojure-project is from swank-clojure
11:30 you need to update swank-clojure I guess
11:31 if you don't use anything besides clojure and clojure-contrib, I guess it provides no benefit
11:32 duncanm: tomoj: i can't find this, i have the latest swank-clojure from GIT
11:33 ahh
11:33 i see that defun now
11:33 tomoj: \
11:35 steiger: seems if you use metadata you either end up keeping a map with node ids as keys or using a vector to hold the node data anyway
11:36 unless maybe you can ask a map to give you a certain key?
11:39 if you go with chousuke's representation above, then getting all the incoming edges for a node is slow, you have to search the whole graph :(
11:45 ysmolsky: i have kinda dumb question. slime gives me cool auto-completition. is there a way to get such functionality for usual clojure edit buffer? i mean abbr works okay and all, but completition for java would be great.
11:47 tomoj: ysmolsky: if you figure it out let me know
11:47 :)
11:49 duncanm: tomoj: i don't get how M-x clojure-project works
11:49 ysmolsky: i see :)
11:49 duncanm: it wouldn't let me type at the Project Root prompt
11:51 yuras: tomoj: anyway, are you satisfied with abbr completition you have for clojure atm? ;)
11:52 tomoj: I don't have abbr completion
11:52 duncanm: tomoj: ahh, i'm using swank-clojure from someone else's github
11:52 tomoj: or if I do I don't know how to use it
11:52 duncanm: I use technomancy's
11:52 I believe it's swank-clojure-project nowadays
11:52 duncanm: right
11:52 i have jochu's
11:52 tomoj: if it won't let you type maybe you don't have ido working?
11:53 yuras: you should update all kind of modules like, slime, swank-clojure and clojure-mode
11:53 actually i make it work when i used clojure-install command from clojure-mode
11:53 it downloads all needed deps and configure things
11:55 duncanm: hmm
11:55 i have emacs 23 on windows
11:55 swank-clojure-project isn't working, or i don't know how IDO works
11:59 tomoj: how do you accept the project root?
11:59 that's my project right now
12:00 s/project/problem/
12:00 tomoj: type to the root of your project and press enter
12:00 e.g. I type ~/clojure/foo-project/ RET
12:00 maybe it doesn't allow you to choose that directory if it's not set up right
12:00 you should have a lib/ and src/ directory at minimum
12:01 and clojure.jar (and maybe clojure-contrib.jar) need to be in lib/
12:02 duncanm: tomoj: enter isn't working
12:02 it's something to do with locate-dominating-file
12:02 RET isn't working
12:04 tomoj: someone else had a problem like that before
12:04 didn't hear a solution
12:04 I think I have emacs 23 somewhere around here, I'll try it
12:05 (not windows though)
12:07 duncanm: tomoj: i took out the IDO part and now it works
12:07 maybe ido-* is broken on windows
12:08 tomoj: sounds terrible
12:08 unless you have a replacement, I guess
12:09 duncanm: hmm
12:09 swank-clojure-classpath's value is
12:09 ("c:/Projects/FileMonitor/src/" "c:/Projects/FileMonitor/lib/clojure-contrib.jar" "c:/Projects/FileMonitor/lib/clojure.jar" "c:/Projects/FileMonitor/lib/ij.jar" "c:/Projects/FileMonitor/test/")
12:09 so that's correct - but when i try to load a file (C-c C-l) it still couldn't find it
12:09 tomoj: what file did you try to load
12:09 also try C-c C-k instead
12:10 duncanm: i have src files under "c:/Projects/FileMonitor/src/"
12:10 but it couldn't see them
12:10 tomoj: a file that defines the namespace foo.bar.baz should be in src/foo/bar/baz.clj
12:10 duncanm: yeah, i have that
12:10 and it's saying it couldn't find foo.bar.baz
12:11 tomoj: well, C-c C-l works fine for me, strange
12:11 but try C-c C-k in a source buffer I guess?
12:11 duncanm: same deal
12:12 tomoj: C-c C-l works fine without swank-clojure-project?
12:12 duncanm: yeah
12:12 well, i didn't use the ns feature before
12:12 tomoj: that doesn't make sense to me
12:13 since it's doing the same thing it was doing before, swank-clojure-project just sets the classpath... /shrug
12:13 duncanm: and my listing of swank-clojure-classpath looks correct?
12:13 tomoj: yep
12:13 duncanm: if i have files c:/Projects/FileMonitor/src/com/example/Foo.clj
12:14 ambient: i use small text in clj files, like "foo.clj" myself
12:14 tomoj: I wouldn't think that would matter
12:15 duncanm: hmm
12:15 tomoj: what is the exact error when you C-c C-k
12:15 duncanm: tomoj: if i print out the classpath, it doesn't include my project dir
12:15 user> (println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))
12:15 (#<URL file:/C:/Users/Duncan/.jars/clojure.jar> #<URL file:/C:/Users/Duncan/git/swank-clojure/src/main/clojure/> #<URL file:/C:/Users/Duncan/git/swank-clojure/src/main/clojure/> #<URL file:/C:/Users/Duncan/.jars/clojure-contrib.jar> #<URL file:/C:/Users/Duncan/git/fiji/ImageJA/ij.jar>)
12:15 tomoj: did you kill your old slime repl before doing swank-clojure-project?
12:15 duncanm: lemme start from scratch
12:15 sigh, i'll restart emacs
12:15 tomoj: you need to ,sayoonara
12:16 swank-clojure-project wants to start a new repl and a new java process
12:16 duncanm: dum de dum
12:16 still no go
12:18 oooh
12:18 i was doing :use, maybe i should use :refer instead?
12:18 tomoj: :use should be fine
12:18 duncanm: tomoj: what did you suggest earlier? when i talking about load scripts?
12:18 tomoj: anyway that definitely doesn't matter if it can't even find the file
12:19 duncanm: oooh
12:19 i see this problem, maybe
12:19 when i do C-c C-k, the top of the output says
12:19 ambient: duncanm i got emacs 23 on windows and i do this in my .emacs: (dolist (d (list "c:/code/clj/penumbra/src" "c:/some/more/stuff")) (add-to-list 'swank-clojure-classpath d))
12:19 duncanm: cd c:/Projects/FileMonitor/src/edu/harvard/connectome/
12:20 so maybe it's going too deep into the directory tree
12:20 Unknown location:
12:20 error: java.io.FileNotFoundException: Could not locate edu/harvard/connectome/DownsampleImages__init.class or edu/harvard/connectome/DownsampleImages.clj on classpath: (FileMonitor.clj:1)
12:20 ahhh
12:20 ambient: sounds like the problem is in the classpath and how to set it right
12:21 tomoj: and you have a src/edu/harvard/connectome/DownsampleImages.clj?
12:21 duncanm: yeah
12:22 tomoj: then your classpath seems fine to me
12:22 maybe swank-clojure is setting it in the linux way
12:23 or some other windows problem is happening
12:23 I think those libraries are not tested much on windows
12:23 duncanm: (ns edu.harvard.connectome.FileMonitor
12:23 (:import (javax.swing JFrame SwingUtilities))
12:23 (:use DownsampleImages DownsampleXML)
12:23 (:gen-class))
12:23 ambient: is it a windows problem when a software assumes that there's a UNIX-like filesystem? ;)
12:23 duncanm: that's what i'm doing now
12:23 ambient: i always use the full name in :use, like amb.synth.engine etc..
12:24 hiredman: ambient: Yes.
12:24 tomoj: yes, try with the full name
12:24 Chousuke: the naming isn't very idiomatic either :/
12:24 duncanm: oooh
12:24 tomoj: you can use a prefix for having two of them
12:24 duncanm: okay
12:24 tomoj: so if i have edu.harvard.connectome.DownsampleImages, then that works
12:25 aha, now it works
12:25 tomoj: like {:use [edu.harvard.connectome DownsampleImages DownsampleXML]) I believe
12:25 Chousuke: usually a list, but either works
12:25 tomoj: and, yeah, we use lisp-case around here, not CamelCase :P
12:26 duncanm: seems like the only case that works is the full name, with no spaces
12:26 i don't mind having n lines of :use's
12:26 tomoj: oh, I think it's like
12:26 well, hmm
12:27 (:use (edu.harvard.connectome DownsampleImages DownsampleXML)) should work, right?
12:27 duncanm: tomoj: i like using lisp-case too, but i can't name my files that way, before DownsampleImages, it was downsample-images
12:27 tomoj: yeah, but that precisely did not work
12:27 tomoj: you can't name files using hyphens?
12:27 gerry_: hello
12:27 duncanm: i supposed i could have foo-bar, but then the filename needs to be foo_bar.clj
12:27 tomoj: why not foo-bar.clj?
12:28 duncanm: tomoj: it wouldn't find it
12:28 hiredman: tomoj: - is not legal in classnames
12:28 gerry_: will datatypes support inheritance just like oop?
12:29 tomoj: hiredman: nor package segments?
12:29 it certainly is.. clojure.contrib.repl-utils for instance
12:29 Chousuke: gerry_: what would you inherit? the fields? :P
12:29 hiredman: tomoj: the file is named repl_utils.clj
12:29 duncanm: ambient: so the key thing is not to use setDefaultOperation and make it EXIT_ON_CLOSE?
12:29 tomoj: hiredman: ah, I see
12:29 gerry_: chousuke: fields and methods
12:30 hiredman: clojure maps '-' in namespaces to '_' in file names
12:30 tomoj: good to know
12:31 duncanm: nice, now i can do the work in SLIME, and still build it into a jar with netbeans
12:35 gerry_: Chousuke: if i want add fields to some datatypes been defined?
12:35 Chousuke: hmm.
12:37 ambient: duncanm yes, i dont do that generally
12:37 duncanm instead i make my own window close listener and bind any operations i want to do into that
12:37 Chousuke: well, the classes won't have any methods, and can apparently only implement interfaces.
12:37 so you wouldn't be able to use defclass to derive from another class.
12:38 gerry_: Prototype-based oop such as javascript or Io seems not bad
12:38 Chousuke: any methods besides the ones the implemented interfaces require, that is.
12:38 The-Kenny: I want a port of CLOS to clojure :)
12:38 tomoj: why would we want prototype based oop?
12:38 Chousuke: clojure already has that anyway :P
12:38 just put stuff in maps :P
12:39 gerry_: hmm
12:40 ambient: i dont just use maps for classes, i also use them for type system :|
12:40 gerry_: can i just assoc datatype to get new datatype?
12:40 or something like this?
12:49 chouser: you could use macros to assemble larger datatypes out of smaller pieces.
12:54 duncanm: ambient: ping?
12:54 ambient: ack
12:55 djork: I bet this question has been beaten to death, but: rhickey: what kind of setup do you use to write Clojure code?
12:55 duncanm: ambient: i'm trying to redirect System.out to a JTextArea, and i'm just translating Java code to Clojure, but it's not working
12:55 djork: he uses emacs and clojure-mode, no slime
12:56 ambient: duncanm hmm well i've never done that. if it were me i'd just add a function that writes some more stuff into the JTextArea.
12:56 i dont know what you're trying to do
12:56 drewr: djork: he uses emacs+clojure mode
12:57 whoops, didn't see duncanm's response
12:57 duncanm: ooh
12:57 djork: cool
12:57 drewr: promise!
12:57 djork: (glad there's so many rhickey fans in here):)
12:58 drewr: while we like rhickey, we're not so much fans of him as his work (which I think he prefers)
12:59 rys: I'm a big fan of his hair
12:59 But mostly Clojure
12:59 arsatiki: it must be nice to have a name like his, because then you never feel poor
13:01 djork: indeed
13:05 Kjellski: Hi there =)
13:09 djork: Kjellski: howdy
13:09 how's the learning going?
13:09 I have been playing with your bacteria problem
13:10 without great success, I might add
13:10 notallama: i don't think i could easily go back to no slime.
13:11 Kjellski: ... still problems with recur... but I´m trying hard... got time to look at a snipped``
13:11 ?
13:11 It´s not that easy right?
13:11 djork: sure
13:11 :)
13:13 Kjellski: http://
13:13 =)
13:14 My problem is, that the populate should be called with an initially population and an initial day... like (populate [1] 1) ... but it will never stop... blowing the jvm...
13:14 djork: yeah
13:14 Kjellski: nevermind the doalls in that other function ^^
13:16 djork: heh
13:16 Kjellski: C´mon, tell me...
13:21 falkor: Hi, Here is a silly question from a newbie: How can I execute a LazySeq (ie, make it a IFn)?
13:22 Kjellski: You mean, get all values out?
13:22 That would be a (doall lazy-seq)
13:22 falkor: let me try...
13:23 Kjellski: But be carefull with infinite definitions... ^^ they last long...
13:28 qed: im having some trouble understanding iteration in clojure
13:28 i see these combinations of loop, recur, inc, dec, iterate, etc.
13:29 djork_: oops
13:29 qed: how do i make the basic example of two nested for loops
13:29 djork_: Kjellski: out of memory on 100th day
13:30 Kjellski: djork : damned ^^ got something running that´s not working... and we need some not stack consuming construction with letfn or so!?
13:31 djork_: something like that
13:31 proper tail-recursion would do the trick
13:31 although I ran out of heap not stack
13:31 Kjellski: Just combine, like (for [a b] (for [c a] ... )) ?
13:31 @ qed
13:32 djork_: Kjellski: I think he means nested for loops in another language
13:33 like two Java for loops
13:33 qed: im trying to decrement from 999, and increment from 901
13:33 djork_: in Clojure for creates a seq
13:33 and it also binds multiple seqs to iterate over
13:33 ,(doc for)
13:33 clojurebot: "([seq-exprs body-expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost fastest, and nested coll-exprs can refer to bindings created in prior binding-forms. Supported modifiers are: :let [binding-form expr ...], :while test, :when test.
13:33 qed: it's one of the euler problems where i need to try combinations of multiplying 3 digit numbers
13:33 The-Kenny: qed: Show an example in some pseudocode.
13:35 djork_: ,([x (range 1 10) y (reverse (range 1 10))] [x y])
13:35 clojurebot: java.lang.Exception: Unable to resolve symbol: x in this context
13:35 djork_: oops
13:35 ,(for [x (range 1 10) y (reverse (range 1 10))] [x y])
13:35 clojurebot: ([1 9] [1 8] [1 7] [1 6] [1 5] [1 4] [1 3] [1 2] [1 1] [2 9] [2 8] [2 7] [2 6] [2 5] [2 4] [2 3] [2 2] [2 1] [3 9] [3 8] [3 7] [3 6] [3 5] [3 4] [3 3] [3 2] [3 1] [4 9] [4 8] [4 7] [4 6] [4 5] [4 4] [4 3] [4 2] [4 1] [5 9] [5 8] [5 7] [5 6] [5 5] [5 4] [5 3] [5 2] [5 1] [6 9] [6 8] [6 7] [6 6] [6 5] [6 4] [6 3] [6 2] [6 1] [7 9] [7 8] [7 7] [7 6] [7 5] [7 4] [7 3] [7 2] [7 1] [8 9] [8 8] [8 7] [8 6] [8 5] [8 4] [8 3] [8 2
13:35 ambient: is there any performance difference between (let [foo 1 bar 2] ...) and (let [foo 1] (let [bar 2] ...)) ?
13:35 djork_: sorry, too many for an example :)
13:36 ,(for [x (range 1 3) y (reverse (range 1 3))] [x y])
13:36 clojurebot: ([1 2] [1 1] [2 2] [2 1])
13:36 qed: (loop (for n=999; n < 901; n-- (for k=901; k<=999; k++ ( test-if-this-is-palindrome(n*k)))))
13:36 i know i dont need that loop, but id like to use special forms instead of for loops
13:36 like fn/loop/recur
13:36 The-Kenny: qed: I think for is the thing you need.
13:36 chouser: ambient: I think those produce the same bytecode
13:37 ambient: chouser thanks
13:37 qed: so it will multiply 999*901, 998*902, 997*903, etc.
13:38 Kjellski: maybe this works for you? (for [n (reverse (range 901 999)) k (range 901 999)] (test-palin (* n k)))
13:39 qed: Kjellski: where do you close the [
13:39 before the k?
13:40 oh nevermind
13:40 Kjellski: ;9
13:40 qed: im getting used to this whole [] thing
13:40 you are defining sequences within []
13:40 Kjellski: if you need, you could also place some commas in there, they are interpreted just like spaces...
13:40 That´s it!
13:41 chouser: ,(loop [i 5, v []] (if (zero? i) v (recur (dec i) (loop [j 5, v v] (if (zero? j) v (recur (dec j) (conj v [i j])))))))
13:41 clojurebot: [[5 5] [5 4] [5 3] [5 2] [5 1] [4 5] [4 4] [4 3] [4 2] [4 1] [3 5] [3 4] [3 3] [3 2] [3 1] [2 5] [2 4] [2 3] [2 2] [2 1] [1 5] [1 4] [1 3] [1 2] [1 1]]
13:41 qed: so could i also do: (for [n (range 901 999)] (for [k (999 901)] (test-valid n*k)))
13:41 The-Kenny: I think he could also use the :when keyword
13:42 chouser: but you rarely need such nastiness. use 'for' if it'll do for you.
13:42 Kjellski: With a range in the k thing?
13:42 falkor4: argh.... network problems
13:42 djork: for + range = bliss, honestly
13:42 I see no need to do it recursively
13:42 falkor4: Sorry, I just lost track of the previous conversation
13:43 Does anyone has any idea on how to execute a LazySeq?
13:43 Kjellski: ,(doc doall)
13:43 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time."
13:43 djork: falkor4: you can use doall doseq, etc
13:43 there's another one that doesn't retain the head
13:44 dorun
13:44 ,(doc dorun)
13:44 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil."
13:44 djork: (testing...)
13:44 ~dorun
13:44 clojurebot: Pardon?
13:45 qed: how do i only print (* n k) when reverse-and-test is true?
13:45 right now this loop tests those combinations, but just prints a ton of falses for me
13:45 The-Kenny: qed: Add a :when and the predicate afterwards to the binding-list
13:46 (I was trying to suggest this, but emacs doesn't let me copy the text...
13:46 Kjellski: The-Kenny : /agree
13:46 The-Kenny: qed: Like (for [a (range) b (range2) :when #(is-prime? (* %1 %2))] (* a b))
13:47 qed: why the lambda?
13:47 The-Kenny: Because my fictional is-prime? takes one argument
13:47 and for passes both arguments to the fn
13:48 somnium: you can also use a let binding before when
13:48 it makes it more readable sometimes
13:48 falkor4: As an example, if I do (let [x (concat '(println) '(1))] (doall x))
13:48 I get nothing
13:48 somnium: :let [z (* x y)] :when #(is-prime? z)
13:49 qed: somnium: this is inside the for loop?
13:49 somnium: yup
13:49 qed: in the binding of the foor loop
13:49 The-Kenny: Wow, I didn't know :let is supported there. Cool :)
13:49 qed: for loop
13:49 ok
13:49 somnium: clojure's list comprehensions are amazing
13:49 destructuring everywhere to boot
13:49 The-Kenny: qed: The last thing will only get executed if the predicate after :when is true.
13:50 (Forgive me... my english isn't very good ;))
13:52 qed: okay i think i got this working
13:52 now the only thing left is, i get it to print all trues, how do i get it to print the output from * n k, when it's true
13:52 more :when code?
13:52 The-Kenny: qed: Show what you have now.
13:52 somnium: ,(doc complement)
13:52 clojurebot: "([f]); Takes a fn f and returns a fn that takes the same arguments as f, has the same effects, if any, and returns the opposite truth value."
13:52 The-Kenny: qed: For returns a list. You could just print this sequence.
13:53 qed: (for [n (reverse (range 100 999))
13:53 oops, let me pastie this
13:57 http://
13:58 ^^That's what I have so far
13:58 it prints every instance where reverse-and-test is true
13:58 The-Kenny: qed: Just remove the reverse-and-test just before the last )
13:58 (Just (* a b) in the body)
13:59 The last part of the for will get executed for each element where the :when-predicate returns true and the result of the call is added to a list
13:59 qed: how does apply work?
14:00 like (apply max (for...))
14:00 ,doc apply
14:00 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/doc
14:00 hiredman: ~def apply
14:00 The-Kenny: Apply takes a fn and a list and will apply the elements of a list to the fn.
14:00 (apply max [1 2 3 4 5 6]) == (max 1 2 3 4 5 6)
14:00 hiredman: nice
14:00 nginx 404
14:01 qed: So what does my for loop return to us then? a seq?
14:01 The-Kenny: Yes
14:01 Kjellski: jap
14:01 The-Kenny: Of the palindromes, if your predicate is correct
14:01 qed: clojure.lang.LazySeq
14:02 hiredman: ~for
14:02 clojurebot: for is not a loop
14:02 qed: yayyy i got the answer!
14:02 thanks for your help
14:02 hiredman: ~botsnack
14:02 clojurebot: thanks; that was delicious. (nom nom nom)
14:02 qed: lol
14:02 i think those noms would give us more happiness if they were capitalized
14:02 NOM NOM NOM
14:02 Kjellski: Are you solcing challenges?
14:03 qed: Kjellski: yeah
14:03 Kjellski: On hacker.org?
14:03 qed: project-euler.net
14:03 Kjellski: =) !Have fun! (=
14:03 spuz: qed: I thought I recognised that problem :)
14:03 qed: Originally I had this really bright idea to just find what 999*999 was, and then descend from there, testing each result decrementing down for a palindrome
14:04 unfortunately the palindrome i find doing that, is not able to be composed by multiplying 2, 3 digit integers
14:04 so i had to brute force :(
14:05 spuz: qed: you can improve it a bit by only testing for each pair of numbers once
14:05 The-Kenny: memoize! :)
14:05 Kjellski: djork: Got something running, also with attention to memory, but it´s just not spitting the right answer for 8 days ...
14:05 spuz: at the moment you have n = 100-999, k = 100-999, you could have n = 100-999, k = n-999
14:06 qed: once i bind n in my for loop, and i use it immediately within the same binding?
14:06 spuz: yep :)
14:06 qed: like [n (range 100 150) k (range n 200)]
14:06 if i define n in terms of itself will it blow up?
14:06 :)
14:07 hiredman: n is not a number there
14:07 n is range
14:07 and range takes numbers, not ranges
14:07 qed: "Elapsed time: 2679.445 msecs"
14:08 (the old way)
14:08 "Elapsed time: 1347.57 msecs"
14:08 spuz: hiredman: I'm pretty sure my solution uses exactly that construct
14:08 qed: (spuz's way)
14:08 spuz: thanks for that tip
14:08 spuz: and apparently it works for qed :)
14:08 hiredman: ah, I see
14:08 (for ...)
14:08 spuz: yeah, it's not a let :p
14:09 The-Kenny: A tribute to geocities: http://
14:12 qed: so quick question
14:13 Kjellski: Damned... just not getting it.
14:13 qed: how does :when work there, it says "when" to add (* n k) to the new seq?
14:14 Kjellski: It´s just executing the body, ":when" the condition is true...
14:15 djork: http://
14:16 qed: Kjellski: thanks again man!
14:16 Kjellski: qed: welcome...
14:17 qed: you know, normally somebody is helping me... so this is the least =)
14:18 qed: haha, well eventually ill be able to offer something back to the newcomers, but im struggling to keep my head above water right now
14:18 some of it seems to make perfect sense, but then other things, that seem like they should be so easy, look so different
14:18 let bindings and all of that are very new to me
14:18 anyway gotta get back to work, lunch is over
14:18 ciao
14:18 Kjellski: For me too, and then, for me it´s also my first lisp... ^^
14:18 vya
14:18 bye
14:19 qed: Kjellski: same here, first lisp
14:33 scottj: how do I change a struct-map into a normal map so I can dissoc?
14:33 chouser: (into {} m)
14:36 scottj: sorry, my stupid irssi was messed up and I didn't see that. did you just answer my q?
14:42 piccolino: Is there some way in Slime to make the current expression get sent to the REPL? That is, so that it appears in your REPL buffer, and not in your minibuffer?
14:42 (This is with Aquamacs and Clojure).
14:42 Kjellski: Maybe C-M-X or does it affect your buffer?
14:43 err C-M-x
14:43 chouser: scottj: use 'into' to convert just about anything to a clojure persistent datastructure
14:43 scottj: like (into { } other-map)
14:43 piccolino: Kjellski when I do that command, it tells me the result in the minibuffer (eg, "nil"), but then the function is not defined when I switch to the REPL.
14:44 Kjellski: piccolino: it is, if it is a function... but a call will give you the result...
14:44 piccolino: Hm, nope.
14:45 Not in "inferior lisp" or "Slime-repl clojure."
14:45 Kjellski: Okay, sorry... I´m using ClojureBox so maybe it´s something else here...
14:45 Are you sure you´re doing it on a (defn ... ?
14:45 piccolino: Yup.
14:46 Kjellski: Forget everything I said. Sorry.
14:46 piccolino: Oh, how embarrassing.
14:46 duncanm: hmm
14:46 piccolino: I forgot to qualify the function with the namespace when I was in the repl.
14:46 duncanm: anyone familiar with Swing here?
14:47 piccolino: It does work, thanks Kjellski.
14:47 Kjellski: piccolino : welcome =)
14:48 ambient: anyone know how i can control in Emacs which buffer windows stay unchanged?
14:48 it annoys me greatly when a command like C-x C-b (list buffers) changes a random buffer window
14:49 i tried browsing emacs wiki but found nothing obvious solution to this
14:50 tomoj: ambient: if you find something ping me
14:51 maybe #emacs would be more helpful
14:51 piccolino: OK, next question: how can I make a repl use a namespace even though it can't find the file to load the namespace fun? So I don't have to type out everything with the full namespace?
14:52 ambient: (ns your.namespace) i'd think
14:52 at least has worked for me so far
14:52 djork: ,(doc import)
14:52 clojurebot: "([& import-symbols-or-lists]); import-list => (package-symbol class-name-symbols*) For each name in class-name-symbols, adds a mapping from name to the class named by package.name to the current namespace. Use :import in the ns macro in preference to calling this directly."
14:52 Kjellski: ,(doc use)
14:52 clojurebot: "([& args]); Like 'require, but also refers to each lib's namespace using clojure.core/refer. Use :use in the ns macro in preference to calling this directly. 'use accepts additional options in libspecs: :exclude, :only, :rename. The arguments and semantics for :exclude, :only, and :rename are the same as those documented for clojure.core/refer."
14:52 piccolino: I tried use, it complains it can't load the file.
14:53 tomoj: then you must load the file
14:53 hiredman: piccolino: well, then you can't use it
14:53 tomoj: or put it someplace so that clojure can find it
14:53 hiredman: you can just create the namespace
14:53 but it will be empty
14:53 tomoj: well you could just (load "/full/path/to/file.clj"), no?
14:54 djork: OK so about loading with use
14:54 if I have foo.clj
14:54 and . in my classpath
14:54 hiredman: djork: you already failed
14:54 piccolino: OK, "ns" worked, thanks ambient.
14:54 djork: oh
14:54 hiredman: ~namespace
14:54 clojurebot: Titim gan éirí ort.
14:54 hiredman: ~namespaces
14:54 clojurebot: namespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it
14:54 djork: well ok then :)
14:54 tomoj: why is it that you can't use single segment namespaces?
14:55 hiredman: you can, they just don't behave well, so I discourage their use
14:55 tomoj: ah
14:55 Kjellski: djork: there you are... ^^
14:56 djork: hey
14:57 yeah I'm at work (doing non-Clojure 99% of the time)
14:57 trying to squeeze it in for server stuff
14:57 Kjellski: Urgh, sorry... ^^
14:57 Just go on ^^
14:57 djork: heh it's find I use fun languages anywa
14:57 Rails, ObjC
14:57 my typing is awful today
14:58 notallama: is objC a superset of c?
14:58 Kjellski: Better than mine, everyday.
15:00 The-Kenny: notallama: It's used in Osx. Things like classes, functors, message-passing etc. are the features.
15:01 djork: ObjC is fun. It's like Smalltalk bolted onto C.
15:01 [foo messageWithArgument:bar andAnotherArgument:baz];
15:01 lots of typing though
15:01 The-Kenny: heh, yeah.
15:02 duncanm: hmm
15:02 i don't think i can bind *out* in the swing EDT
15:02 notallama: that's always the way with c-like languages. they're verbose.
15:02 djork: [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[self context] sectionNameKeyPath:nil cacheName:nil];
15:03 :)
15:03 hiredman: duncanm: what do you mean?
15:03 The-Kenny: djork: don't forget to call release :)
15:04 duncanm: hiredman: i tried something like (SwingUtilities/invokeLater #(... (binding [*out* out-writer] ....))), but in my click handler, println still goes to the normal stdout
15:04 Chousuke: the interleaved message send syntax is one of ObjC's good points though :P
15:04 duncanm: hiredman: but i use (.println System/out "foo"), then it goes to my swing window
15:05 hiredman: duncanm: pastebin some code?
15:05 duncanm: hiredman: sure
15:09 hiredman: http://
15:10 hiredman: makes sense?
15:13 Chousuke: duncanm: I don't think the binding is in effect anymore after you've created the buttons.
15:13 duncanm: Chousuke: so what can i do?
15:16 Chousuke: duncanm: capture the value of *out* in a local when the click proxy is created and rebind it in the body
15:16 hiredman: pass out-stream around?
15:16 duncanm: eew, that's kinda lame
15:17 Chousuke: you can also change the root binding :P
15:17 hiredman: ~url
15:17 clojurebot: something
15:17 hiredman: lisppaste8: url
15:17 lisppaste8: To use the lisppaste bot, visit http://
15:17 duncanm: why is it that *out* is not dependant on System.out?
15:17 hiredman: ah, i'll use that pastebot next time
15:18 lisppaste8: hiredman pasted "binding *out*" at http://
15:18 Chousuke: duncanm: because System.out can't be rebound, I guess :P
15:18 hiredman: you can set System.out
15:18 duncanm: i did
15:18 Chousuke: yeah, but that's not what I meant.
15:18 duncanm: but it doesn't affect println
15:18 i suppose i can keep out-stream in the top-level
15:18 Chousuke: duncanm: the default root binding of *out* just happens to be System.out. that's all.
15:18 they're completely separate otherwise
15:18 duncanm: how do i change the root binding?
15:19 Chousuke: alter-var-root!
15:19 hiredman: :(
15:19 Chousuke: it's safe, and fine, too. as long as you do it only once...
15:19 duncanm: i can do it in my -main
15:19 Chousuke: if you build your logic around changing it and then setting it back, you should figure out some other method :)
15:19 duncanm: i'm not gonna set it back
15:20 Chousuke: should be okay, then.
15:21 but hm
15:21 why is your OutputStream proxy calling print?
15:21 won't that cause a loop?
15:21 duncanm: oh
15:21 print is a local fn
15:21 Chousuke: ah, yeah. shadows the global ;/
15:22 I don't like pastebin's syntax highlighting at all... too low contrast.
15:23 duncanm: (alter-var-root *out* #(out-writer)) ;; that doesn't work
15:24 notallama: there's a "!", i think.
15:24 Chousuke: it's an alter-style function
15:25 you'll want (fn [_] out-writer)
15:25 also you'll want (var *out)* instead of *out*
15:25 oops
15:26 djork: pastebin is pretty terrible :)
15:26 Chousuke: anyway, since it's an alter function, you're supposed to use it like (alter-var-root! #'*somevar* inc)
15:27 djork: (might I suggest http://
15:28 Chousuke: gists are great
15:28 they actually *highlight* code instead of just colouring it :P
15:29 djork: yeah, seriously... I can *check out a paste*
15:30 Chousuke: heh
15:30 you can actually commit too
15:31 clojurebot started as a gist
15:31 hiredman: http://
15:31 Chousuke: full development history exists
15:31 duncanm: hmm
15:31 Chousuke: I just cloned it from the gist and pushed it on github at one point :P
15:32 hiredman: I was using bzr, and had a script that would copy clojurebot.clj to the git clone of the gist, and commit and push
15:32 :/
15:33 Chousuke: heh. do you use git nowadays, though? :P
15:33 hiredman: yes
15:33 Chousuke: good. :)
15:34 * technomancy is contributing to a bzr-based project. it beats svn, but I'll leave it at that.
15:34 djork: hah hah
15:34 Chousuke: vimperator moved onto hg at one point, and I actually tried to use hg
15:35 I found the lack of local branches disturbing.
15:35 djork: SVN is fine. It's like the Honda Civic of version control.
15:35 hiredman: my dotfiles are all still in bzr
15:35 Chousuke: I can use git as an SVN client, so SVN is passable.
15:35 technomancy: hg has local branching now
15:36 Chousuke: yeah, I tried some extension, but... It just isn't git ;/
15:37 git lets me do whatever I want with my branches and commits and I kind of like that :)
15:39 The hg worldview seems to be that commits and branches exist forever and are indestructible :/
15:39 Kjellski: Bye for today... cya
15:40 Chousuke: I guess I could have adapted hg to my workflow if I had put in more effort but I finally just ended up importing the hg repo into a git one :P
15:41 djork: git wins whenever there is any question about workflow
15:43 duncanm: is there a standard technique for processing argument lists that are in the form of a plist?
15:43 technomancy: duncanm: (apply hash-map args)
15:44 hiredman: :(
15:45 you could just use hash destructuring
15:45 duncanm: hiredman: yeah, what's the syntax for that?
15:45 hiredman: clojurebot: destructuring
15:45 clojurebot: destructuring is http://
15:45 * technomancy always forgets about hash destructuring
15:52 AWizzArd: it's very useful
15:52 i also ignored it several months
15:58 duncanm: sigh, doto doesn't work with set! and fields
16:01 djork: how do you mean
16:08 duncanm: djork: you can't write (doto x (set! foo 1)) to mean (set! (.foo x) 1)
16:09 somnium: how can you get to clojure metadata from .java?
16:09 duncanm: oh wait
16:10 nah, you can't
16:11 djork: that doesn't make sense
16:12 duncanm: it'd be nice to have (doto x (set! .foo 1))
16:19 tomoj: hmm?
16:19 somnium: you can get to clojure metadata from java
16:19 somnium: I know its possible, I didn't find the right incantation while looking
16:20 tomoj: just call .meta() on it
16:20 you will get an IPersistentMap back
16:20 somnium: ok, trying to find a way to avoid reflection in a proxy class, that should do it
16:20 tomoj: oh, I thought duncanm was talking to you
16:21 duncanm: what would that even mean?
16:22 oh, you mean assigning to a public field, I see
16:25 djork: slutty types...
16:25 rhickey: ok, bridge method generation in place for newnew/defclass*
16:25 djork: implement setFoo and (doto x (.setFoo 1)) and you're done
16:32 duncanm: djork: not when it's not my own class
16:32 Chousuke: duncanm: (-> x .foo (set! 1)) :/
16:32 djork: ew, who designed a class with important public fields... I need to know so I don't accidentally hire
16:33 chouser: rhickey: woohoo!
16:36 stuartsierra: chouser: what's woohoo?
16:38 cemerick: stuartsierra: "rhickey: ok, bridge method generation in place for newnew/defclass*"
16:38 rhickey is rebuilding the foundation while we party in the rafters :-)
16:39 stuartsierra: heh
16:39 At the rate he's going, he's going to have to call it Clojure 2.0 instead of 1.1.
16:40 technomancy: hehe
16:45 jasapp: somnium: thanks for congomongo
16:55 skillet-thief: trying to get slime working. I get into an *inferior-lisp* buffer with clojure,
16:55 but no slime buffer. Am i missing something obvious?
16:56 technomancy: skillet-thief: did you install via M-x clojure-install or manually?
16:56 somnium: jasapp: hows it working for you?
16:56 djork: skillet-thief: I'm going to guess that this is the second time you're starting Emacs after clojure-install.
16:56 skillet-thief: technomancy: manually
16:56 djork: oh, wrong
16:57 skillet-thief: clojure-install means going through elpa, right?
16:57 technomancy: skillet-thief: no, it performs git checkouts for you
16:57 it's orthogonal to elpa
17:00 skillet-thief: ok, I'm going to try again with clojure-install and come back later. Thanks!
17:02 djork: skillet-thief: just pay special attention to the post-install note
17:02 technomancy: djork: I learned my lesson; the next version will not require so much attention to detail to install. =)
17:02 djork: :)
17:03 it's not so baad
17:03 it's quite slick
17:03 it's just the note on the first line is easy to miss
17:03 technomancy: I do get a number of people who miss it though. I think I can do better.
17:03 somnium: I tried installing the latest but I couldn't figure where it put anything and wasn't in the mood to configure emacs :(
17:05 The-Kenny: My installation of swank-clojure is a bit fragile... I don't want to touch a file, it could destroy everything!
17:05 technomancy: just wait, the next version will be simpler.
17:05 as soon as I can get two hours to myself to finish it. (so maybe around mid-November)
17:05 somnium: heh
17:06 spuz: technomancy: next version of what?
17:06 technomancy: swank-clojure
17:07 djork: technomancy: yeah I'm a little fuzzy on where it goes
17:08 (too)
17:13 yuras: i want to build jsonrpc server using http as transport layer, and im not sure about choosing appropriate http lib for that. will jetty be okay? or should i go with something more simple like one of embedd into jdk http servers? im a bit newbie about java world, came from python :) please advise
17:13 hiredman: I wrote an extremely minimal http server for clojurebot
17:14 tomoj: so I think the best representation for my graphs is four maps, from node ids to seqs of outgoing edge ids, from node ids to seqs of incoding edge ids, from node ids to node data, and from edge ids to edge data
17:15 yuras: hiredman: thanks, will check out now... i just dont want to reinvent the wheel and follow idiomatic way of clojure.
17:15 tomoj: which is... weird
17:15 hiredman: http://
17:15 tomoj: when I've used jetty with compojure it's been stupid simple
17:16 duncanm: is condt the right library to use to get a 'case' macro?
17:16 tomoj: I really don't know anything at all about jetty, and yet I've used it successfully
17:16 duncanm: i don't see it in clojure-contrib
17:16 chouser: duncanm: cond and condp are built in
17:16 yuras: tomoj: i know, but isnt to heavy for just simple jsonrpc lib, which is supposed to be easy reused...
17:16 duncanm: chouser: i want something that looks like case in Scheme
17:17 hiredman: http_server.clj and factoid_server.clj allow for json queries of clojurebot's factiods over http
17:18 yuras: hiredman: thank you very much, im almost there with your code
17:18 hiredman: http://
17:18 rhickey: case-like switch thingy coming soon
17:18 duncanm: rhickey: oh? that's nice
17:19 stuartsierra: duncanm: condp (built-in) is very close to case; clojure.contrib.fcase is an alternative
17:19 rhickey: the case I'm doing will have constant-time dispatch
17:21 stuartsierra: Yeah, yeah, I'll constant-time dispatch YOU. :)
17:21 chouser: ,(condp get :beta, #{:foo :bar} "classic", #{:alpha :beta} "greek", "other")
17:21 clojurebot: "greek"
17:22 chouser: duncanm: that's *not* constant-time dispatch, but might be close to what you want
17:23 rhickey: Scheme case is not guaranteed constant time anyway
17:24 and yes, the condp example is a good equivalent
17:26 hiredman: I've been using (condp = …) a lot
17:33 duncanm: Chousuke, if I use (-> x .foo (set! 1)), what's the syntax for setting .bar?
17:33 i mean, .foo and .bar
17:33 Chousuke: hm, I guess you can't :/
17:33 duncanm: yeah
17:33 Chousuke: you need to make your own macro :)
17:33 duncanm: i'm always coming up with little syntactic things that i wanna change
17:33 Chousuke: well, you can :P
17:34 duncanm: last time, it was having automatic proxy-ication
17:34 but rhickey shot down that idea ;-/, oh well ;-P
17:34 Chousuke: it's almost trivial to make a (set-fields! x .foo 1 .bar 2 .zonk 3)
17:34 duncanm: right
17:35 i know syntax-rules and E-R macros from Scheme, but i haven't really looked into writing Clojure macros
17:35 Chousuke: you just return plain lists of symbols and such
17:35 usually using syntax-quote
17:36 eyeris: When I evaluate my file via vim-clojure, all of the defns succeed, but the code that actually does something doesn't seem to be run.
17:37 hiredman: duncanm: clojure macros are just functions that s-expressions and return s-expressions
17:37 duncanm: hiredman: sure, all lisp macros are like that ;-P
17:37 hiredman: i just need to sit down and learn it, that's all
17:37 eyeris: For example, at the bottom of the file, below the last defn, I can put (+ 1 2). I see the last defn is established, but it never evaluates (+ 1 2)
17:38 Chousuke: (defmacro set-fields! [object & fields] `(do ~@(map (fn [[field foo]] `(set! ~object ~(list field foo))) (partition 2 fields))) or something
17:38 though probably has problems with multiple evaluation
17:39 also I didn't count the closing parens :P
17:41 also it wouldn't work anyway.
17:41 hm
17:42 moral of the story: don't write macros in irssi ;(
17:42 chouser: heh
17:43 tomoj: eyeris: how do you know it never evaluates (+ 1 2)?
17:43 eyeris: tomoj It is never printed in the preview window.
17:44 tomoj: well, I dunno anything about vim-clojure, but I would be somewhat surprised if it DID print anything
17:44 maybe try (println (+ 1 2))?
17:44 eyeris: tomoj: Why?
17:44 maacl: All three Clojure Quicksorts at Rosetta Code (http://
17:44 tomoj: does it print out the result of every single form in the file when you compile something?
17:44 that would be incredibly annoying to me
17:45 eyeris: You're missing the point tomoj. It's a repl. The println is implicit.
17:45 tomoj: it's not a repl if you're compiling a file...
17:45 rhickey: wanted - suggestions for alternative to 'expando' for talking about automatic extensible keys/assoc support for deftype/defclass
17:45 eyeris: I am not compiling a file.
17:46 chouser: maacl: broken in what way?
17:46 eyeris: rhickey: You just want a better name? Or a better implementation?
17:46 tomoj: so, what do you mean "evaluate my file"?
17:46 you're going form-by-form and sending those forms to the repl?
17:46 rhickey: eyeris: name :)
17:46 eyeris: tomoj: Nevermind man. This is a vimclojure thing. It works fine from the std repl, when compiling, etc.
17:46 chouser: aux-keys
17:46 maacl: chouser: they blow the stack - all use direct recursion
17:47 tomoj: does "evaluate a file" in vimclojure mean "send every form in the file to the repl and print its result"? just curious, feel free to ignore me :)
17:47 eyeris: tomoj: Yes, that's precisely what it means.
17:47 tomoj: wow
17:48 why is that useful?
17:48 eyeris: tomoj: It's useful so that you don't have to startup your program every time you make a tiny change.
17:49 tomoj: I must be confused
17:49 I don't ever have to do that and I don't have that feature
17:50 oh well
17:50 eyeris: tomoj: do you use emacs?
17:50 tomoj: indeed
17:51 duncanm: oen thing that always bugged me about clojure is that the functions are read top-down, so I have to always order my functions carefully - is there something i can do so i don't have to do that?
17:51 tomoj: (doc declare)
17:51 clojurebot: "([& names]); defs the supplied var names with no bindings, useful for making forward declarations."
17:51 duncanm: tomoj: so i have to declare everything ahead of time?
17:52 tomoj: I think maybe doing otherwise has unpleasant consequences?
17:52 eyeris: tomoj: I think the emacs/slime equivilent is C-c C-l
17:52 tomoj: maybe it breaks the conflation of compile-time/eval-time or something?
17:52 eyeris: ok, but C-c C-l doesn't print out the result of each and every form in the file
17:52 eyeris: I'm not sure though. I've never felt comfortable in emacs.
17:53 tomoj: that's the puzzling part to me
17:53 djork: maacl: they need to be made tail-recursive and use the recur facilities
17:53 eyeris: tomoj: M-x slime-eval-buffer?
17:53 djork: I'm still too much of a n00b to do it myself.
17:54 AWizzArd: rhickey: "inject", "inject-keys"
17:54 tomoj: eyeris: that prints out the result of only the last form in the file
17:54 maacl: djork: yeah I figured as much, but can really see how to do it since they all need to recur on both parts of the list
17:54 tomoj: which, if it's something like (+ 1 2), is 3, yes
17:55 djork: yeah, I don't really know the best way to do it
17:55 above my head
17:55 tomoj: eyeris: what does it print out when the last thing in the file is a def(n)?
17:55 something like "#'foo"?
17:55 eyeris: #'edu.wisc.uwsc.xlsmerge.gui/build-main-window
17:55 maacl: djork: same here
17:55 tomoj: yeah, then that is pretty odd
17:56 have you tried putting something that takes a really long time?
17:56 as in, maybe it's evaluating it but just not printing it for some reason?
17:56 eyeris: When it works, it's very quick.
17:56 AWizzArd: rhickey: "introduce", "extend", "grow", "enlarge"
17:57 chouser: rhickey: we're looking for a noun, right?
17:57 eyeris: I think it has something to do with the repl server not being able to create a Swing frame, but I don't know because I can't get an error out of it.
17:58 tomoj: what do swing frames have to do with (+ 1 2)?
17:59 eyeris: tomoj: (+ 1 2) evals properly when it is before the defns but not after the defns
17:59 All of the defns are involved with Swing GUI construction
17:59 tomoj: and you're actually calling one of those functions somewhere up there?
18:00 eyeris: Nope
18:00 tomoj: doesn't make sense that they would hang, then
18:00 to me, anyway
18:00 until they're called
18:01 somnium: what's the most straight-forward .java way to create a PersistentHashMap?
18:01 rhickey: chouser: something like :meta, for metadata
18:02 chouser: I like :aux
18:03 :extra :bonus :supplementary
18:04 AWizzArd: bonus sounds funny :-)
18:04 Chousuke: somnium: RT.map()?
18:04 eyeris: quit
18:04 rhickey: I wonder how fine grained it should be, could just be based on interfaces
18:04 (defclass name [fields] #^{:disable #{Seqable Associative}} [interfaces] & methods)
18:05 AWizzArd: Can the granularity be configurable?
18:05 rhickey: basically there will be several auto-implementd interfaces you need to be able to turn off
18:05 AWizzArd: what does that mean?
18:06 hrm, interfaces list not a good place for that, since it might not be present. (deftype [a b c]) perfectly ok
18:07 AWizzArd: you said it could just be based on interfaces.. what would be the alternative?
18:07 rhickey: oops (deftype Foo [a b c]) perfectly ok
18:08 AWizzArd: :meta toggles IObj/IMeta, :expando-whatever toggles Associative+
18:08 Chousuke: so wait, you have both deftype and defclass?
18:08 rhickey: Chousuke: yes, deftype is a dynamically typed thing (think more powerful structs), defclass is a regular named class
18:09 Chousuke: ah, okay.
18:11 rhickey: could also be toggled by presence of explicit methods, but that's tricky since only some might be implemented, overlap between interfaces etc
18:11 also, methods not required
18:11 Chousuke: that sounds like too much magic :/
18:12 rhickey: someone might want a very simple non-extensible struct-like thing without meta/lookup/extension at all
18:22 AWizzArd: Chousuke: :aux or :aux-keys is good
18:23 rhickey: yes, exactly such a struct with clojure syntax is what we need
18:42 steiger: Chousuke, rhickey , what is this deftype/defclass about? does it have something to do to contrib's deftype?
18:42 hiredman: ~datatypes
18:42 clojurebot: http://
18:43 hiredman: I think those notes are already obr
18:53 defn: I need to find the 10001st prime. Anyone have any good lazy prime sieve code?
18:54 ls
18:57 hiredman: clojurebot: sieve?
18:57 clojurebot: Excuse me?
18:57 hiredman: clojurebot: the genuine sieve of eratosthenes
18:57 clojurebot: the genuine sieve of eratosthenes is http://
18:58 hiredman: clojurebot: sieve is <reply>see the genuine sieve of eratosthenes
18:58 clojurebot: Ok.
18:58 LauJensen: hiredman, check out cgrands blogpost re the same
18:59 hiredman: LauJensen: hey, I kicked my euler habit, so I am not interested in lazy infinite sequences of primes
18:59 LauJensen: k
19:00 defn: heh
19:00 it's a bad habit isnt it
19:01 cgrands post is old though, it uses lazy-cons
19:06 somnium: hmm, how would I go about calling the JSON parser in contrib from java?
19:06 hiredman: you get a hold of the var
19:07 so you need a symbol
19:07 somnium: import clojure.lang.Symbol ?
19:07 god I forgot how much I hate java
19:07 hiredman: Var.find(Symbol.create("some.namespace.qualified.symbol"))
19:07 then you need to deref the var
19:07 v.deref()
19:08 so you should have an IFn
19:08 fn.invoke(arg1, arg1, ...)
19:08 somnium: cool
19:08 I may make this mutable spaghetti speak a little clojure yet
19:09 any ideas on what kind of object would make a good proxy between struct maps on the one side, and mutable hash-map derivatives with string keywords on the other?
19:10 hiredman: ~def c.l.LispReader
19:10 technomancy: what's the converse of nth?
19:11 converse may not be the exact right word, but given an item and a collection, what's the position of that item?
19:11 somnium: it needs to be mutable for all nasty side effecty functions called on it by the java api, serialize clojure to json, and return IPersistentMaps to clojure
19:11 offset?
19:13 hiredman: (get (nth (map vector coll (iterate inc 0)) n) 1)
19:13 well
19:13 technomancy: I thought it was added to clojure core
19:13 hiredman: hmmm
19:13 technomancy: or possibly somewhere in contrib, though I'm not finding it in seq-utils
19:14 defn: how do i convert a massive biginteger, into a sequence of integers
19:14 hiredman: defn: #euler or something
19:14 somnium: :)
19:15 defn: treat it like a sequence of integers of course
19:17 steiger: OH
19:17 i was struggling with how to represent some adts (too much choices, no default one)
19:18 i'm glad to see the plans to datatypes
19:18 *plants to new datatype features
19:27 timothypratley: I have some sort of classpath problem but not sure how to resolve it:
19:28 user=> (compile 'sandpit.button)
19:28 java.io.IOException: No such file or directory (button.clj:3)
19:28 (ns sandpit.button
19:28 (:gen-class))
19:28 It is finding button.clj to compile it, but then when not happy with the ns declaration
19:29 And I can't see any reason why
19:51 Oh hmmm nevermind, no classes directory caused it.
21:03 hircus_: if I use struct-map to create a new map, is there a way to check which "interface" it implements?
21:03 or is it wholly duck-typed?
21:07 tomoj: hircus_: I was wondering that a couple days ago
21:07 it seems the reference to the structmap object is private
21:07 so afaik no way to get at it
21:08 if you have a reason to care about that sort of thing you should probably put a :type field in the metadata
21:08 hircus_: tomoj: ah, that's a bummer. true, that'd bloat the size a bit though
21:08 tomoj: (with the help of a make-foo function or such perhaps)
21:08 well, hmm
21:08 hircus_: I guess I could gensym the type to make sure it is unique (but that'd make it non-serializable)
21:09 probably ok in this context, actually
21:09 tomoj: if you have (def foo [bar] (with-meta bar {:type 'foo}))
21:09 when you call foo on two different objects, are their metadata maps identical?
21:10 nope, they aren't
21:11 that seems kinda strange to me, I would've expected the map that gets put into the metadata to be the map the reader read, which would be the same always
21:11 somnium: hircus_: what do you mean what interface?
21:12 tomoj: my completions on the slime repl suddenly don't work
21:12 somnium: hircus_: struct definition or interface as in IPersistentMap
21:13 hmm, anyone know where a definitive guide to gen class is?
21:13 hircus_: tomoj: they are identical when I tried it
21:13 somnium: found almost contradictory versions on two wikis
21:13 hircus_: tomoj: user> (= (meta (foo x)) (meta (foo y)))
21:13 true
21:13 somnium: struct definition
21:13 tomoj: = is not identical?
21:13 hircus_: tomoj: ah, yes. == returns false
21:14 tomoj: well, that's because they're not numbers
21:14 you're looking for identical?
21:14 hircus_: aha
21:14 somnium: why not use a macro to add the meta data automagically?
21:14 hircus_: so I can use identical? if I want to be anal, and have a private map
21:14 tomoj: so that means every time you make a structmap with your {:type 'foo} metadata you have to allocate that map
21:14 hircus_: somnium: I'm going to do that, I'm just looking for a form that is small enough
21:14 tomoj: somnium: why a macro and not a function?
21:14 somnium: better performance would be one argument
21:15 tomoj: I wonder if they'd be identical, then
21:15 somnium: but I don't know, you could certainly use a function
21:15 functions always have to be called, and defstruct involves def so a macro seems appropriate
21:15 tomoj: yeah
21:17 still not identical, but in this case it makes perfect sense to me why they're not
21:19 somnium: I compiled my gen-class in slime, and no errors, but it couldn't the .class file. So I build it with ant and it blew up right away
21:20 tomoj: aha
21:20 somnium: and I can't even find a confirmation of the right syntax
21:20 tomoj: (def foo ((fn [meta-map] (fn [bar] (with-meta bar meta-map))) {:type 'foo}))
21:20 I wonder if there's an easier way to do that
21:20 somnium: you could comp them for less overhead
21:21 no nevermind, youre return a fn, I'm tried
21:21 tomoj: of course this is almost certainly pointless except as an exercise :
21:21 somnium: think of the fun it would be to implement that with anonymous class ;)
21:22 tomoj: but,
21:22 ,(let [foo ((fn [meta-map] (fn [bar] (with-meta bar meta-map))) {:type 'foo})] (identical? ^(foo []) ^(foo {})))
21:22 clojurebot: true
21:39 eyeris: The /api page doens't render properly in FF 3 (neither normal mode nor safe mode) for me. Does it work for anyone else?
21:39 tomoj: yep
21:39 but a couple others have complained of the same problem
21:39 timothypratley: mostly :)
21:39 eyeris: tomoj what version do you have?
21:39 tomoj: well, if the problem is that it cuts off half way through or something
21:40 ambient: it's a firefox bug. sometimes the bottom of the page (or all of it) are black for long lists or pages of text
21:40 eyeris: Right, that's the problem I am having.
21:40 I have 3.5.3
21:40 tomoj: I dunno my firefox version right now - only have conkeror here
21:40 will check in a bit
21:40 ambient: usually it works
21:40 eyeris: ambient: It never works for me on the /api page.
21:40 tomoj: sometimes it causes a bug in conkeror too, strangely
21:40 but not a rendering bug
21:41 ambient: 3.5.3 also
21:41 works fine atm
22:03 manby-ace: is there a way to get a list of the methods that a java object implements from clojure?
22:04 tomoj: (require '[clojure.contrib.repl-utils :as repl])
22:04 (repl/show the-java-object)
22:04 that's for looking for your own convenience
22:04 for getting a list you can work with programmatically I guess you'd use java reflection or something
22:06 manby-ace: tomoj: thanks very much, that's exactly what I need - just for the repl.
22:07 tomoj: if you're using slime there's a fancier way, too
22:08 though, now when I try it it doesn't show methods, only fields
22:10 manby-ace: cheers - I am - will investigate further
22:11 arohner: is anyone using a graph / charting library in webapps?
22:11 I need something that will print a graph (like graphviz) to a web page, and haven't found anything good yet
22:12 jasapp: incanter?
22:12 arohner: incanter is more of a statistics library, and it uses jfreechart to draw
22:12 AFAIK, jfreechart doesn't have anything for showing a graph / tree
22:14 Flox_: arohner: JGraph is LGPL since a few weeks: http://
22:16 arohner: Flox_: interesting, thanks
22:16 Flox_: arohner: sorry - missed the bit about "web apps". JGraph also have a JS lib called mxgraph, but it is not free.
22:16 arohner: Flox_: can it serve a png?
22:18 Flox_: arohner: I would guess so, but I haven't used it lately (just about 10 years ago, when it was not completely free...)
22:19 arohner: Flox_: thanks anyways
22:28 Flox_: About the Firefox / API page rendering problem: It works if you disable some CSS scripts via the "Web Developer" extension. Alas, I do not yet know exactly which style (combination) causes the effect.
22:30 ambient: the bugs appears only like 5% of the time, and usually when i dont have time to debug :)
22:32 Flox_: arohner: I might soon need to serve some graphs too, so I'd be keen to learn what worked for you! Good luck!
22:32 Good night all!
22:42 djork: is there any logic to choosing a namespace?
22:42 Licenser: somnium: what clojure version do you need for your mongodb driver?
22:43 somnium: Licenser: Ive been using recent 1.1
22:43 didn't test against 1.0
22:43 Licenser: ah that explains :)
22:43 somnium: is it broken?
22:43 Licenser: yes
22:43 because clojure/walk does not seem to be there
22:43 somnium: I have a 1.0, will it not build at all?
22:43 really
22:43 well, it won't be needed shortly
22:43 tomoj: djork: java standard is to start with reverse domain name
22:43 djork: well yeah
22:44 but what if I don't have a domain name
22:44 tomoj: dunno
22:44 somnium: was talking with eliot at mongo today, and almost have a .java proxy class
22:44 Licenser: somnium: nice!
22:44 tomoj: if your project has a unique enough name it's not so bad to just use it, I guess
22:44 compojure does this for example
22:44 somnium: he hacked in an interesting hook, that didn't quite work, but he set me on the right track (I hope)
22:44 its a bit of a compromise
22:44 Licenser: ^^
22:45 somnium: its a mutable thing that can take keywords and handle json
22:45 but its definitely not clojure, mutable like jelly :)
22:45 * Licenser waits for the oblegory stoning for mentioning mutable
22:45 Licenser: ^^
22:46 somnium: it will be performant, most db transactions won't alter records, if youre doing number crunching just cast them I guess
22:46 (shrug)
22:46 Licenser: :)
22:47 hmm when I build a jarfire for a clojure project, it won't automatically include all the needed clojure framework files right?
22:49 somnium: it depends on the build.xml
22:49 I try to keep them slim, you could end up with five clojure jars in your lib dir if youre not careful
22:50 he got it so you can put keywords in as values, but that's kind of useless
22:51 clojure.walk is sloooow, got to get rid of it, good for macros but not running thousands of little hashmaps
22:51 Licenser: ^^
22:51 somnium: I want to get it work first of all, I don't yet worry about slow or fast
22:52 somnium: all the tests passed before I pushed, I swear
22:52 will put a note about 1.1 I guess, but I only think two people besides me have tried it so far :)
22:53 Licenser: wooh so I'm the second beta tester :P
22:53 erm alpha tester
22:53 somnium: pre-alpha tester :)
22:54 Licenser: omega tester?
22:55 somnium: gamma at least
22:57 Licenser: heh
22:57 still breaking narf
22:57 I guess I also need the mongodb java driver?
23:00 hrm, it's really not easy to get your driver to work somnium :P
23:00 java.lang.ClassNotFoundException: clojure.core$_EQ___4369 <- not good
23:00 I guess
23:00 djork: n00b question: what's the best way to set up a "main" entry point for a clojure project
23:01 somnium: yeah
23:01 but, its in deps
23:01 Licenser: for me it's 4341 in the end
23:01 odd very very odd
23:01 somnium: Licenser: hmm, you have bleeding edge clojure jar somewhere?
23:01 Licenser: yes I just downloaded and ant'ed it from github
23:02 that is what I'm using
23:02 somnium: git clone .... cd congomongo... ant -Dclojure.jar=path/to/that/clojure.jar
23:02 Licenser: but seriousely i know that isn't a congomongo problem, how the hell did that happen?
23:02 Flox_: arohner: I just read up on JGraph: The license is now BSD (used to be LGPL for the renderer and proprietary for the layouter, which is now included - see http://
23:02 somnium: hrmm
23:03 what error are you getting?
23:03 Licenser: class not found: java.lang.ClassNotFoundException: clojure.core$_EQ___4369
23:03 he does not found EQ
23:03 oddly enough my cloure package implements only clojure.core$_EQ___4341
23:03 somnium: ...
23:04 yikes,
23:04 Licenser: yes I find that very very odd
23:04 but with recompiling it works
23:04 somnium: let me push my clojure jar and see if that works for you
23:04 it worked?
23:04 Licenser: yes
23:04 somnium: sweet
23:04 Licenser: but I wonder, does that mean I've to have the exact smae clojure jar to make other people's jar work?
23:04 that would be a very new definition of unportable :P
23:04 somnium: well, I guess edge isnt very stable
23:05 clojure's been moving fast though, always new toys
23:05 Licenser: but EQ isn't that new
23:05 somnium: maybe its an AOT thing? no idea, I can barely read java anymore
23:05 http://
23:06 look at this crap, just to get a function out of contrib to use in java
23:06 Licenser: heh
23:06 Java sucks, but java sucked before clojure existed :P
23:07 somnium: true, but I wouldn't be writing java now if it weren't for clojure :/
23:07 Licenser: teehee
23:12 the one thing that realy makes me cry with clojure are the horribly bad exceptions
23:13 it's as bad as java just a bit worst since you've a gazillion lines of stacktrace :/
23:14 very helpful texts like: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.NullPointerException
23:22 hmm I see another problem but it seems to be a mongodb prolem
23:23 no it's not
23:23 somnium: why is the driver casting integers to floats? :P
23:23 that is a bugy bug
23:32 somnium: ?
23:33 what produced it?
23:35 tomoj: if I pass an array of Objects to a java method which is overloaded to accept both Object and Object[], is it possible the Object one is called?
23:35 somnium: Licenser: did you run the tests?
23:35 tomoj: is type-hinting the way to solve this?
23:36 Licenser: somnium: if I fetch from my collection he gets float backs and nope, no clue how to o.O
23:37 somnium: same as build, just add test at the end
23:37 plenty of integers not getting cast over here, can you past what produced the bug?
23:37 Licenser: ahh sneaky
23:40 somnium: all passed
23:40 tomoj: to answer my own question, yes
23:40 Licenser: tomoj: glad we could help *hides*
23:40 tomoj: :)
23:41 I was getting a very strange error on a pretty much direct port from working java
23:42 because, I guess, clojure can't tell that when you pass an Object[] in, it shouldn't call the method that takes an Object
23:42 somnium: wtf is up with java exceptions, why won't they just let world end to see what breaks?
23:42 tomoj: in my case that's exactly what they did :)
23:43 hiredman: ,(ancestors (class (to-array [])))
23:43 clojurebot: #{java.io.Serializable java.lang.Object java.lang.Cloneable :clojure.contrib.generic/any}
23:43 Licenser: somnium: java exeptions were introduced to toss the russions of the track back in the cold war, sadly the scientist who came up with that plan commited suicide shortly after when he tried to compile some java code and only got cryptic expetions
23:43 somnium: this attempt at java has driven me back to netbeans
23:44 tomoj: huh
23:44 how did that :clojure.contrib.generic/any get there
23:44 hiredman: ,(doc derive)
23:44 clojurebot: "([tag parent] [h tag parent]); Establishes a parent/child relationship between parent and tag. Parent must be a namespace-qualified symbol or keyword and child can be either a namespace-qualified symbol or keyword or a class. h must be a hierarchy obtained from make-hierarchy, if not supplied defaults to, and modifies, the global hierarchy."
23:45 tomoj: oh, I see
23:45 I always figured ancestors just meant superclasses/interfaces
23:45 hiredman: ,(doc supers)
23:45 clojurebot: "([class]); Returns the immediate and indirect superclasses and interfaces of c, if any"
23:45 tomoj: :)
23:45 somnium: hiredman: I was able to get to contrib.JSON with your help, but I can't figure out what exception to throw and where to put return on the invoke :(
23:46 hiredman: I finally knocked me reader back into shape
23:46 somnium: ,(isa? String "foo")
23:46 clojurebot: false
23:46 hiredman: somnium: Exception
23:46 somnium: I love that
23:46 hiredman: return on the invoke?
23:46 oh
23:46 somnium: yeah
23:46 hiredman: invoke returns an Object
23:46 somnium: hmm
23:47 hiredman: so you have to cast it to whatever
23:47 IPersistantMap or something
23:47 somnium: #$%^ ... java
23:47 I just need a string
23:47 20 locs to call one function and return a string
23:47 hiredman: so you are generating json?
23:48 somnium: yeah, I need to override mongo's json parser
23:48 djork: ,(class "foo")
23:48 clojurebot: java.lang.String
23:48 djork: wait...
23:48 tomoj: ,(ancestors "foo")
23:48 clojurebot: nil
23:48 tomoj: huh?
23:48 somnium: (class (class "foo"))
23:48 ,(class (class "foo"))
23:48 clojurebot: java.lang.Class
23:48 hiredman: ,(ancestors (class "foo"))
23:48 clojurebot: #{java.io.Serializable java.lang.Object java.lang.Comparable java.lang.CharSequence :clojure.contrib.generic/any}
23:48 djork: ,(isa? String (String. "foo"))
23:48 clojurebot: false
23:48 djork: HAH
23:48 hiredman: ,(isa? String (class "foo"))
23:48 clojurebot: true
23:49 hiredman: ,(doc isa?)
23:49 clojurebot: "([child parent] [h child parent]); Returns true if (= child parent), or child is directly or indirectly derived from parent, either via a Java type inheritance relationship or a relationship established via derive. h must be a hierarchy obtained from make-hierarchy, if not supplied defaults to the global hierarchy"
23:49 tomoj: oh, it's for classes, yes, of course :)
23:49 Licenser: ,(isa? String (new String "a"))
23:49 somnium: the docs for isa? and derive were seriously designed to confuse in my opinion
23:49 clojurebot: false
23:49 somnium: (instance? String "foo")
23:49 djork: so "derived" does not mean the instance but the class
23:49 hiredman: there is no type inheritance relationship between the java class String and the String instance "foo"
23:49 somnium: ,(instance? String "foo")
23:49 clojurebot: true
23:49 djork: ok there we go
23:49 Licenser: ,(doc isa?)
23:49 clojurebot: "([child parent] [h child parent]); Returns true if (= child parent), or child is directly or indirectly derived from parent, either via a Java type inheritance relationship or a relationship established via derive. h must be a hierarchy obtained from make-hierarchy, if not supplied defaults to the global hierarchy"
23:49 hiredman: it doesn't say "derived"
23:50 it says "derive"
23:50 somnium: hiredman: I understand that only because I understand it
23:50 hiredman: which is a specific function
23:50 somnium: not because it was even remotely intuitive or obvious
23:50 Licenser: I find that very confusing
23:50 somnium: its a bit like emacs
23:50 hiredman: *shrug*
23:50 djork: oh well, now I know the difference between isa? and instance?
23:51 Licenser: isa? does not what you expect, instance? does
23:52 hiredman: http://
23:52 it's a technical term
23:53 Licenser: I still didn't expected that :p
23:53 somnium: http://
23:53 hiredman: if you know the term, you do
23:54 you need to return a string in the catch
23:54 somnium: of course
23:55 hiredman: I've been reading and re-reading java a lot lately
23:55 somnium: its odd that the compiler would find 'println "The world ended."' so satisfying
23:55 hiredman: and doing some IFn invoking from java
23:55 I finally sorted out a big tangle in my reader
23:56 somnium: I really want to be using gen-class but I can't find any comprehensive examples
23:56 hiredman: really?
23:56 somnium: well, I followed to, and the first one was broken, and then I got frustrated and decided to finish this java file
23:56 djork: Clojure - because it's still faster than Ruby
23:57 somnium: hiredman: if you could point to any real usage in the wild or examples I would love it