#clojure log - Aug 28 2009

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

0:01 technomancy`: heh... now I've switched it back and can't repro.

0:01 should have checked it in I guess

0:02 or at least stashed

0:02 cark: =)

0:04 technomancy`: http://github.com/technomancy/sketchbook/tree/master <= if you're curious

0:04 having some fun with Processing

0:04 even if the language itself is crap, calling it from Clojure is pretty nice.

0:05 krumholt__: can someone tell me why (java.nio.IntBuffer/wrap (into-array [1 2 3 4 5])) is not working?

0:06 ah i allready know

0:06 cark: ,(int-array [1 2 3 4])

0:06 clojurebot: #<int[] [I@172bab9>

0:06 krumholt__: yes that its

0:06 thank you very much

0:06 cark: ,(into-array Integer/TYPE [1 2 3 4])

0:06 clojurebot: #<int[] [I@26b12d>

3:46 AWizzArd: hiredman: ping

3:58 eevar2: anyone here with commit rights to sourceforge's clojure-contrib?

4:00 i think someone should make a commit cleaning out all the files, like on google code. but maybe get rid of the license files as well; don't really need 3-4 different licenses to go along with your text file explaining that the project has moved

4:03 vIkSiT: hi all

4:03 anyone around?

4:03 I'm getting a compilation error on def.clj in clojure-contrib at line 106

4:04 [java] java.lang.Exception: Unable to resolve symbol: next in this context (def.clj:106)

4:04 any ideas?

4:05 eevar2: sure you use compatible versions of clojure and the contrib source? i.e. both from master, or both from an 1.0-branch on github?

4:09 vIkSiT: eevar2, hmm I think I have, although let me refresh to make sure

4:12 eevar2, I guess I could use both versions from master?

4:13 AWizzArd: sounds good

4:14 * vIkSiT gits

4:14 eevar2: yes, master and the 1.0 branches aren't compatible

4:15 trying to build (master) here now. just in case ;)

4:15 vIkSiT: curiously - vimclojure vs emacs-slime as mode of choice?

4:15 opqdonut: emacs

4:15 eevar2: enclojure :p

4:15 * vIkSiT used lots of emacs slime during his lisp hacking

4:16 vIkSiT: does anyone here use vimclojure at all? :)

4:16 eevar2: if you're already damaged, you might as well stick with emacs

4:16 vIkSiT: hehe eevar2 - except, moved to using vim after that because of ssh and not liking emacs -nw - and now like it better

4:17 * eevar2 started using emacs after vim, mostly for slime (with CL) and now i'm suck at both ;)

4:17 vIkSiT: hehe

4:19 eevar2: my build of clojure, contrib & compojure, current master branch, went ok

4:24 AWizzArd: vIkSiT: I use emacs+slime. The author of VimClojure is often here (but not right now). Has many happy users.

4:25 vIkSiT: ah

4:25 AWizzArd: Last time I checked VimClojure had unique features. For example it can autocomplete the names of static methods.

4:37 vIkSiT: ah I see

4:37 alrighty, thanks all

6:44 G0SUB: How do I access the values of a Java HashMap?

6:45 (mymap "key") throws an error. says it can't be cast into an IFn

6:45 keys are strings, by the way

6:45 AWizzArd: Use the method get

6:45 (.get mymap "key")

6:46 G0SUB: AWizzArd: any way to convert that HashMap to an IFn?

6:46 jdz: i think into works, like (into {} mymap)

6:46 AWizzArd: Yes, use into

6:46 G0SUB: jdz: interesting. thanks.

6:47 AWizzArd: G0SUB: if your Map is very big then this operation is maybe not required.

6:48 you could leave it as a j.u.HM

6:48 G0SUB: AWizzArd: makes sense

6:49 AWizzArd: Especially if it is a read-only object. When there are no writers, then read access is thread-safe

6:57 ole3: Hello, I have to syncronize access to a struct.

6:57 Is it better to put the whole struct into a reference or let the slot be references?

7:06 ok

7:14 AWizzArd: in most cases it would make sense to put a whole struct instance into a ref.

7:14 But, it can also make sense to have refs in refs, if you need to keep identity of objects in a collection which itself is in a ref.

7:17 ole3: well in my struct is a stack and i have to push and pop elements from it.

7:18 it is easy if that stack is in a ref.

7:48 Fossi: ole3: that sounds as if the stack should be one ref

7:57 * Fossi wonders whether he found a concurrency issue in clojure

7:57 Licenser: hmmm I wanted to write a few macros that make some things in compojure easyer (namely adding restfull resources) I'm not getting far sadly :/. I wonder if someone could be so nice and take a look and help me out? http://gist.github.com/176928 (as a warning I'm a beginner)

7:58 Fossi: might be totally unrelated, but the appengine has a deadline after 30 seconds and it's the second time that it fails while starting up in Keyword.intern/ConcurrentHashMap.putIfAbsent

8:02 ole3: Fossi & AWizzArd: thanks for the response, the stack is now the ref.

8:10 Chousuke: Licenser: what do you seek to accomplish with that let in the resource macro?

8:11 oh, I see now. that won't work.

8:11 Licenser: that the 'inner macros' like list_items know how the resource is named

8:11 I noticed that

8:11 Chousuke: ,(list `foo# `foo#)

8:11 clojurebot: (foo__2476__auto__ foo__2477__auto__)

8:11 Chousuke: autogensyms in different syntax quotes are never the same.

8:11 Licenser: I fear it's even 'bad style' since the macros like list_items would not be how is it clled, a function of it's values

8:12 *nods*

8:12 okay again something learned

8:12 Chousuke: you should instead make those macros use some globally bound *resource-name*

8:12 Licenser: o.o

8:12 isn't that very badish?

8:12 Chousuke: then do (binding [*resource-name* whatever] (some-macros-here) (some-more-here))

8:12 Licenser: ah okay binding localizes it?

8:13 Chousuke: dynamic global bindings are very common in lisps, and in clojure.

8:13 Fossi: who would be responsible for the Keywork.java code? rhickey?

8:13 Licenser: I love the (doc thing)

8:13 Chousuke: there are no global (uncontrolled) *variables* in clojure so it's all fine.

8:13 Licenser: Okay

8:14 Chousuke: also, don't use underscores

8:15 list-items, get-item, etc. are better.

8:15 AWizzArd: Fossi: yes

8:15 Licenser: Okay, thanks for the advice

8:15 Fossi: AWizzArd: k, i'll ask him later then

8:15 Licenser: wow something is working!

8:17 okay it compiles, now just to get it working too ^^

8:18 Chousuke: Licenser: also instead of all those nths you could do `(let [~p [(params :id)]] ...) or `(let [~p [(params :id) params]] ...)

8:19 eg. use destructuring.

8:19 Licenser: hmm sneaky

8:19 Chousuke: eh, not eg; ie. ;(

8:19 Licenser: thanks

8:19 Fossi: destructuring is the shit.

8:20 AWizzArd: ??

8:20 Wieso dasn?

8:20 Fossi: *the* shit. ask google :)

8:25 Chousuke: Licenser: http://gist.github.com/176962 this should work

8:25 Licenser: so *

8:26 *looks at it*

8:26 Chousuke: your (do ~@body)'s were superfluous so I removed the dos

8:26 Licenser: hmm why ~'*resource-name* in the one macro?

8:26 okay I had that from the macro documentation ^^

8:26 Chousuke: because otherwise it would become qualified.

8:27 and you can't bind to qualified names I think

8:27 Licenser: ah it would resolve to the value you mean

8:27 Chousuke: no, I mean

8:27 ,`*warn-on-reflection*

8:27 clojurebot: clojure.core/*warn-on-reflection*

8:27 Chousuke: ,`~'*warn-on-reflection*

8:27 clojurebot: *warn-on-reflection*

8:28 Chousuke: maybe it's possible to use binding with qualified names though.

8:28 but with let it fails :)

8:28 (it helps people to not shoot themselves in the foot with macros)

8:28 Licenser: yes with let it did, I tried something like that :P

8:29 Chouser: binding is on vars, so it gets qualified either manually or automatically.

8:29 Licenser: I wanted to shoot myelf in the foot, or nearly did

8:29 G0SUB: Is it possible to create private defmulti & defmethods ? like defn- ?

8:29 Chousuke: (defmulti #^{:private true} foo)

8:29 G0SUB: Chousuke: Thanks. What about the defmethods?

8:29 Chousuke: they can't be private I think.

8:30 Chouser: you don't call them directly anyway -- they are reachable through the multi, so if that's private you're safe.

8:31 Licenser: hmmm

8:31 G0SUB: cool

8:31 Chousuke: I put the same metadata after the defmethod. it compiled fine.

8:31 Licenser: when a function takes arguments like (function a1 b1 a2 b2) can I pass it a list too?

8:31 it will destruct it right?

8:32 Chouser: G0SUB: that metadata is probably being ignored.

8:32 G0SUB: Chouser: right.

8:32 Fossi: Licenser: you can use apply the list

8:32 today no english me

8:32 Licenser: hmm hmm

8:33 AWizzArd: ,(re-find #".* \(" "foo (bar)")

8:33 clojurebot: "foo ("

8:33 AWizzArd: but I want only "foo"

8:33 G0SUB: What is the best way to figure out if the arg to a defmethod is a HashMap? I am using (identical? (type arg) (type {}))

8:34 Chousuke: AWizzArd: use capturing groups and take the first group? :/

8:34 G0SUB: ,(re-find #"(.*) \(" "foo (bar)")

8:34 clojurebot: ["foo (" "foo"]

8:34 G0SUB: ,(re-find #"(.*) \(" "foo (bar)")[1]

8:34 clojurebot: ["foo (" "foo"]

8:34 Chouser: ,(re-find #".*(?= \()" "foo (bar)")

8:34 clojurebot: "foo"

8:35 AWizzArd: G0SUB: you can use instance? for the check

8:35 Chousuke: oh, right. :)

8:35 Chouser: positive zero-length lookahead assertion

8:35 AWizzArd: ,(instance? java.util.HashMap (java.util.HashMap.))

8:35 clojurebot: true

8:35 Chouser: ,(map? {})

8:35 clojurebot: true

8:36 AWizzArd: ,(map? (java.util.HashMap.))

8:36 clojurebot: false

8:36 AWizzArd: so I check in my programs for being java.util.Map

8:36 because I need to capture all those cases

8:36 ,(doc map?)

8:36 clojurebot: "([x]); Return true if x implements IPersistentMap"

8:36 Chouser: ah

8:37 AWizzArd: Chouser: are you in for a very hard regex again? ;-)

8:37 I think it is so hard that noone here can solve it.

8:37 Chouser: heh. well, statements like that are a good way to get me interested

8:38 AWizzArd: I got some funny file format that someone invented and I parse it with a function now. But I think a regex may be able to do it too.

8:38 I have a string, similar to .csv, in which columns are separated either by , or ;

8:38 "15,hello;30;4"

8:38 but...

8:39 it also contains strings in which , or ; may show up. Those should not be splitting. These strings are marked by the entries BEGIN;now some,,;;string is here;; with no\n splitting.;ENDTEXT;

8:41 "93257,1257 ;1;341;NULL;BEGINTEXT,[zzz] MR813.txt[2009-04-21 14:44];ENDTEXT;BEGINTEXT;>> \r\n>> Hello, it is good; but not now. \"It\" is.\r\n>> Ok;ENDTEXT;BEGINTEXT;NULL,ENDTEXT;BEGINTEXT,NULL;ENDTEXT"

8:41 This is an example input

8:41 Chouser: wow. so pretty.

8:42 AWizzArd: and it should split into "93256" "1257 " "1" "341" "NULL" "[zzz] MR813.txt[2009-04-21 14:44]" ">> \r\n>> Hello, it is good; but not now. \"It\" is.\r\n>> Ok" "NULL" "NULL

8:42 jdz: and nobody ever puts BEGINTEXT etc in those fields?

8:42 :)

8:42 AWizzArd: I hope. I don't know who invented it *sigh*

8:43 But I assume that it does not happen.

8:43 So, the [,;] should split only when not inside a BEGIN END block.

8:43 And the BEGINs and ENDs need to be eliminated from the result.

8:43 Chouser: I assume the \" are just for Clojure, not in the file itself?

8:44 jdz: i think i'd create a filter that would escape those separators inside begin/end

8:44 AWizzArd: Chouser: right

8:44 jdz: ard remove begin/end themselves

8:45 AWizzArd: jdz: yes, I am doing it in a similar way, in a function. But they are important markers, because the [,;] inbetween must not split.

8:45 jdz: actually, i think using regular expressions here is more trouble than they help

8:45 AWizzArd: I was just curious weather this can be expressed with a regex.

8:45 jdz: yup

8:46 I think noone here can solve that

8:46 jdz: i'm not gonna trip on that one

8:46 i have my own devices to tinker with :)

8:47 AWizzArd: Yes. I think most people will just give up on it after a few tries. It is really complex, and easily solved in an ordinary function.

8:48 Fossi: the BDFL arrived (Keyword.java).

8:48 Fossi: AWizzArd: ah, excellent :) super assistent ;)

8:53 rhickey: (Keyword.java:25) if i read the javadoc right, putIfAbsent returns the old key if it already exists, so the check in :26 is unnecessary

8:54 rhickey: that being said we have a strange problem on the app engine where we time out in initializing. it happened to be twice in that line, so could it be some concurrency issue?

8:55 Chouser: AWizzArd: (map #(or (% 1) (% 2)) (re-seq #"(?s)(?:^|[,;])(?:BEGINTEXT[,;](.*?)[,;]ENDTEXT|(?!BEGINTEXT)([^,;]+))" x))

8:55 Fossi: ("it" happened: the timeout)

8:55 Chouser: now, who couldn't love a solution like that? :-P

8:58 ole3: hello, how do i check if a process is still running? (.exitValue process) ?

8:58 Fossi: brb

9:03 jdz: ole3: solutions to Java related issues can also be tried in #java

9:03 (i hope)

9:03 ole3: jdz: good idea, thank you.

9:04 AWizzArd: Chouser: let me test, one sec

9:05 Chouser: AWizzArd: (re-seq #"(?s)(?<=BEGINTEXT[,;]).*?(?=[,;]ENDTEXT)|(?<=^|,|;)(?!BEGINTEXT)[^,;]+" x)

9:05 there, without the map.

9:05 bstephenson: hello, have a quick question for the clojure experts, if I could

9:06 I have a vector of hours (e.g. [0 1 2 0 4 3]) and a map of that holds the totals hours in each day used already (e.g., {:day1 0 :day2 2 :day3 3 :day4 7 :day5 6}. Is there a straightforward way (or any way, really) to add the vector values to the map values such that the nth vector value gets added to the value of "day-nth" in the map? The map and vector counts will always be the same.

9:07 jdz: bstephenson: hardcoding day names in your map keys seems to be a bad idea (to me)

9:08 bstephenson: how would you approach it?

9:08 AWizzArd: Chouser: looks good. You were the first who made that. I gave that puzzle to some friends so far and they gave up.

9:09 jdz: bstephenson: but anyway, you can have a separate map which will give you vector indices when given day names

9:09 bstephenson: well, why not use vectors of hours or maps in both cases?

9:10 bstephenson: well, I was using the map to use the assoc function to update the value, but I think now that you are probably correct, two vectors will work better than a vec and a map, they will always have the same index.

9:11 jdz: thx

9:28 rhickey: Fossi: how is the check unnecessary? If the key was there I need to return the old one, if not the new one. I can't just return the result of putIfAbsent as it will be null if it wasn't there

9:30 Fossi: do you get a stack trace when you timeout?

10:08 liwp: Chouser: I think you need to add ENDTEXT to the negative lookahead as well

10:08 ,(re-seq #"(?s)(?<=BEGINTEXT[,;]).*?(?=[,;]ENDTEXT)|(?<=^|,|;)(?!BEGINTEXT|ENDTEXT)[^,;]+" "BEGINTEXT;foo;ENDTEXT")

10:08 clojurebot: ("foo")

10:09 liwp: Chouser: and thanks for all the effort you're putting into these regexp challenges, I'm learning a lot here

10:11 Chouser: ,(re-seq #"(?s)(?<=BEGINTEXT[,;]).*?(?=[,;]ENDTEXT)|(?=^|,|;)(?!BEGINTEXT)[^,;]+" "BEGINTEXT;foo;ENDTEXT")

10:11 clojurebot: ("foo")

10:11 liwp: maybe I messed up my copy pasting...

10:11 Chouser: oh, no, I think I did.

10:11 liwp: ,(re-seq #"(?s)(?<=BEGINTEXT[,;]).*?(?=[,;]ENDTEXT)|(?<=^|,|;)(?!BEGINTEXT)[^,;]+" "BEGINTEXT;foo;ENDTEXT")

10:11 clojurebot: ("foo" "ENDTEXT")

10:12 liwp: that's what I got earlier

10:12 AWizzArd: hmm

10:12 Chouser: the one I just pasted above is not right. please ignore it

10:13 AWizzArd: what is this (?s) thing with which it starts?

10:13 liwp: who knows ;-)

10:14 Chouser: liwp: yes, you're right. I had this in my command history, but somehow pasted the wrong one instead. I think this is right (and essentially the same as you have):

10:14 (re-seq #"(?s)(?<=BEGINTEXT[,;]).*?(?=[,;]ENDTEXT)|(?<=^|,|;)(?!BEGINTEXT)(?!ENDTEXT)[^,;]+" "BEGINTEXT;foo;ENDTEXT;bar")

10:14 the (?s) at the beginning says that . should also match \n for the rest of the regex

10:15 liwp: The other question mark stuff is related to lookaround: http://www.regular-expressions.info/lookaround.html

10:16 for those of us who didn't know how it all worked

10:17 Chouser: and if you ever think regex can't do something or other, keep this in mind: http://blog.n01se.net/?p=12

10:18 liwp: urgh, some people have too much time on their hands

10:19 AWizzArd: There is this programming language Malbolge ( http://en.wikipedia.org/wiki/Malbolge ) in which only "Hello World" was the only program ever written. And this hello world program was not written by a human, but by a Lisp program :)

10:20 If people really have a lot of time...

11:06 Fossi: rhickey: ah, ok, the documentation says it's equal to a if !contains, put else get, which would return the old one, so i didn't care to read the actual return documentation

11:06 a little inconsisten there

11:08 rhickey: is it ok if i pm you the stacktrace?

11:10 (as a paste link of course)

11:18 lpetit_: hello

11:18 I can't seem to get rid of reflection warning here, missing something trivial I think :(let [to-name-fn #(-> #^File %

11:18 .getPath

11:18 (str2/drop (inc (-> *builds-dir*

11:18 .getPath

11:18 .length)))

11:18 (.replace "/" "."))]

11:19 The last call to .replace generates a "call to replace can't be resolved."

11:20 .replace works on a String, and takes CharSequences as arguments. How can I indicate the "mutation" of the threaded argument ?

11:27 jdz: lpetit_: i'd try macroexpanding that form and look what's there

11:30 lpetit_: ,(macroexpand '#(-> #^File % .getPath (.replace "/" ".")))

11:30 clojurebot: (fn* [p1__2529] (-> p1__2529 .getPath (.replace "/" ".")))

11:31 jdz: seems to me that the type tag is lost

11:31 or maybe not

11:32 ,(macroexpand '(-> p1__2529 .getPath (.replace "/" ".")))

11:32 clojurebot: (. (clojure.core/-> p1__2529 .getPath) replace "/" ".")

11:34 cark: str2/drop must be returning an Object

11:34 so you could #^String (str2/drop ...

11:34 lpetit_: I'll try, thanks (was working on the wrong s-exp :-( )

11:36 weird, I tried it but still same warning

11:36 cark: mhh

11:37 *builds-dir* is untyped too

11:38 lpetit_: Reflection warning, /home/lpetit/*******_tests.clj:28 - call to replace can't be resolved.

11:41 cark: and when you run it you have no errors ?

11:42 could you paste your current code ?

11:42 lpetit_: currently trying to cut it down to the minimum

11:43 no error when running

11:43 Chouser: -> builds a new list for each step past the first

11:44 ,(binding [*print-meta* true] (prn (macroexpand '(-> a #^Integer (b)))))

11:44 clojurebot: (b a)

11:44 lpetit_: now that's interesting:

11:44 1:41 engine-tests=> #(.replace "/" ".")

11:44 Reflection warning, NO_SOURCE_PATH:41 - call to replace can't be resolved.

11:44 #<engine_tests$eval__250$fn__252 engine_tests$eval__250$fn__252@15d616e>

11:45 cark: mhh i know i resolved type warning within ->

11:45 lpetit_: I also remember this demonstrated on the ml

11:46 (note : working with clojure-1.0)

11:46 Chouser: -> could be patched to copy metadata from the given form to the produced one.

11:46 lpetit_: don't misinterpret : it's not working with clojure-1.0, I'm using clojure-1.0

11:47 ,(binding [*print-meta* true] (prn (macroexpand '(-> a (#^Integer b)))))

11:47 clojurebot: (#^Integer b a)

11:48 lpetit_: beh

11:49 Maybe we're not focusing on the right problem, see:

11:49 1:43 engine-tests=> (fn [] (.replace "/" "."))

11:49 Reflection warning, NO_SOURCE_PATH:43 - call to replace can't be resolved.

11:49 #<engine_tests$eval__262$fn__264 engine_tests$eval__262$fn__264@c5aa00>

11:49 Chouser: .replace needs 3 args

11:50 only 2 within ->

11:50 lpetit_: oh yes sorry

11:50 cark: chouser : indeed it's not working

11:50 lpetit_: so the goes back to the -> , of course

11:51 cark: anyways you could insert a str call juste before the (.replace

11:51 lpetit_: within -> it's normal the first is the threaded argument

11:52 so in my original example with ->, there are 3 arguments to .replace

11:53 Chouser: try (#^String str2/drop ...)

11:56 lpetit_: that's it !

11:58 I could also tackle it directly in clojure-contrib/str-utils2 : changing defs like (defn drop [#^String s n] into (defn #^String drop [#^String s n]

11:58 Chouser: str2 could use some hints splinkled around.

11:58 yeah

11:58 lpetit_: post collision :)

11:58 ok I'll do it

11:59 around the beginning of next week, it 6pm here in France, by guys

11:59 and thx for all

12:00 hiredman: AWizzArd: pong

12:44 * stuartsierra was listening, http://www.assembla.com/spaces/clojure-contrib/tickets/27

12:51 stuartsierra: commit 4b4f6ab5bcab58c4219eb50395bd366daea3ecc3: str_utils2.clj: added type hints for String return values; fixes #27

12:58 fsodomka: hi all!

12:58 couple days ago I saw discussion about new possible multimaps and their syntax... some time ago I played with Rebol, so I wanted to point out its syntax if anyone wants to get inspired...

12:58 Values: http://rebol.com/docs/core23/rebolcore-3.html#section-2

12:58 Evaluating Simple Values: http://rebol.com/docs/core23/rebolcore-4.html#section-4.2

12:58 and their use: Conditional Blocks: http://rebol.com/docs/core23/rebolcore-4.html#section-6.1

12:58 ... not sure if that helps...

13:30 * stuartsierra committed cdbfc8de57: test_is.clj: compatibility bridge to the new clojure.test; refs #26

13:54 Chouser: rathore: nice job posting! Sounds interesting.

14:01 cark: a sample executable jar build process using ant : http://github.com/cark/clj-exe-jar/tree/master

14:02 ~executable jar?

14:02 clojurebot: Pardon?

14:03 cark: ~executable jar is a sample executable jar build using ant : http://github.com/cark/clj-exe-jar/tree/master

14:04 hum

14:04 hiredman: :(

14:04 ababo: Hi there, please help me to figure out why casting to an interface is not working!

14:04 cark: clojurebot: don't do thhis to me !

14:04 clojurebot: Pardon?

14:04 ababo: ,(cast javax.script.Invocable (.getEngineByName (javax.script.ScriptEngineManager.) "js"))

14:04 clojurebot: nil

14:05 ababo: That returns ScriptEngineManager instead of Invocable

14:05 stuartsierra: Clojure is dynamic, no need to cast anything.

14:05 ababo: When I try to call a method of the interface it fails.

14:07 Chouser: ,(doc cast)

14:07 clojurebot: "([c x]); Throws a ClassCastException if x is not a c, else returns x."

14:08 ababo: Aha, got it, thanks!

14:08 cark: is there some good soul that would provide me with the equivalent linux clojure startup script for the sample project i just linked ?

14:08 stuartsierra: ScriptEngine isn't required to implement the Invocable interface.

14:09 cark: equivalent to run-clojure.bat

14:09 stuartsierra: cark: there are sample launch scripts in contrib

14:10 Chouser: cark: line 2 looks like it would work as-is -- what does line 1 do?

14:10 cark: i'm at home and don't have a linux handy. I wouldn't want to screw an example

14:11 chouser : line 1 changes current directory to the .bat file's directory

14:11 dmix: anyone recognize whats causing this error? http://gist.github.com/177119 I can't decipher it

14:13 cark: dmix : maybe show us the code that produces the error ?

14:16 hiredman: ~executable jar is a sample executable jar build using ant : http://github.com/cark/clj-exe-jar/tree/master

14:16 clojurebot: Ok.

14:16 hiredman: ~executable jar

14:16 clojurebot: executable jar is a sample executable jar build using ant : http://github.com/cark/clj-exe-jar/tree/master

14:16 cark: hiredman : thanks !

14:16 ababo: My bad, method name is .invokeFunction but the example code has .invoke

14:16 Thanks for the input!

14:20 Chouser: #!/bin/bash

14:20 cd "$(dirname $0)"

14:20 cark: Those two lines instead of your first should do it.

14:20 cark: chouser : ok and the filename should be run-clojure.sh ?

14:21 Chouser: you could leave of the .sh, but sure.

14:21 cark: i'm a linux ignoramus

14:21 ok thanks

14:21 hiredman: :(

14:22 #!/bin/sh

14:22 #!/bin/bash is horrible

14:26 hoeck1: cark: and split paths on the java -cp line with a colon instead of a semicolon

14:26 Chouser: hiredman: oh? what OS do you use?

14:26 cark: ah yes indeed !

14:26 Chouser: hoeck1: oh, good catch -- I missed that.

14:26 hiredman: $() is a bash thing anyway -- /bin/sh wants me to use backquotes or something.

14:27 hiredman: Chouser: $() is a sh thing

14:27 I use an OS that does not come with bash, and addon software doesn't get installed in /

14:28 Chouser: hiredman: so... not linux. :-)

14:28 cark: i think any linux user picky enough to want one or the other should be able to make the change

14:29 hiredman: cark: #!/bin/sh

14:30 cark: haha looks like i have to make a vm to test this anyways =/

14:31 hiredman: two characters, and suddenly your shell script will run on any unix

14:39 rsynnott: and you'll want the permissions to be right

16:03 kotarak: Chouser: thanks for for!

16:21 hiredman: http://www.scala-lang.org/node/3069 "He found that it is, on average, 30% faster to comprehend algorithms that use for-comprehensions and maps, as in Scala, rather than those with the iterative while-loops of Java."

16:23 ankou: hi, I just read the chapter about lazy sequences in Programming Clojure and I am surprised that lazy sequences use normal recursion instead of tail-recursion but seam to work with large numbers as well? why? or is this a missunderstanding?

16:24 hiredman: ankou: sort of

16:24 lazy-seqs sort of recur

16:25 but the recursion and stack depth are controled by sequence consumption

16:25 kotarak: ankou: when the recursive call happens the original call, where the recursion was "started" already returned. So there is no build up of stack frames

16:25 hiredman: so if you consume the sequence, but throw away the parts you have already seen, you don't consume space

16:25 kotarak: you can still blow the stack by piling eg. map on map on map on map ...

16:27 And - man - cl-format sure is on steroids...

16:34 Chouser: kotarak: I didn't write 'for', it's all I can do to understand it just enough to tweak a bit here and there.

16:34 but you're welcome for the chunked version. It was hard!

16:38 This has gotten a bit interesting recently: http://github.com/richhickey/clojure/graphs/impact

16:40 kotarak: github doesn't like me. :( The network graph for contrib seems frozen for days now. :(

16:41 The small fixes could use some turbo. :|

16:43 rhickey: Chouser: neat, I'd never seen that view

16:44 Chouser: rhickey: btw, the finger tree paper does define deque ops, tail-l and tail-r. I just missed them somehow.

16:45 rhickey: oh, good

16:46 Chouser: so split is only useful or needed for annotated (measure/reduce) tree.

16:46 rhickey: okasaki famously left out delete from his example red black tree

16:46 Chouser: heh

16:48 someone asked me last night why you didn't do finger trees in the first place. I had some guesses, but didn't know.

16:48 instead of vectors, I suppose.

16:48 rhickey: so I wonder - how important are the annotated versions?

16:48 finger tress are unlikely to touch the perf of the vectors

16:50 Chouser: annotations can give you random-access, priority queues, ordered sequences...

16:51 also I suspect some clever application-specific uses. For testing I'm using the str fn for both measure and reduce, so I always have a correctly-ordered string representation of the whole collection.

16:51 rhickey: neat

16:52 reigy working ok for you?

16:52 reify

16:52 Chouser: not there yet.

16:52 probably start trying to use it this weekend.

16:53 the transition from haskell-ish to clojure is big enough by itself. I wanted to get a taste of that before I tried to figure out the right way to use reify.

16:54 rhickey: makes sense

16:54 Chouser: do you have a gut feeling about whether a node of 2 to 4 items should be an array of 4, an array of needed size, or 4 separate fields?

16:55 oops, gotta go. I'll read the history later...

16:56 rhickey: Chouser: do the node of different N have different behavior? If you look at the different Clojure data structures you'll see a lot of Node polymorphism

17:03 lpetit: stuartsierra: hi, I saw you were quicker than me to add missing type hints on c.c.str-utils2 :)

17:03 would you mind applying them on the compat branch, also ? (I didn't check, maybe already done ?)

17:13 stuartsierra: lpetit: ok

17:17 ok, done

17:18 Chouser: rhickey: ah, I hadn't thought of that. I'll have to look again to see how transients are done now.

17:18 lpetit: stuartsierra: thanks a lot!

17:19 rhickey: Chouser: not just for transients, see e.g. PersistentTreeMap

17:20 Okasaki's pattern matches turned into polymorphic dispatch

17:23 lpetit: stuartsierra: did not see the commit yet

17:24 stuartsierra: did you make "clojure-contrib behaviour breaking changes" on the clojure-1.0-compatible branch ? (templating system, etc.)

17:27 stuartsierra: I thought clojure-compatible was not only compatible with also clojure-1.0, but also just a maintenance branch of clojure-contrib, so that people know they have a "1.0 with no breaking changes clojure/clojure-contrib" duo ?

17:29 stuartsierra: note that importing new functionality does no harm, but sometimes it has side effects as importing newer (incompatible ?) versions of some other dependencies ...

17:31 stuartsierra: Wait, did I just break the git repo?

17:32 lpetit: no, I did not (intentionally) make any behavior-breaking changes

17:33 lpetit: stuartsierra: ok, glad to have been able to catch it, then.

17:36 stuartsierra: woops, you pushed 110 commits from master to compat branch

17:36 stuartsierra: Damn.

17:36 How the heck did that happen?

17:37 lpetit: stuartsierra: you did some sort of merge instead of a cherry pick

17:37 stuartsierra: probably

17:37 stuartsierra: Great. Now I have to figure out how to fix that.

17:38 lpetit: stuartsierra: let's think about it together

17:38 stuartsierra: Anybody know how to fix this

17:40 lpetit: ok I'm pretty sure you did a merge (not a rebase) from what I can see from gitk

17:40 so it will be very easy to do the reverse change

17:40 stuartsierra: ok, just cloned a new copy of clojure-contrib

17:42 lpetit: it's just a matter of making the compat label point to the rev with comment "repl-utils: Fix init state for...", that is rev e0080e640a2d9b79

17:42 now we must find the appropriate command :)

17:44 stuartsierra: yeah

17:45 lpetit: the simpler could be to do a git reset ...(options to determine) and if you have commit rights, to push it. It will definitely delete the wrong commit.

17:45 stuartsierra: I think it was an older commit, though.

17:45 lpetit: If nobody tried to checkout or fetch compat in the time interval, nobody will be harmed

17:46 stuartsierra: let's go with that assumption

17:47 lpetit: ok, so enter git reset --hard e0080e640a2d9b79 in your clone

17:47 stuartsierra: They seem to diverge on "build.xml: run compile-clojure in headless..." 3073f0dc0614cb8c95f2debd0b7e6a75c1736ece

17:51 ok, did: git checkout origin/clojure-1.0-compatible

17:51 lpetit: no, chouser ported a correction in commit e0080e640a2d9b79

17:52 no, don't do that !

17:52 stuartsierra: ok, clearly I don't understand git as well as I thought I did

17:53 lpetit: I'm not 100% sure, but pretty sure it's a bad thing : it is intended as being a mirror of what is on the remote

17:53 I also have git repos for Counterclockwise, and work only on private trees that I push from time to time

17:54 on your fresh clone, switch to your local branch for compat, maybe you have named it compat, maybe something else, so type git branch to see all your branches, and once you've localised it, git checkout <theRightName>

17:55 then issue the command I stated previously : git reset --hard e0080e640a2d9b79

17:55 then try to push. If this does not work, there are some things in the configuration I don't master yet.

17:56 you'll finish in the spam black list of everybody :-p

17:57 drewr: are you guys trying to push to the public repo after a local git reset --hard?

17:57 lpetit: :-$

17:58 oups, caught

17:58 stuartsierra: We're trying to erase a bunch of commits that I accidentally merged into the clojure-1.0-compatible branch.

17:58 drewr: you would have gotten away with it if it weren't for a couple of commits that just came in from others :-/

17:58 stuartsierra: damn

17:58 now what?

17:59 lpetit: drewr: no the problem is on the compat branch of clojure-contrib

17:59 drewr: git rebase origin/master :-)

17:59 stuartsierra: No, master is fine. It's only the clojure-1.0-compatible branch that I messed up.

17:59 drewr: at this point it's probably best to just leave it alone

18:00 lpetit: compat branch has just the last merge commit wrong.

18:00 drewr: the history will be a little dirty, but that's ok

18:00 lpetit: Seriously, for the compat branch, no big deal to quickly correct this ?

18:00 stuartsierra: Assuming we can figure out how.

18:01 lpetit: (is it me that is saying that)

18:01 stuart, did you try my "instructions" ?

18:01 drewr: maybe the couple of msgs I saw were from you guys

18:01 stuartsierra: lpetit: not yet, hang on

18:02 drewr: as long as no one else has committed, you can "git reset --hard COMMIT_YOU_WANT && git push -f origin/clojure-1.0-compatible"

18:02 lpetit: I'll reproduce it locally too.

18:02 stuartsierra: Ok, starting fresh.

18:03 git clone git@github.com:richhickey/clojure-contrib.git

18:03 cd clojure-contrib

18:03 lpetit: git branch -r ; copy the name origin/clojure...compatible ...

18:04 stuartsierra: git checkout -b compat origin/clojure-1.0-compatible

18:04 lpetit: git checkout -b compat origin/clojure... ; compat will be the name of your branch

18:04 ok

18:05 stuartsierra: git reset --hard e0080e640a2d9b79

18:05 lpetit: now, the hard reset git reset --hard e0080e640a2d9b79

18:05 ok !

18:05 and the command from drew (thanks!)

18:05 stuartsierra: Now what do I push to?

18:05 "git push origin/clojure-1.0-compatible" ?

18:06 Or just "git push"?

18:06 lpetit: let's try that

18:06 the fully specified first

18:06 drewr: you'll likely have to push -f

18:07 because the histories don't agree

18:07 stuartsierra: "error: src refspec clojure-1.0-compatible does not match any."

18:07 lpetit: true

18:08 would -f help ?

18:08 drewr: not for that error

18:08 stuartsierra: same error

18:08 drewr: let me update and look aroudn

18:08 lpetit: based on the criteria of "shooting yourself on the feet", I would say git is way powerful than clojure :)

18:09 stuart : and just git push -f

18:09 if you still are in the compat branch, of course

18:09 drewr: stuartsierra: remove the slash

18:09 it should be "origin cloj..."

18:09 stuartsierra: did that

18:10 lispaste: url

18:10 lisppaste: url

18:10 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

18:10 drewr: you could do "git push origin :clojure-1.0-compatible && git push origin clojure-1.0-compatible"

18:11 that'll delete the branch and recreate it

18:11 lpetit: seems dangerous

18:11 stuartsierra: But git seems to be telling me that the branch doesn't exist in the first place

18:11 lisppaste8: stuartsierra pasted "Trying to push to github" at http://paste.lisp.org/display/86203

18:11 drewr: stuartsierra: what does "git branch -a" tell you?

18:12 lisppaste8: stuartsierra annotated #86203 "git branch -a" at http://paste.lisp.org/display/86203#1

18:12 lpetit: it may be because there are some implicit conventions, and since you did not give the same name to your local branch and the remote one, some more typing may be involved

18:12 drewr: ahh

18:12 stuartsierra: ah, pes

18:12 yes

18:12 Chousuke: you should not use -f to push

18:12 drewr: so you would do...

18:13 since your local branch is a different name

18:13 stuartsierra: stuart@wsgrhl700c3:/tmp/clojure-contrib$ git push -f origin compat:clojure-1.0-compatible

18:13 Total 0 (delta 0), reused 0 (delta 0)

18:13 To git@github.com:richhickey/clojure-contrib.git

18:13 + 69f810b...e0080e6 compat -> clojure-1.0-compatible (forced update)

18:13 Chousuke: if you use -f and push a branch that is not a descendant of the branch you're pushing to, you'll screw up other people's repos

18:14 drewr: Chousuke: that's what they're trying to do

18:14 stuartsierra: Chousuke: I know, normally I would not push -f, but in this case I already screwed up the repo and I'm trying to fix it.

18:14 Chousuke: ah, okay :)

18:14 drewr: stuartsierra: ok, so you got it?

18:14 stuartsierra: I think that did it. Look at http://github.com/richhickey/clojure-contrib/commits/clojure-1.0-compatible

18:15 lpetit: better, I'll do a fetch and see locally :)

18:15 drewr: looks good here

18:16 lpetit: yeah

18:16 fiouu

18:16 stuartsierra: ok, phew

18:16 drewr: git log -1 --pretty=oneline

18:16 e0080e640a2d9b79564a3fb6eb7ee36be1882901 repl-utils: Fix init state for add-break-thread!

18:16 lpetit: oh sorry phew is fiouu in french :)

18:16 yes that's what we wanted

18:16 stuartsierra: fiouu is a better spelling, anyway :)

18:17 lpetit: so now, stuart, please man git-checkout :-)

18:17 no, man git-cherry-pick


18:17 ;-)

18:17 stuartsierra: yeah, I still don't understand it. I did cherry-pick then push, what could be simpler?

18:18 lpetit: oh

18:18 stuartsierra: Wait, I know.

18:18 I did "git checkout -b compat" without specifying which branch to track, so I got the master branch.

18:18 Then pushed it back.

18:19 lpetit: yes, but how come it was then checked in the compat branch ?

18:19 do you stil have the history of the commands?

18:19 Chousuke: hmm, yeah, master is still a descendant of the compat branch, is it?

18:20 lpetit: no, Chouser commited something on July

18:20 stuart, it work, the reverse spamming has begun :)

18:20 it works

18:21 stuartsierra: yay

18:22 lpetit: so now, let's try the cherrypick ? :-) git checkout compat && git cherry-pick -x 4b4f6ab5bcab58c4219e

18:23 stuartsierra: no, I'm going home. I'll try the cherry-pick when I'm more awake

18:23 lpetit: if it's possible to do this as a patch I can do it and then attach it to the issue

18:23 at your convenience

18:24 Chousuke: well you can always do the cherrypick yourself and then use git format-patch

18:24 the end result will be the same.

18:24 stuartsierra: That won't help, will it? I (or someone) still have to push to the right branch.

18:24 I just have to get good with git.

18:25 lpetit: ok, so we'll let this as an exercise for the reader :)

18:25 stuartsierra: yeah, g'night folks

18:25 Licenser: I think it is great to have those videos

18:25 lpetit: g'night

18:26 Licenser: night lpetit

18:31 drewr: whenever I'm about to venture into uncharted territory with git I always create a test repository, clone it, try whatever on the clone, and then push

18:32 you can do that in /tmp in 5 min

18:32 and they're both gone

18:32 (lpetit and stuartsierra that is)

19:53 JAS415: is there a way to match and replace a string without java doing the regex machinations?

19:58 Chouser: what's wrong with Java doing it? I like contrib str-utils2/replace

20:01 dmiles_afk: are some you guy s masters at understanding verify errors?

20:01 javaclassloader verify errors that is

20:02 does clojure use invokeinterface ? or just invokevirtuals?

20:03 (thats eigther only invokevirtuals vs both)

20:10 ah it uses a private copy of ASM whichmakes it more transparent

21:39 lowlycoder: is there a macro for scheme-like define in clojure? one that acts more like letfn than defn? (i.e. define the function in the local lexical environment~ not the global one)

21:42 cemerick: lowlycoder: I *think* so. I remember someone asking something very similar, and there was either something in place, or perhaps in contrib?

21:42 * cemerick was never a schemer :-/

21:43 lowlycoder: not finding it grepping for "define " in clojure-contrib

21:43 JAS415: hmm

21:43 how do i replace a $ with an escaped $ in a string?

21:43 lowlycoder: then again~ i'm running clojure 1.0.0 with the relevant clojure-contrib

21:43 JAS415: with a regex

21:44 you could just use letfn all over

21:44 lowlycoder: no; i have the indenting

21:44 s/have/hate

21:45 JAS415: oh, indenting

21:45 you could make a macro

21:46 tomoj: lowlycoder: didn't we already talk about this?

21:46 lowlycoder: yes; we concluded that clojure and scheme are different

21:47 tomoj: also that a macro for the inner defines alone wouldn't help

21:47 you'd need to use a macro for the toplevel form

21:47 lowlycoder: of course not

21:47 right

21:47 this looks like a messy job

21:47 and also screws up debugging support

21:47 (like mismatching of source code lines)

21:48 so i'm hoping someone else has handled this already

21:48 tomoj: macros mismatch source code lines?

21:48 cark: lowlycoder : are you looking for letfn ?

21:49 lowlycoder: no~ i'm looking for a macro that ends up writing letfn

21:49 JAS415: um

21:49 lowlycoder: s/writing/calling

21:49 cark: what's the local envioronment you're talking about ?

21:50 JAS415: i forget how define in scheme works

21:50 tomoj: I think you would need to macroexpand all the forms in the body, take the initial segment that start with def, and then turn those into a letfn that you wrap around the rest of the body

21:50 or if you use "define" in the inner defines as well, it would be even easier

21:50 JAS415: upi cam

21:50 cark: oh i see now

21:50 JAS415: you can't just use let

21:50 lowlycoder: cark: it's hard to explain unless you use scheme; it's obvious if you do

21:50 JAS415: ?

21:51 cark: i got it now

21:51 JAS415: let = define..

21:51 we're talking about lexical scope?

21:51 lowlycoder: yes

21:51 cark: i don't think you can access the environement from a macro in clojure

21:52 tomoj: sure you can

21:52 just have the macro produce a letfn

21:52 cark: right but he wants to have the "define" valid after it is err ... defined

21:53 tomoj: that's why you need a macro

21:53 lowlycoder: cark: there we go :-)

21:53 tomoj: it needs to convert those into a proper letfn

21:53 JAS415: have the define valid after is define

21:53 cark: but how would your macro know what are the next forms

21:53 JAS415: hum

21:53 tomoj: it's just the rest of the body

21:54 all the forms in the body besides the initial segment which start with "define"

21:54 JAS415: hmm

21:54 well idunno

21:54 it sounds like a lot of work to reimplement scheme :-P

21:54 cark: that's what he wants (def bleh [] (define somefunc (fn [] (println "hello")) (somefunc))

21:55 tomoj: cark: no, the new macro goes at the top level

21:55 (define bleh [] (define somefunc (fn [] ...)) (somefunc))

21:56 in that case the toplevel define can take the initial segment of forms starting with "define" it its body and convert them into a letfn, then wrap that around the rest of the body

21:56 cark: ah in this case the define macro could walk the code and do it, yes

21:56 tomoj: you're right, seems impossible to add inner defines to defn

21:57 cark: but i don't like it, because the semantic of the outer define is not the same as the inside one

21:57 tomoj: well you could name it whatever

21:57 cark: mhh no scratch that

21:58 it would be ok as the outer lexical scope is the namespace

21:58 tomoj: to really get this working like scheme you would have to define new versions of fn, let, letfn, defn

21:58 lowlycoder: where is richhickey?

21:58 tomoj: since inner defines can be used in all the scheme equivalents

21:58 lowlycoder: i want to hear his reasons for changing this

21:59 tomoj: changing it?

21:59 cark: well i want to hear your reasons to have it your way =P

21:59 tomoj: did clojure support inner defines at one time?

21:59 lowlycoder: yeah~ for making the semantics of defn clojure != scheme define

21:59 tomoj: clojure did not derive from scheme...

21:59 lowlycoder: all languages derive from scheme

21:59 tomoj: hah

21:59 JAS415: no

21:59 cark: hehe

22:00 JAS415: all languagse derive from fortran

22:00 :-(

22:00 fortran and algol

22:00 lowlycoder: all langauges derive from waving a magnet over a harddrive

22:00 JAS415: :-( :-(

22:00 tomoj: I mean it's not like he took scheme and then said for each feature, "hmm.. should we keep this feature or change it?"

22:01 JAS415: how do i replace a $ in a string with an escaped $?

22:01 i've got this far

22:01 (.replaceAll "$324" "\\$" "\$")

22:02 (.replaceAll "$324" "\\$" "\\$")

22:03 this far

22:03 Chouser: ,(.replaceAll "$324" "\\$" "\\$")

22:03 hiredman: oops

22:03 JAS415: it returns $324

22:03 tomoj: ,(.replace "$324" "$" "\\$")

22:03 clojurebot: "\\$324"

22:03 JAS415: but i'm guessing i want \$324

22:03 so i try to escape it

22:04 hiredman: you have to \\\\

22:04 ,(.replace "$324" "\\$" "\\$")

22:04 clojurebot: "$324"

22:04 hiredman: ,(.replace "$324" "\\\\$" "\\$")

22:04 clojurebot: "$324"

22:04 hiredman: ,(.replace "$324" "\\\\$" "\\\\$")

22:04 clojurebot: "$324"

22:04 JAS415: ,(.replaceAll "$324" "\\$" "\\\\$")

22:04 clojurebot: java.lang.StringIndexOutOfBoundsException: String index out of range: 3

22:04 JAS415: oh i need 5

22:04 okay

22:04 i was trying 4

22:04 tomoj: I must not understand what you're trying to do..

22:05 you want to replace "$" in a string with "\\$" ?

22:05 JAS415: well i got this string, which i'm going to use in a regular expression...

22:05 which i pulled from an 'unknown source'

22:05 so the internets

22:06 and it comes back something like "Blahblah $60,000"

22:06 hiredman: ,(.replace "$324" "$" "\\$")

22:06 clojurebot: "\\$324"

22:06 hiredman: like that?

22:06 JAS415: wow

22:06 exactly like that

22:06 there's a plain old replace?

22:06 nice

22:06 tomoj: das hab ich auch gesagt..

22:06 Chouser: oh, use \Q

22:06 ,(re-seq #"\Q$1" "$1")

22:06 clojurebot: ("$1")

22:09 wtetzner_: is there a function to check if a value is contained in a sequence?

22:09 i know there is contains?, but that checks if a key exists in something associative

22:09 JAS415: nice (.replace works perfectly

22:09 Chouser: if you can use a set instead of a sequence, your life will be easier

22:09 JAS415: i'll have to look up \Q

22:10 wtetzner_: oh, that should be ok

22:10 thanks

22:10 hiredman: calling .contains is much faster than creating a set and testing for set membership

22:11 fyi

22:11 cemerick: so, I've got this lib whose most significant hotspot is isa? and friends

22:12 I did a bunch of profiling, and supers (and to a much lesser extent, bases) is the fundamental culprit

22:12 wtetzner_: oh, thanks hiredman

22:12 so is .contains part of the collection interface, but doesn't have a corresponding clojure function?

22:12 cemerick: I memoized supers, and got a very large factor speed improvement -- perhaps up to an order of magnitude, but I haven't taken a precise measurement

22:13 (memoizing bases helped a little more, but was far less impactful)

22:13 Does it seem like memoizing supers (+ bases, perhaps) is a good idea in general?

22:14 I'm thinking that using a WeakHashMap would be more correct, so as to allow dead classes to go away, etc.

22:14 hiredman: cemerick: if your hierarchs are not java classes, it seems like they can be mutated

22:14 cemerick: hiredman: bases and supers are only concerned with classes and interfaces

22:14 hiredman: oh

22:14 of course

22:15 cemerick: so, I'm thinking that this might be a safe optimization to apply, but I'm unsure of any impact on touchy module systems

22:15 * cemerick squints at osgi

22:15 cemerick: ...and any other things I'm not thinking of.

22:15 One way or the other, the perf improvement is very significant.

22:16 anyway, I'm going to write some results up for a msg to the group, but I wanted to see if anyone had any immediate reasons why this would be a bad idea

22:17 hiredman: I wonder how good Class's .hashCode is

22:18 cemerick: hiredman: it doesn't override it

22:19 which I *think* is good in this case

22:19 e.g. if a new version of a class with the same name as another comes into supers/bases, it'll get its bases/supers recalculated

22:19 that might actually be what saves me with the module systems

22:19 cark: the usage of isa? that needs to be optimzed, is it in a loop under your control ?

22:20 cemerick: cark: yes, but the size of the dataset isn't

22:21 cark: you could (binding [super (memoize super)] ...] ...) around your loops maybe ?

22:21 or whatever function

22:21 cemerick: heh, that's sneaky :-)

22:21 but, if this is safe, I'd like to see it made available to everyone's code

22:22 cark: mhh i don't think it is safe, i wouldn't want that a default in clojure

22:22 some classes might be unloaded

22:23 cemerick: cark: that's why a weakhashmap would be more appropriate

22:23 Chouser: classes don't go away unless they're loaded by a classloader that goes away

22:23 cark: right

22:24 this is a pretty obvious optimization, don't you think the java people would have done that already if it was a good idea ?

22:24 cemerick: cark: the point is, using a weakhashmap would allow those unloaded classes to get collected as they would be otherwise

22:25 Chouser: the supers of a class can't change, can they?

22:25 cemerick: nope. (JDK 7 majick aside)

22:25 Chouser: until we get interface injection, or whatever it's called.

22:25 cemerick: right

22:26 cark: hum if there's one exception, that's it, you can't do it anymore

22:26 cemerick: OK, quick numbers. Before memoization, 17165ms. After memoizing, 2749ms

22:26 me likey :-)

22:28 cark: exception? Like java.lang.Exception?

22:28 cark: nope i mean like "an exception to the rule that you can do it"

22:28 like say jdk 7 =)

22:29 cemerick: oh, sure. If it's not safe, then that's it.

22:29 Chouser: well, you just need to know when to invalidate your cache

22:29 cemerick: jdk 7 is an externality until it actually exists in a meaningful way :-)

22:30 Chouser: yeah, I'd assume interface injection would come with some kind of notification mechanism we could hook into

22:31 Chouser: actually didn't they say you had to do the injection before doing anything else with the class?

22:31 cemerick: I don't know...

22:31 doesn't that defeat the point?

22:32 cark: are they trying to do something like c# extention methods ?

22:34 Chouser: ok, I remembered that wrong. Here's what I was thinking of: "For any given class and injectable interface, the injector method is called the first time the question arises whether the class implements the interface. (This could be an invokeinterface, an instanceof, or a reflective operation.) Just before the decision, the class is called an injection candidate."

22:34 cemerick: ah

22:34 after injection, does a new class get consed up and swapped in for the old?

22:41 hiredman: I hope not

Logging service provided by n01se.net