#clojure log - Jan 09 2009

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

0:31 danlarkin: Oh man I'm totally in the clojure zone right now

1:13 durka: is there an easy way to have a long .. form, but just bail out early and return nil if something in the chain returns nil?

1:15 vogelrn: durka: the only thing I can think of (although that isn't saying much) is to make a variation on the .. macro

1:18 durka: i might do that

1:21 i just wrapped the call to .. in a try and caught NullPointerExceptions

1:22 hiredman: heh

1:22 "maybe" be damned

1:23 durka: eh?

1:23 hiredman: "try" or "andand" or whatever they are calling it these days

1:24 http://andand.rubyforge.org/

1:24 durka: is bitbucket down?

1:25 Puzzler: I've been thinking again about "amb". Is it possible to implement amb without continuations? Does anyone here even know what I'm talking about :) ?

1:25 vogelrn: I do not :P

1:26 hiredman: sounds slightly familiar

1:27 Puzzler: http://gd.tuwien.ac.at/languages/scheme/tutorial-dsitaram/t-y-scheme-Z-H-15.html

1:27 durka: bitbucket responds to ping but i think apache crashed...

1:27 can someone confirm or is my computer acting up?

1:28 Puzzler: It's a very useful tool for writing search programs with backtracking.

1:28 It's also one of those things that's commonly used to show off something you can write in Lisp/Scheme that's hard to write in other languages.

1:32 hiredman: interesting

1:41 vogelrn: Puzzler: it looks like it's possible, but more complicated. Isn't it basically just a depth first traversal of the options?

1:42 hiredman: no

1:42 vogelrn: oh?

1:43 Puzzler: vogelrn: It's related, but the way (amb) jumps back and retries the last choice point with a different option makes it tricky to implement.

1:43 hiredman: without contiuations I dunno how you could do it

1:43 Puzzler: How do you break out? By raising an error? That doesn't quite work. How do you capture the remaining computation?

1:45 I think it might be possible to implement a variation that obeys a certain kind of scoping. Not quite the same, but maybe just as useful for the common case.

1:45 hiredman: maybe you could do it with some kind of abstraction over (try (catch))

1:46 * durka wonders if CL conditions could handl it

1:46 durka: andle

1:46 fail

1:46 hiredman: clojurebot: just a little bit?

1:46 clojurebot: 1

1:47 durka: clojurebot: how 'bout a zero bit?

1:47 clojurebot: 1

1:47 Puzzler: It's hard to figure out how to make something like this work: (defn pick-a-digt [] (amb 0 1 2 3 4 5 6 7 8 9))

1:48 hiredman: clojurebot: amb is http://gd.tuwien.ac.at/languages/scheme/tutorial-dsitaram/t-y-scheme-Z-H-15.html

1:48 clojurebot: 'Sea, mhuise.

1:48 Puzzler: It's easier to imagine a form that works like let: (amb [x (range 10)] (if (< x 8) (amb-fail) x)))

1:49 hiredman: yes

1:49 Puzzler: My 9 ) turned into a emoticon 9)

1:49 8)

1:49 I mean 8 )

1:51 hiredman: (amb-fail) could just throw an exception

1:52 Puzzler: Right, and that might work for the one that works like a let form. But in the first case, imagine amb is a macro that tries to catch an amb-fail exception. In that block of code, there is no exception. The exception will be thrown somewhere completely different that isn't scoped as part of this code.

1:53 hiredman: yeah

1:53 I know

1:54 Puzzler: What interests me the most about this problem is that if I can implement amb, I'd like to see if I can leverage Clojure's agent system to create a new variant that explores various branches on different threads. I think it could be a very cool way to do search.

1:54 hiredman: man

1:54 my fingers are itching now

1:55 hmmm, and vim has stopped working

1:56 vogelrn: it might just be that I'm tired, but I'm still having trouble seeing how it isn't equivalent to depth-first search on a tree

1:58 you go down a branch, and if you encounter failure, you backtrack to the last place you had another option

1:59 Puzzler: The order in which the various choices are searched is equivalent to a depth-first search. But the way in which you express the choice points, and the rejection of choices, in your code, is very flexible, making it a pleasant way to code such things.

2:00 For example, at the REPL, I can say something like (def a (amb 1 2 3)). As I work with a, for now it will be 1. Later, I can just type (amb) at the prompt, and it will automatically go back and redo everything I've done as if earlier I had defined a to be 2.

2:02 durka: that sounds really hard to do without a continuation

2:03 Puzzler: i wonder if maybe there's a way to take advantage of the transaction system to record a "choice point". But transactions don't really nest; inner transactions are essentially a no-op.

2:03 So no way to create a hierarchy of choice points with that technique.

2:05 vogelrn: would it be correct to say that amb is taking advantage of continuations as an implicit tree structure?

2:08 Puzzler: I think it's usually implemented where each time you do amb, it takes a continuation and stores it on a stack. When amb fails, it pops the most recent continuation off the stack and resumes with another choice. So it's the combination of the stack and the continuations that gives you the tree structure.

2:09 durka: i mean, at the REPL you're looping so even if you throw something like an exception there's nothing to unwind

2:09 vogelrn: ok, just making sure I understood

2:11 the way I see it you would either have to use an explicit tree structure or find another language feature capable of expressing it implicitly, neither of which seems very palatable :P

2:12 Puzzler: I think the let version might be doable though. I'll have to think more about it. Anyway, I've gotta run. Good chatting with y'all!

2:13 vogelrn: whatever it is it's going to be very hackish

2:13 you too, I'm out as well

2:14 durka: apparently i have 19,947 unique classes on my classpath

2:29 that was incorrect, a bug excluded clojure.jar

2:29 there are 25,814 classes

2:30 Gorilla=> (lookup "Ref")

2:30 ["com.sun.xml.internal.bind.v2.model.core.Ref" "com.sun.xml.internal.bind.v2.runtime.reflect.opt.Ref" "com.sun.xml.internal.xsom.impl.Ref" "java.sql.Ref" "sun.misc.Ref" "clojure.lang.Ref"]

2:30 hiredman: ,(identity *ns*)

2:30 clojurebot: #<Namespace sandbox>

2:30 hiredman: ,(amb [v (range 1 8)] (if (not= 8 v) (throw (Exception. "not an eight")) v))

2:30 clojurebot: 8

2:33 durka: ,(amb [v (range 1 8)] (amb [w (range 7 0 -1)] (if (not= v w (throw (Exception. "not equal"))))))

2:33 clojurebot: java.lang.Exception: Too few arguments to if

2:33 durka: whoopa

2:33 hiredman: lisppaste8: url?

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

2:33 durka: ,(amb [v (range 1 8)] (amb [w (range 7 0 -1)] (if (not= v w) (throw (Exception. "not equal")))))

2:33 clojurebot: nil

2:34 hiredman: hmmm

2:34 not a very clean macro

2:34 durka: ,(amb [v (range 1 8)] (amb [w (range 7 0 -1)] (if (not= v w) (throw (Exception. "not equal")) v)))

2:34 clojurebot: #<core$range__3485 clojure.core$range__3485@141e00a>

2:35 durka: er

2:35 hiredman: nesting is a no go

2:36 lisppaste8: hiredman pasted "amb, embaressing attempt 1" at http://paste.lisp.org/display/73311

3:01 hiredman: ,(amb [v (range 1 8)] (amb [w (range 7 0 -1)] (if (not= v w) (throw (Exception. "not equal")) v)))

3:01 clojurebot: 1

3:01 lisppaste8: hiredman annotated #73311 with "try #2" at http://paste.lisp.org/display/73311#1

8:19 jpcooper: hello

8:19 does anyone know about getting Clojure running with j2me?

8:20 I'm interested in writing programmes for my mobile phone

9:10 ole3: hello i like to specialize methods on types, this works for strings as in the example on the homepage, but i can not specialize on keywords. Is it posible to specialise a function on keywords?

9:11 rhickey: ole3: sure

9:11 you want to say (foo :fred ...) and have that do something different from (foo :ethel ...) ?

9:12 ole3: nope

9:12 rhickey: then what?

9:12 ole3: i want to say (foo string ...) to be different from (foo :keyword)

9:12 I get an exeption: No method for dispatch value

9:13 rhickey: you've done (defmulti foo class)?

9:13 ole3: yes

9:13 (defmethod foo keyword [k] ...)

9:13 rhickey: (then defmethod foo clojure.lang.Keyword [k] ...)

9:13 ole3: ;)

9:14 thank you!

9:14 kotarak: ole3: (class :foo) helps in such a case to find at the correct dispatch value...

9:15 ole3: i see!

9:40 leafw: simple problem, hard solution: suppose I have a vector or list [a b c d e] and now I want to take d and put it after a: [a d b c e]. What is the proper, easy way to do so?

9:42 AWizzArd: To my knowledge Clojure does not yet offer a function to do this. Even no vdelete and vinsert are availble. So you will manually have to remove and insert that element.

9:43 leafw: AWizzArd: then I have to implement my own vdelete and vinsert ..

9:43 AWizzArd: leafw: or make it a hashmap with numbers as keys

9:43 leafw: AWizzArd: can't. I need to keep a list with no gaps in the numeric keys.

9:43 AWizzArd: {0 a 1 b 2 c 3 d 4 e}

9:43 leafw: i.e. inserting one new element would mean shifting all keys

9:44 or adding a floating point key

9:44 its a list of objects to be painted in stack order, because they overlap.

9:44 gnuvince_: leafw: how would you make the function call?

9:45 AWizzArd: leafw: (apply hash-map (interleave (range (count your-vector)) your-vector))

9:45 leafw: I would pass the element to shift, plus a numeric shift value: -1, -2, 6, etc. relative to its current position. If it goes beyond first or last, then make it first or last respectively.

9:45 AWizzArd: then you can use assoc and dissoc

9:48 leafw: there must be an easier way. Keeping a hash map would mean dissoc first, assoc with a floating point key, sort by keys, get vals, make new vector, interleave with range, make new hash map ...

9:48 that reads is overly complicated.

9:48 hiredman: (doc sorted-map)

9:48 clojurebot: keyval => key val Returns a new sorted map with supplied mappings.; arglists ([& keyvals])

9:49 gnuvince_: leafw: have you considered alternative ways to accomplish the higher level task you want to do?

9:50 leafw: gnuvince_: I confess I used to do this with an array, where positions are swapped easily.

9:50 gnuvince_: but resizing arrays is a pain

9:51 hiredman: the sorted map doesn't solve much, still need floating point keys, which may become unmanageable.

9:51 I know I can solve this, I am just exploring how could one solve it easily and elegantly

9:51 gnuvince_: leafw: cause it looks like there's no easy solution for this

9:51 hiredman: leafw: after you munge the map, you can turn it back into a vector

9:51 and loose the keys

9:52 gnuvince_: And although I have no proof of that, my gut tells me that the implementation would be rather inefficient

9:52 leafw: hiredman: true. Then make it again .. every time

9:52 hiredman: *shrug*

9:52 leafw: with cons cells one should be able to do it

9:52 AWizzArd: leafw: you could use a doubly linked list

9:52 hiredman: how many objects are you painting?

9:53 AWizzArd: There you could move elements around pretty efficient. But random access is not so fast as in vectors of course.

9:53 leafw: hiredman: from 0 to thousands

9:54 AWizzArd: maybe java.util.LinkedList can help

9:54 leafw: AWizzArd: need to learn more about doubly linked lists

9:55 AWizzArd: would need to protect it in a private ref in any case ... could work

9:55 AWizzArd: leafw: http://java.sun.com/javase/6/docs/api/java/util/package-summary.html or specifically http://java.sun.com/javase/6/docs/api/java/util/LinkedList.html

9:56 leafw: AWizzArd: I know the java collections rather well, thanks :)

9:56 lisppaste8: jdz pasted "the put one thing after the other thing" at http://paste.lisp.org/display/73321

9:56 leafw: I was looking for a trivial solution in clojure

9:56 AWizzArd: leafw: does not exist yet

9:56 leafw: AWizzArd: one can only hope.

9:56 achim_p: hmm, is there a data structure that provides constant-time indexed access and fast inserts/deletes? none that i knew of.

9:57 leafw: achim_p: a doubly linked list, I guess. Removing is just remerging the prev with the next elements in the chain.

9:58 AWizzArd: the constant-time indexed access is not available with doubly linked lists

9:58 achim_p: leafw: lists have linear time access ...

9:58 leafw: achim_p: true

10:03 lisppaste8: jdz annotated #73321 with "a terminating version" at http://paste.lisp.org/display/73321#1

10:04 leafw: jdz: commendable, but I can't use it. Thanks in any case.

10:04 jdz: leafw: you can't use it because?

10:06 leafw: jdz: because the first time I described the problem improperly. Then I explained: I would pass the element to shift, plus a numeric shift value: -1, -2, 6, etc. relative to its current position. If it goes beyond first or last, then make it first or last respectively.

10:07 jdz: leafw: seems like a trivial change to the function to me

10:29 lisppaste8: jdz annotated #73321 with "oh those lazy young programmers" at http://paste.lisp.org/display/73321#2

10:31 jdz: i think i'll rather go do some projecteuler.net puzzles

10:39 Cark: hum this doesn't work anymore : (.showMessageDialog JOptionPane parent (if (nil? message) "null" message))

10:40 it says that JOptionPane has no showMessageDialog method

10:40 i guess because it's a static method

10:40 rhickey: .method is for instance methods only

10:40 Cark: what would be the correct syntax now ?

10:40 jdz: try .JOptionPane/showMessageDialog?

10:41 Cark: ah that makes sense

10:43 Lau_of_DK: Its (javax.swing.JOptionPane/showMessagedialog nil "Message")

10:43 Cark: yep that works, thanks all

10:45 Lau_of_DK: npz

11:32 knapr: how hard would it be to port Clojure to another platform? or create its own VM ?

11:34 rhickey: Chouser's ported a lot of it to JavaScript

11:34 Raynes: Hawt.

11:34 vsthesquares: that's nice

11:34 knapr: but bascially a lot of it is portbale right? the /src stuff. it is the java stuff that needs to be rewritten

11:34 rzezeski: rhickey, didn't you initially implement Clojure on both the JVM and .Net simultaneously, but then dropped the .Net impl because of time?

11:35 knapr: not that I want to Java interop is super. just asking

11:35 rhickey: rzezeski: yes

11:35 Raynes: rhickey: I totally want your autograph :p

11:36 vsthesquares: but why would you want to make yet another VM? there's enough duplication in effort going on as it is

11:37 knapr: ^^ as i said

11:37 just wondering

11:38 rzezeski: Not that I care for it to be implemented on another VM, but it could help for adoption in certain situations (say a .Net only shop)

11:38 knapr: but wouldnt they just choose F# ?

11:39 im getting into datamining more and more, generally heavy computational tasks and it looks like C++ is kind of needed a lot.

11:39 then

11:39 rzezeski: maybe, maybe not, but they may have no choice if Clojure is only on the JVM

11:39 vsthesquares: maybe we'll see a IronClojure one day ;)

11:40 Raynes: They wouldn't use F# because F# is a horrible mess.

11:40 :|

11:42 cooldude127: hey is there a way to declare function arguments to be type `int'?

11:42 rzezeski: Most any language is a horrible mess with a big enough microscope

11:42 cooldude127: as opposed to the boxed Integer

11:42 rhickey: cooldude127: no

11:43 knapr: cooldude: i think you can annotate inside a function to spped up though, not the same thing though obv

11:43 cooldude127: knapr: how do you mean?

11:43 optimization is the goal here

11:44 rhickey: is this because the difference between primitives and objects would require too much special code?

11:44 rhickey: cooldude127: but if you need to use them as such in a tight loop inside the fn, you can re-let them with type coercions: (defn foo [x y] (let [ (int x) y (int y)] ...))

11:45 sorry (let [x (int x)...

11:45 cooldude127: oh

11:45 rhickey: cooldude127: yes, fns have a uniform object-based interface

11:45 IFn

11:46 cooldude127: should i be fooled by the fact that at the repl, (class (int 5)) gives java.lang.Integer

11:46 ?

11:47 rhickey: cooldude127: primitives are not first-class objects, let of a primitive creates a primitive local, and hints can avoid boxing in arg calls, but whenever a first-class value is required it's going to be boxed

11:47 hiredman: clojurebot: amb is also http://paste.lisp.org/display/73311

11:47 clojurebot: You don't have to tell me twice.

11:47 cooldude127: rhickey: so i am fooled

11:47 hiredman: cooldude127: class is a function, so the int is boxed as it goes in

11:47 cooldude127: :)

11:47 got it

11:48 btw hiredman does your amb work?

11:48 cuz I was kinda trying a little while ago to implement that

11:48 hiredman: by not really being amb

11:48 cooldude127: and exceptions NEVER occurred to me

11:48 what do you mean

11:48 rhickey: primitive support is currently only local or into java methods

11:48 cooldude127: rhickey: got it

11:48 makes sense

11:49 rhickey: I have ideas about expanding IFn for a select set of primitive overloads...

11:49 hiredman: cooldude127: well, the real amb using continuations and allows for really weird stuff

11:49 my amb is just sort of, you know, flow control using exceptions :(

11:50 cooldude127: hiredman: well i tried doing the CL pseudo continuations from on lisp in clojure

11:50 and the lack of mutability made me give up

11:50 very different semantics

11:52 hiredman: actually as I was falling asleep last night a modification or two to try #2 occured to me, but nothing really major

11:52 cooldude127: i'm about to try out #2, see if it does the kinda stuff I wanted it for

11:53 oh i see this is a little different then amb from, say, arc

11:53 but i g2g

11:53 hiredman: I am sure it is

11:53 Chouser: we do have definline already

11:54 rhickey: Chouser: that still only helps going to Java methods

11:55 Chouser: or other inlines/macros?

11:55 rhickey: right, but must bottom out on method taking primitive to really help

11:56 The idea here would be to add some more overloads to IFn, for unary and binary int/long/float/double returning same type

11:56 then a fn variant that let you say it was a fn of ints/longs/floats/doubles

11:57 Object sign would map to primitive sig, for use in any unknown context

11:57 in known context, with known desire for primitive return, all-primitive sig would be called - no boxing

11:58 would help these silly microbenchmarks where people think Clojure recursion is slow but it's just the arg boxing

11:58 and the decomposition of math code into fns

11:59 needs desired return type inference not currently present

12:00 but could simply require coercions to signal - give me the primitive version

12:01 otherwise can't distinguish (f afloat) -> float from (f afloat) -> something-else

12:02 still thinking about it but mostly done (in my head at least) :)

12:02 Chouser: not just a smop

12:02 now just a smop

12:02 rhickey: smop?

12:02 Chouser: Simple Matter Of Programming

12:02 rhickey: yeh

12:02 and time

12:03 Chouser: generally used with some degree of facetiousness

12:03 rhickey: I'm working on getting my streams stuff up into a branch so people can play with it

12:03 Chouser: interesting.

12:04 thanks for you recent detailed treatment of non-caching seqs.

12:04 leafw: beyond assoc for a vector, are there any other vector-related utilities to find elements (any kind of index of?)

12:04 rhickey: Chouser: did it make sense?

12:05 leafw: vectors are Lists, so:

12:05 user=> (.indexOf [2 3 1 2] 1)

12:05 2

12:07 Chouser: I hadn't found the arguments for changing seq behavior to be terribly compelling, but your mention of functional generators "accidentally" hanging onto the previous head was enlightening

12:07 leafw: fantastic ... had just made a fn to do that

12:07 so, fully, java.util.List ?

12:08 rhickey: Chouser: that is the kicker, and a nasty thing to chase down

12:08 leafw: yeah

12:09 (ancestors (class [1 2 3]))

12:09 leafw: (ancestors (class []))

12:09 exactly.

12:10 zakwilson_: Is there a tool that's commonly used for profiling Clojure code?

12:11 rhickey: Chouser: my idea with the stream stuff is to get the basics up, with a few examples of streamified lib fns (map/filter etc), then if we get enough hands, we might be able to parallelize the effort and make them available sooner rather than later

12:11 leafw: hum, but .set doesn't work -- of course, wouldn't be persistent then

12:11 throws unsupported exception

12:12 rhickey: leafw: all of the mutation methods are optional and Clojure opts out

12:12 perfectly legal

12:12 :)

12:12 leafw: indeed.

12:13 rhickey: zakwilson: I use YourKit, not free but very nice

12:14 (actually it was free, YourKit generously donated licenses to Clojure)

12:16 zakwilson: rhickey: any plans to include basic profiling functions in Clojure itself?

12:16 rhickey: zakwilson: nope - the Java tools are great

12:17 zakwilson: I guess I need to learn my way around the Java ecosystem better then.

12:19 rhickey: zakwilson: yeah, Clojure emits the low-level stuff so Java debuggers and profilers work, yielding tools far more sophisticated than those of langs much older (than Clojure)

12:21 zakwilson: I'm used to CL and a little Scheme. I love Clojure the language. I'm still getting used to the Java world though.

12:22 rhickey: admittedly, it's not the same experience as say, CL debugging, but then I was a Lispworks customer for a few years before they had step debugging (Clojure has right now), and the Java profiling is fantastic

12:23 technomancy: I'm curious, what was the first real program (written for production use) in clojure?

12:25 achim_p: hmm, google groups confuses me. usually, i receive copies of emails i send to the group. not with this one: http://groups.google.com/group/clojure/browse_thread/thread/3db6cb2b71008e73

12:26 and it says "To <me>" instead of "From <me>" in the web view. weird - anybody else received it?

12:26 rhickey: technomancy: none I can talk about, but have several private reports, still a secret-weapon tech I guess :)

12:26 technomancy: oooh; secret-weapon tech... exciting. =)

12:27 rhickey: hopefully not for actual weapons :)

12:27 technomancy: I was thinking "the pen is mightier than the sword"-type weapons.

12:28 danlarkin: achim_p: I received it in my inbox with no abnormality

12:29 AWizzArd: If I want to make a Java Hashtable in Clojure, what is then the equivalent to

12:29 Hashtable<String, Integer> numbers = new Hashtable<String, Integer>();

12:29 achim_p: danlarkin: good, thanks! just wanted to check before re-posting

12:30 AWizzArd: or should I just say (def numbers (Hashtable.)) and make sure to have strings as keys and numbers as vals?

12:30 rhickey: AWizzArd: just leave out the <...> stuff, Java uses erasure

12:30 so at runtime they are all Hashtable <Object, Object>

12:31 that's actually a great feature for dynamic langs like Clojure

12:33 jpcooper: has anyone worked with Clojure and J2ME?

12:33 AWizzArd: yes

12:34 although it might be nice for speeding up access to specify the types as type hints

12:34 jpcooper: AWizzArd, was it quite simple?

12:34 AWizzArd: jpcooper: yes

12:34 oh, sorry

12:34 my "yes" was for rhickey

12:34 jpcooper: oh :(

12:34 AWizzArd: I think with the J2ME it's a bit problematic, as the ME has ridiculous memory limits.

12:35 jpcooper: shame

12:35 rhickey: AWizzArd: I don't think it would matter at all, the generic types are gone at runtime

12:35 AWizzArd: jpcooper: The clojure.jar is over one MB in size, but the ME allows only a few kb, like in the 1980ies.

12:35 I see

12:35 hiredman: also, j2me is old java

12:35 jdk1.4? maybe older

12:36 jpcooper: I wonder whether I could get some kind of embedded Scheme running on one of these phones

12:36 AWizzArd: A mobile phone that runs the full JRE would be nice.

12:36 Under those all Clojure apps should run...

12:36 technomancy: would that include Android?

12:37 hiredman: bleg

12:37 jpcooper: I have a Nokia 6500c. I believe that it runs Symbian

12:37 hiredman: android threw away the best part of java and kept the worst

12:37 (threw away the jvm and kept the java language)

12:37 technomancy: eww

12:37 nsinghal: (re-seq #"(.*\\n)|(.+$)" "jajd\nskdk") this used to split the string into "jajd\n" and "skdk"

12:37 it doesnt work now

12:38 hiredman: ,(.split "\n" "jajd\nskdk")

12:38 clojurebot: #<String[] [Ljava.lang.String;@119fc9e>

12:38 hiredman: ,(apply vector (.split "\n" "jajd\nskdk"))

12:38 clojurebot: ["\n"]

12:38 hiredman: oh

12:38 duh

12:38 ,(apply vector (.split "jajd\nskdk" "\n"))

12:38 clojurebot: ["jajd" "skdk"]

12:38 nsinghal: string.split removes the "\n" new line

12:39 hiredman: *tadda*

12:39 nsinghal: i want to preserve that

12:39 the desired results is "jajd\n" "skdk"

12:44 rhickey: nsinghal: you don't need double \s now: (re-seq #"(.*\n)|(.+$)" "jajd\nskdk")

12:49 nsinghal: rhickey: thx that works

12:51 lisppaste8: AWizzArd pasted "Hashtable Java vs. Clojure" at http://paste.lisp.org/display/73331

12:51 AWizzArd: rhickey: do you see a way how to speed up the code in Clojure here with type hints?

12:52 As I used the Java Hashtables in Clojure the difference in runtime efficiency could maybe be smaller than factor 40?

12:55 achim_p_: AWizzArd: (time (dotimes [i 1000000] (.put #^java.util.Hashtable x "vier" i))) ?

12:58 Chousuke: easier to do that when defing though.

12:58 (def #^java.util.Hashtable x ...)

13:00 danlarkin: yeah adding the typehint sped it up to about 100 ms on my machine, down from 2800ish

13:01 reflection'll kill ya

13:02 use (set! *warn-on-reflection* true) to see if the code you're writing has to use reflection

13:02 hiredman: isn't there some warn on reflection deal you can set?

13:02 ah

13:02 Chouser: necessary when writing applets

13:03 rhickey: you shouldn't worry about reflection unless called often

13:03 Chouser: or if you're writing applets. ;-)

13:04 achim_p_: Chousuke: shouldn't matter much. i ike the annotations close to method calls, find it easier to see what's happening

13:04 rhickey: Chouser: all reflection prohibited in applets?

13:04 AWizzArd: thanks achim_p_

13:04 achim_p_: now it funnily runs *faster* in Clojure ;-)

13:04 Chouser: rhickey: looks like it. I haven't proved it, but certainly some reflection is prohibited.

13:05 I can't use proxy-super in the Applet itself.

13:05 rhickey: anyone have an interesting applet or Android app yet?

13:06 Chouser: reflection of non-publics make sense to prohibit

13:06 leafw: Chouser: can't setAccesible(true) in appletS: throws a security violation exception of some sort

13:06 Chouser: rhickey: dunno if it counts as interesting: http://chouser.n01se.net/misc/tree.html

13:06 leafw: in Method and Field, that is.

13:06 technomancy: is there a way to look up all the methods of a Java object from the repl?

13:07 eyeris: (disclaimer: complete lisp newb here) Is (. (100) (toString)) the proper way to convert an integer to a string?

13:08 technomancy: eyeris: should be (.toString 100)

13:08 leafw: technomancy: (doseq [m (sort (.getDeclaredMethods (class your-ob)))] (println m))

13:08 technomancy: or (str 100)

13:08 hiredman: clojurebot: show?

13:08 clojurebot: show is clojure.contrib.repl-utils/show

13:08 technomancy: leafw: thanks!

13:08 hiredman: eyeris: (str 100)

13:08 technomancy: eyeris: if you put 100 wrapped in parens, it will try to call the function 100... which doesn't really make sense

13:09 hiredman: or

13:09 ,(.toString (Integer. 100))

13:09 clojurebot: "100"

13:09 eyeris: (str 100) seemed sensible to me but I got an exception (class java.lang.Integerjava.lang.IllegalArgumentException: No formatter for type: class java.lang.Integer

13:09 )

13:09 hiredman: erm

13:09 technomancy: right; that needs to be a Java Integer like hiredman said

13:09 hiredman: ,(str 100)

13:09 clojurebot: "100"

13:10 hiredman: works fine here

13:10 technomancy: for .toString I mean

13:10 str should work on anything

13:10 lisppaste8: rhickey pasted "applet error" at http://paste.lisp.org/display/73333

13:10 rhickey: Chouser: I get ^^

13:10 vsthesquares: I'm experiencing the same

13:10 eyeris: Oh, the , is meaningful?

13:10 I thought that was a typo :)

13:10 Chousuke: eyeris: what version of clojure do you have? :/

13:10 eyeris: Chousuke current svn

13:10 hiredman: clojurebot: latest?

13:10 clojurebot: latest is 1195

13:10 Chouser: rhickey: ah, yeah, sorry -- doesn't work on Mac. I haven't tried to figure out why.

13:10 technomancy: repl-utils/show doesn't have a docstring.

13:11 vsthesquares: eyeris: no, the comma just tells clojurebot to execute

13:11 leafw: technomancy: sorry, (doseq [m (.getDeclaredMethods String)] (println m))

13:11 hiredman: is that right? I think clojurebot's svn stuff is borked

13:11 technomancy: but it looks useful

13:11 hiredman: bah

13:11 it is

13:11 borked that is

13:12 Chouser: technomancy: yeah, that's not really acceptible, is it.

13:13 technomancy: Chouser: I'll see if I can figure it out and submit a patch.

13:14 it's actually... behaving pretty strangely for me. I show'd a date, then when I show'd an Integer it was telling me it had some of the Date's methods in there.

13:15 Chouser: technomancy: I've got it covered -- just a sec.

13:15 eyeris: Where can I find documentation for the `( form?

13:15 (the web site search breaks on that input)

13:16 vsthesquares: eyeris: http://clojure.org/special_forms

13:16 technomancy: Chouser: the docstring or the mixed Date/Integer return value?

13:16 lisppaste8: technomancy pasted "show strangeness (Date and Integer)" at http://paste.lisp.org/display/73335

13:16 Chouser: technomancy: the docstrings

13:17 eyeris: vsthesquares I see the '( form there but not the `( form. Does it have another name?

13:17 Chousuke: eyeris: syntax-quote

13:18 Chouser: technomancy: what kind of Repl are you using? that's really goofy.

13:18 technomancy: Chouser: just slime.

13:18 vsthesquares: eyeris: (= `(1 2 3) '(1 2 3))

13:18 technomancy: I can try to repro in the regular repl if you like

13:19 Chousuke: vsthesquares: ` and ' have crucial differences though.

13:19 vsthesquares: oh, I didn't know that

13:19 Chouser: technomancy: nothing "just" about slime. :-) The Integer members ought to be listed after "=== public final java.lang.Integer ==="

13:20 Chousuke: vsthesquares: in that case they produce the same output, but `(foo bar) is not the same as '(foo bar)

13:20 vsthesquares: interesting, is this documented somewhere?

13:20 Chousuke: yes

13:20 probably macros section.

13:20 eyeris: I found the ` docs here: http://clojure.org/reader

13:20 technomancy: Chouser: so do you need me to see if it happens outside of slime for me?

13:21 durka: Chouser: not reproduced in Gorilla repl

13:22 Chouser: technomancy: I can't reproduce it. Are you getting it consistently in Slime?

13:23 technomancy: Chouser: I'm consistently seeing output that makes sense for the previous thing I passed to show.

13:24 Chouser: technomancy: docstrings included in svn 358

13:24 technomancy: so if I show (0) a Date followed by (1) a Date followed by (2) an Integer followed by (3) an Integer, I'll see: (0) nothing (1) Date methods (2) Date methods (3) Integer methods.

13:24 ah, thanks

13:25 Chouser: with some typos fixed in 359 :-P

13:26 technomancy: yeah, please try in a plain terminal repl

13:26 technomancy: ok, will do

13:28 ok, can't repro there. will try a fresh slime instance

13:30 definitely reproducible in new slime instances. =\

13:30 Chouser: sounds like a slime bug to me. :-)

13:31 technomancy: heh. "Connected. Take this REPL, brother, and may it serve you well."

13:31 Chouser: 'show's not doing anything weird with the output, and certainly not hanging onto and state that would allow it to know what you used it on last.

13:31 danlarkin: I love the slime start messages

13:32 technomancy: maybe slime is doesn't expect lazy output or something.

13:32 Chouser: it's not lazy

13:32 I assume you don't have this problem with 'doc'?

13:32 technomancy: right... hmmm... printf flushes for you, right?

13:32 no, never had problems with doc

13:33 Chouser: the only salient difference I see is 'printf' instead of 'println'

13:33 eyeris: Does Webjure have any documentation accessible on the web?

13:33 clojurebot: svn rev 1202; Make syntax-quote Classname. and .method aware, patch from Meikel Brandmeyer

13:33 svn rev 1203; fixed Integer/LongOps.Negate overflow when MIN_VALUE

13:33 svn rev 1204; fix range with too large negative index, patch from Olov Lassus made Range implement count()

13:33 svn rev 1205; Report more incorrect usages of binding vectors, patch from Chouser

13:33 svn rev 1206;

13:33 hiredman: clojurebot: be cool

13:33 clojurebot: Pardon?

13:33 technomancy: oh... hang on. I do have strange things going on with doc sometimes. the output will appear where I don't expect it.

13:33 danlarkin: clojurebot: max people?

13:33 clojurebot: max people is 116

13:33 danlarkin: wrong!

13:34 hiredman: yeah, well, you knwo

13:34 technomancy: here's something interesting... when I first run show, I get only "=== public final java.lang.Integer ==="; no methods, but if I follow that with doc, it shows all the methods from the last call with the doc stuff tacked on the end

13:35 definitely a swank-clojure bug

13:38 hiredman: off hand, anyone know how to get a user count for a channel out of irssi?

13:41 Chouser: hiredman: /list #clojure

13:41 zakwilson: Is there a way to see how many elements of a lazy seq have been cached?

13:44 Chouser: zakwilson: I don't think so.

13:44 that information appears to be private and unaccessible inside LazyCons

13:44 * zakwilson thinks it would be a useful feature.

13:44 Chouser: I wonder if it would be considered "dangerous"

13:45 it mutates of course, so you could have races and stuff in your otherwise beautifully immutable collection.

13:45 zakwilson: I can't see how being able to read that would hurt anything.

13:46 Sure, writing to the cache would be bad.

13:47 eyeris: (: is for special forms, right? So how are they defined? (I'm trying to find the implementation of (:h3) in Webjure sources)

13:47 Chousuke: eyeris: : starts a keyword

13:48 eyeris: :h3 is not explicitly defined; possibly the html macro just uses them to denote html tags

13:48 Chouser: eyeris: it's probably being used very much like a string in that case.

13:48 eyeris: Okay. I see that now.

13:48 zakwilson: eyeris: there's probably no implementation of (:h3) - just a macro that turns forms starting with arbitrary keywords in to HTML.

13:49 eyeris: Yeah, so I need to find the impementaiton of :html

13:49 kotarak: :html is also a keyword

13:49 Chousuke: eyeris: not :html. you need the macro

13:50 eyeris: a macro defines a kind of mini-language and in this case keywords have a special meaning for the mini-language :)

13:50 eyeris: Right. So it would be in the definition of whatever uses `(:html ...)?

13:51 Chousuke: eyeris: probably.

13:51 kotarak: yep

13:51 eyeris: Darn. I found that a long time ago.

13:51 It's a doozie :)

13:53 hiredman: clojurebot: max people?

13:53 clojurebot: max people is 122

13:53 vsthesquares: sounds about right :)

13:53 * danlarkin cheers

13:56 danlarkin: zakwilson: reading the number of cached values from a lazy-seq would ruin the immutability of clojure collections because it'd be different depending on when you evaluated it

13:57 errrrrrrrrrrr

13:57 I guess it wouldn't actually mutate the collection though..

13:58 Chouser: danlarkin: no, but calling 'rest' certainly would

14:08 lisppaste8: fanda pasted "Type hints" at http://paste.lisp.org/display/73336

14:09 fanda: hello!

14:09 just wondering about type hints...

14:09 could Clojure infer the type from (class x) ?

14:10 or... could be type inferred when doing (new Class) ?

14:10 hiredman: ...

14:10 Chouser: you're allowed to re-def, either at the repl with another (def ...) or thread-locally with (binding ...)

14:11 fanda: (def x (new java.util.Hashtable)) clearly defines the type

14:11 Chouser: so a type hint is a little promise you're making to Clojure not to change it to an different type

14:11 Chousuke: some kind of optimisation could probably be implemented when you're compiling clojurecode into something that you will not modify at runtime.

14:12 Chouser: and also allows you to hint a more base type than the specific instance you're setting it to at the moment.

14:12 cemerick: Just in case someone was aching to hear my opinion ( :-P ), I'm mostly uninterested in "non-caching" seqs/streams/etc.

14:12 Chousuke: or even an interface

14:13 like java.util.Map if you require a map parameter that gets assoced a lot.

14:13 * rhickey will see if cemerick avoids streams once they are available

14:13 fanda: yes, I know - I am just trying to identify cases, when it could be useful without my help

14:13 Chousuke: or hm

14:13 I guess assoc already has a type hint for Map? :)

14:14 fanda: ...to specify type

14:14 cemerick: rhickey: :-D Oh, I'm sure I'll use them, but off the top of my head, I can think of only two or three situations where they'd be useful to me now.

14:14 rhickey: cemerick: even if you never use them directly, they are going to speed up map/filter et al by 2x

14:15 Chousuke: will you have separate map/filter functions for streams? streamfilter or streammap or whatnot?

14:15 rhickey: Chousuke: nope, just one

14:17 cemerick: rhickey: that sounds fun; I'm happy to be blissfully ignorant of those impls, tho

14:17 rhickey: cemerick: until you want to emulate them

14:17 Chouser: rhickey: were our reasons for checking if a LazyCons is cached correct?

14:17 Chousuke: are seqs also streams from an interface point of view?

14:17 Chouser: for not allowing checking, that is.

14:18 rhickey: Chouser: you mean getting a count of cached? that's sort of outside the scope of any single element

14:19 Chouser: but you could walk the chain, asking each LazyCons if it's 'rest' was cached yet

14:19 rhickey: Chouser: with access to the implementation, sure

14:19 cemerick: rhickey: emulate map and filter? You've lost me.

14:20 rhickey: cemerick: right now you write your own seq fns using lazy cons, and so do many of the seq fns, after streams the seq fns will mostly be defined in terms of streams, and you might want to do the same

14:21 Chouser: LazyCons.first_cached() { return _first != sentinel; }

14:21 rhickey: Chouser: I missed why this was important/useful

14:22 Chouser: Nobody said, I'm just curious if you would resist exposing that information.

14:22 * cemerick just realized that rhickey and Co. have planned out a weekend of chin-scratching for me sometime in the near future! ;-)

14:22 rhickey: Chouser: resisting right now :)

14:22 Chouser: cemerick: just rhickey. :-)

14:22 rhickey: heh. ok. I assumed you would, and was guessing as to the reasons.

14:22 not a big deal.

14:23 to me, anyway.

14:23 cemerick: Chouser: and Mr. Engleberg, perhaps

14:23 rhickey: Chouser: I'd like to be able to change the implementations of things, if people marry all the details, its game over

14:23 Chouser: "ClassFormatError: Duplicate field name&signature in class file" however is big-ish.

14:23 rhickey: ok.

14:24 rhickey: Chouser: ClassFormatError os where?

14:24 is where?

14:24 zakwilson: Did I just stir up a mess here?

14:24 danlarkin: zakwilson: :)

14:25 zakwilson: The reason I want to be able to get a count of the cached elements is to check the progress of a long calculation from the REPL.

14:25 Chouser: trimming it down...

14:26 Chousuke: zakwilson: you could do that manually.

14:27 wonder if you could use the monad library to do something like that.

14:27 rhickey: Chouser: is it "same sig static method in superclass not hidden"

14:28 zakwilson: Chousuke: how?

14:28 Chousuke: zakwilson: increment a ref at every iteration.

14:29 Chouser: *sigh* it just disappeard. I didn't see that text anywhere in the stack trace, if that's what you're asking.

14:29 rhickey: Chouser: no, a known gen-class issue

14:36 Chouser_: Sorry, power blink

14:36 Chousuke: zakwilson: I thought so too, but then I realised I was wrong.

14:39 eyeris: I know what (defn (defmacro etc do. But what does (def do?

14:40 Chousuke: eyeris: def is the special form

14:40 danlarkin: is *file* blessed for use, or could it be going away?

14:40 Chousuke: eyeris: defn and defmacro use def; it binds a value to a var.

14:40 eyeris: Okay

14:41 I saw it in this JDBC post: http://groups.google.com/group/clojure/browse_thread/thread/5b377466ca44886a

14:41 Why does he use (def rs instead of a let block?

14:42 Chousuke: eyeris: def is global

14:42 sometimes it's useful to have global values

14:42 eyeris: I see

14:43 lisppaste8: Chouser pasted "Duplicate field name&signature in class file" at http://paste.lisp.org/display/73340

14:44 Chouser: rhickey: If I'm doing something wrong there, I'm not spotting it.

14:45 rhickey: Chouser: is there already an init?

14:46 Chouser: oh, there it is. :-)

14:46 yep, that's it. Applet defines init()

14:47 thanks

14:47 rhickey: that's why I stick to fred and ethel :)

14:50 gnuvince_: rhickey: I meant to ask: there do those names come from?

14:51 rhickey: gnuvince_: I Love Lucy

14:51 gnuvince_: OK

14:51 I'm not familiar with it

14:52 rhickey: http://en.wikipedia.org/wiki/I_Love_Lucy

14:53 Chouser: which raises the question, do you love Lucy?

14:54 rhickey: not really, just a fading childhood memory of watching the reruns

14:54 danlarkin: Is there a way to get a filename (or File object, whatever) for each symbol in (loaded-libs)? Like (map #(...) (loaded-libs))

14:55 rhickey: The names used to get a good laugh when I used to teach (advanced C++ of all things) at NYU

14:56 Chouser: some reflection is allowed in applets

14:57 eyeris: Do functions have to be defined before they are used (before in the source file, not chronologically at runtime)

14:57 ?

14:57 Chousuke: eyeris: no

14:57 Chouser: eyeris: yes

14:57 technomancy: eyeris: maybe

14:57 rhickey: no

14:57 technomancy: just to round things out. =)

14:57 eyeris: Haha

14:57 Chouser: vars have to be defined before you can refer to them in code

14:58 rhickey: vars have to be visible, but you can delay the definitions

14:58 technomancy: they don't have to be defined as functions, but they need to be defined as names

14:58 Chousuke: yeah, but that can be done with declare

14:58 danlarkin: (doc declare)

14:58 clojurebot: defs the supplied var names with no bindings, useful for making forward declarations.; arglists ([& names])

14:58 technomancy: so you can (def my-function) (defn function-that-uses-my-function [] [...]) (defn my-function "real definition")

14:59 eyeris: Okay. I get it.

14:59 Chousuke: what's the difference between (declare foo) and (def foo)? or was declare just a convenience if you need multiple empty defs?

15:00 technomancy: declare is nicer than def-with-no-value for multiple vars at a time

15:00 Chousuke: I think it's the latter

15:00 Chouser: 'declare' suggests you're going to 'def' it later. (def foo) suggestes 'foo' will be used for dynamic binding.

15:01 Which I suppose means it ought to be (def *foo*)

15:01 technomancy: I was about to say, yeah, use asterisks

15:15 fanda: about type hints - my question generally is:

15:15 can (def x (new Class)) be equivalent to (def #^Class x (new class))

15:15 also, can (def x 5) be the same as (def #^int x 5)

15:16 i am trying to write a macro for it, no luck so far:

15:16 (defmacro deftag [x value] `(def #^{:tag (class ~value)} ~x ~value))

15:17 hiredman: you are evaluating value tiwce

15:17 twice

15:18 eyeris: Is there a way to list the contents of a .jar?

15:18 vsthesquares: unzip it

15:18 rhickey: ok, Java side of streams is up, in /branches/streams, svn 1207

15:18 replaca: ,(str \L (apply str (replicate 10 \u)) \c \y)

15:18 clojurebot: "Luuuuuuuuuucy"

15:18 eyeris: Thanks

15:18 kotarak: The form must be `(def ~(with-meta x (assoc (meta x) :tag (class value)) ...) which doesn't work, because value is a Symbol.

15:18 hiredman: there is a java api for jar files

15:19 clojurebot: svn rev 1207; intial import of streams stuff, Java side

15:19 hiredman: I forget what package it is in

15:19 clojurebot: way late dude

15:19 clojurebot: I don't understand.

15:19 technomancy: should I try to make a TAGS file for my codebase, or is it better to just ask SLIME where stuff is defined?

15:23 fanda: kotarak: let me think about it little...

15:26 durka: vsthesquares: (enumeration-seq (.entries (java.util.jar.JarFile. "path/to/archive.jar")))

15:26 walters: rhickey: i am actually working on a project where i needed a stream-like abstraction; i remember a discussion that you'd looked at a project where the stream API ended up being fairly complicated for e.g. resource management etc.; did you end up deciding that the current approach you have in SVN of just an Object next(); method is good enough?

15:28 vsthesquares: durka: damn, not only am I a lousy lisp programmer, I seems I don't know anything about the java api either

15:28 rhickey: walters: I'll not say it's the end of the story, but a necessary subcomponent of many things. It's certainly been 'good enough' for IO for a long time. I kind of like that seq models Lisp lists and streams io read, both venerable apis

15:29 vsthesquares: thanks for pointing that out

15:29 walters: rhickey: yeah, i agree

15:29 rhickey: gotta run now

15:29 durka: well, i only know that because i learned it a few days ago when i needed to use it

15:32 vsthesquares: net weer een nieuwe duistere krocht van de java api ontdekt

15:32 woops

15:32 wrong chan

15:32 Chouser: fanda: I've got a def-hint working

15:32 hiredman: clojurebot: what is <reply>net weer een nieuwe duistere krocht van de java api ontdekt

15:32 clojurebot: Roger.

15:33 Chouser: def-auto-hint is a more accurate name, but too long.

15:33 vsthesquares: sorry 'bout that :)

15:33 fanda: Chouser: nice :-)

15:33 Chouser: fanda: you want it, or you want to figure it out yourself?

15:34 fanda: yes, I want it :-)

15:34 Chouser: but I think it's good that 'def' doesn't do this by default -- could cause unexpected breakage that might be hard to track down.

15:34 (defmacro def-hint [sym val] `(do (def ~sym ~val) (alter-meta! (var ~sym) assoc :tag (class ~sym)) (var ~sym)))

15:35 hiredman: clojurebot: what is your stance on state vs. federal goverment?

15:35 clojurebot: Huh?

15:35 hiredman: hmmm

15:35 fanda: Chouser: thanks

15:36 might be useful for other people too

15:36 clojure-contrib?

15:36 kotarak: clojure.contrib.def?

15:36 Chouser: got a better name for it?

15:36 kotarak: deftagged?

15:37 hiredman: def-typed

15:38 def<haskell>

15:39 fanda: deftag / defhint / deftype

15:39 Chouser: hinted is more accurate than hint, I think.

15:39 def-typed

15:39 hiredman: def<haskell>

15:39 for reals

15:40 Chouser: fanda: is def-hinted short enough to still be worth it?

15:40 kotarak: maybe without -? The other defs, don't have it.

15:40 fanda: (def #^java.util.Hashtable x (new java.util.Hashtable))

15:40 (defhinted x (new java.util.Hashtable))

15:41 hiredman: I remind me to start using < and > in fn names

15:41 fanda: (java.util.Hashtable.)

15:41 ,(java.util.Hashtable.)

15:41 clojurebot: #=(java.util.Hashtable. {})

15:41 mmcgrana: (doc force)

15:41 clojurebot: If x is a Delay, returns the (possibly cached) value of its expression, else returns x; arglists ([x])

15:41 fanda: hiredman: yes, I know, I just like (new Class) better than (Class.)

15:42 mmcgrana: oops sorry, that was really random

15:42 fanda: on the other side, I don't like explicit types, so defhinted :-)

15:42 hiredman: (def<haskell> x (java.util.Hashtable.))

15:42 think about it

15:44 fanda: it is supposed to be only syntactic sugar - don't repeat yourself :-)

15:45 cooldude127: hiredman: i like your amb implementation

15:46 works way better than the one i tried to write

15:47 hiredman: good, I think I going to rename it to amb?

15:47 lisppaste8: danlarkin pasted "get files for all (loaded-libs)" at http://paste.lisp.org/display/73343

15:47 hiredman: ugh

15:47 cooldude127: wait, what is that last symbol? i don't think i have emacs set for the proper encoding

15:47 hiredman: interrobang

15:48 cooldude127: oh

15:48 got it

15:48 hiredman: (prn "amb?")

15:48 ,(prn "amb?")

15:48 clojurebot: "amb?"

15:48 hiredman: hmmm

15:48 cooldude127: it's a box for me everytime, but so are some other UTF-8 symbols

15:48 hiredman: ,(symbol "amb?")

15:48 clojurebot: amb?

15:48 hiredman: hmmm

15:48 user=> (def amb? nil)

15:48 #'user/amb=

15:48 :(

15:48 cooldude127: oh no

15:49 danlarkin: that paste I just made is answering my own question from earlier, about how to get filenames for all (loaded-libs)

15:49 technomancy: looks fine to me

15:49 hiredman: when I try to def something to amb? clojure defs it to amb=

15:50 cooldude127: hiredman: maybe we shouldn't mess around with the interrobang anyway

15:50 durka: Gorilla=> (def amb? "iguous")

15:50 #'user/amb?

15:50 Gorilla=> amb?

15:50 "iguous"

15:50 hiredman: oh

15:50 kotarak: :)

15:50 hiredman: I think I remember this

15:51 cooldude127: i'll be right back, i'm gonna try to fix something

15:51 hiredman: jline's fault

15:55 lisppaste8: Chouser pasted "Be careful with defhinted" at http://paste.lisp.org/display/73344

15:57 Chousuke: Chouser: maybe add a check to defhinted if there is already a hinted definition?

15:57 hm, that sentence could use a different word order.

15:58 Chouser: but using 'def' the subsequent times would avoid the check but still cause the exception.

15:58 also 'binding' can cause the same sort of problem

15:59 anyway, it's in clojure-contrib svn 360

15:59 hiredman: there is the whole range of unicode to play with

15:59 kotarak: Well, maybe one has to keep the discipline to only assign the same type to a hinted Var....

16:09 fanda: thanks for help and advice

16:09 talk to you later!

17:08 nsinghal: (defmacro set-enable [panel field-name enable]

17:08 `(.. ~panel ~field-name (setEnabled ~enable)))

17:08 when i do the macroexpand on it

17:08 (macroexpand '(set-enable panel jCheckBoxExternal true))

17:08 i get (. (. panel jCheckBoxExternal) (user/setEnabled true))

17:08 i want (. (. panel jCheckBoxExternal) (setEnabled true))

17:09 Chousuke: nsinghal: use ~'setEnabled in your macro

17:10 nsinghal: Chousuke: Thx so much - that works

17:25 Chouser: Anyone on Mac want to try http://chouser.n01se.net/misc/snake.html ?

17:26 durka: loading...

17:26 Chousuke: hmm

17:26 durka: same as before

17:26 Chousuke: I just get an X :/

17:26 Chouser: durka: ok, thanks.

17:27 Chousuke: that's Windows?

17:27 Chousuke: nah, Mac OS

17:27 firefox

17:27 Chouser: oh, ok. The Mac applet plugin is pickier, apparently.

17:28 Chousuke: same thing with safari

17:29 Chouser: works ok in firefox on linux, and firefox and chrome in XP.

17:29 Chousuke: Chouser: 10/01/2009 00:27:49 [0x0-0x1d70d6f].com.apple.Safari[66560] java.lang.VerifyError: class examples.snake overrides final method

17:29 Chouser: Chousuke: yeah, thanks.

17:29 http://paste.lisp.org/display/73333

17:31 hm, Java 1.5?

17:31 lpetit: applet does not start for me on Windows XP, firefox 3.0.5

17:31 Chousuke: Chouser: yes

17:31 Chouser: maybe it's a 1.5 vs 1.6 thing.

17:32 lpetit: 1.5 too

17:34 Chouser: ok

17:38 durka: chouser: same thing with 64bit 1.6, 1.5 and 32bit 1.5

17:38 Chouser: gah

17:41 durka: again it works fine in appletviewer

17:41 Chouser: wow. Write once, run ...

17:43 I'm downloading the 1.5 JDK. I'll try building all of clojure and the applet with that, see if it helps any.

17:46 lpetit: I've a question concerning swank-clojure

17:48 Chousuke: lpetit: you'll have to ask it if you want help.

17:48 lpetit: Do you know if there exist a client for swank-clojure written in clojure ? I'd like to call swank-clojure from an eclipse plugin, and if there was already the client part written in clojure ...

17:49 Chouser: lpetit: I'd love to see that. I've not heard of one, though.

17:50 ole3: is the swank side not always writen in the host language?

17:50 at least for the cl implementation that is the case

17:50 Chouser: durka: new snake.jar up

17:50 durka: :(

17:51 Chouser: bah

17:51 lpetit: Chouser: yes. For the moment, I balance between doing the strict minimum in eclipse-dev with own homegrown client/server inspired from swank-clojure, but more "straight-to-the-point" (not depending on the protocol of e-macs, maybe not that robust ...), or trying to understand slime/swank protocol ... maybe a pain in the ass since I do know nothing about it

17:52 ole3: I've downloaded swank-clojure. It does not seem to provide a clojure client side, just configuration files for the emacs ELISP configuration client side.

17:53 There is a big class in cusp (common lisp -at least SBCL- eclipse plugin) that speaks to a common lisp swank, but it's not well documented and I don't know whether it will take me more time to integrate to swank, or to redo it more "straight to the point"

17:53 ole3: lpetit: sorry i thought you mean the server side.

17:55 technomancy: there's a CL plugin for eclipse? wow.

17:56 lpetit: Something is stopping me currently from doing it myself : I'm unable to make my server-side part correctly evaluate objects that include defs

17:56 technomancy: Yes. Try cusp on google. I once tried it, it seemed really interesting

17:57 ole3: http://www.bitfauna.com/projects/cusp/ a swank client

17:57 technomancy: it just surprises me that such a thing exists; most CL folk have a low opinion of eclipse.

17:57 ole3: it is nice

17:58 think most of them do not tried eclipse

17:58 lpetit: technomancy: Well, most Eclipse folks have a low opinion of emacs :-)

17:58 technomancy: lpetit: that explains why there's no eclipse-mode in Emacs. =)

17:58 ole3: most stuff works out of the box simple, focused environment

18:00 * technomancy is not commenting on eclipse; just on CL people.

18:01 lpetit: OK. So back to clojure: can you explain me why the following does not work :

18:01 (eval '(binding [*ns* (create-ns 'foo)] (def bar 1)))

18:01 Chouser: yes

18:01 try (binding [*ns* (create-ns 'foo)] (eval '(def bar 1)))

18:02 lpetit: it works

18:05 Chouser: def uses the value of *ns* at compile time.

18:06 lpetit: Now, I want to send the following string from my client : "(ns foo) (def bar 1)"

18:06 I want it read on the server side, and correctly evaluated (so that ns 'foo is created, as well as var 'ns.bar.

18:06 Of course, I would like to not parse the string to search for a 'ns or 'in-ns ... => The string would come from a text editor in eclipse

18:10 So there's no workaround for the general problem ?

18:11 ole3: question: why is swank needed anyway? Why could not the eclipse plugin load an clojure instance?

18:14 Chousuke: ole3: you'd still need a protocol for communicating information between clojure and the IDE.

18:15 ole3: and connecting to an external clojure instance can make things a lot nicer if you need to kill it :P

18:16 lpetit: ole3: I thought about this. Maybe something like starting in debugging mode, and using the possibility of straight java interoperability. That's a possibility, but I don't know much about the feasibility of what I describe here.

18:17 ole3: and concerning swank-clojure, there's already the whole bunch of services it offers for searching documentation, indentation hints, symbol completion, ... and certainly a lot more I don't know about

18:18 But there's also the possibility that swank-clojure will evolve with slime, and that thinks will continuously break, be fixed, break ... I don't know how stable this would be as a dependency ... ?

18:18 durka: that is the current situation isn't it

18:18 lpetit: You haven't answered me ? What IRC client do you use ?

18:19 don't know how disturbing this situation really is, in practice ?

18:20 durka: colloquy

18:20 lpetit: ?

18:21 durka: personally i don't use swank-clojure but as i understand it clojure, swank-clojure and slime keep updating independently, and constantly break compatibility, and the best way to keep a working setup is just to stay on the bleeding edge of all three

18:21 colloquy is the irc client

18:21 i have to go but i will be back later tonight

18:21 hiredman: ,(do (prn (str *ns*)) (binding [*ns* (create-ns 'foo)] (def a 1)))

18:21 clojurebot: #'sandbox/a

18:21 "sandbox"

18:21 hiredman: I see

18:22 durka-gone: i thought clojurebot didn't do defs?

18:22 hiredman: well

18:22 I can reach into his guts

18:22 it does what I say

18:22 technomancy: you must have a long arm

18:22 Chousuke: hiredman: you added an exception for yourself? :P

18:22 or just poking at it at the repl

18:23 technomancy: gotta wait till hiredman goes offline then /nick hiredman and do as you wish. =)

18:23 Chousuke: do you run clojurebot from emacs btw?

18:23 hiredman: Chousuke: poking at the repl

18:23 no

18:23 from zsh :P

18:23 Chousuke: I did, when I was testing it. was pretty nice.

18:23 hiredman: well, good, I guess

18:23 clojurebot: emacs

18:23 clojurebot: emacs is hard, lets go shopping!

18:24 technomancy: would be cool do to IRC from the same instance as you had a bot repl in

18:24 Chousuke: technomancy: heh.

18:25 I think I should run the emacs daemon or something.

18:25 then I could set up my clojure script to just run emacs and show me the slime repl

18:26 lpetit: hiredman: didn't understand your example. Was connected to my question ?

18:26 ole3: lpetit: did you look at the message protocol of the server side? And at eval-region?

18:27 hiredman: lpetit: I was just checking to see how clojurebot's eval handled that

18:27 if it did

18:27 eval-in-a-box

18:28 lpetit: ,(+ 1 2)

18:28 clojurebot: 3

18:28 lpetit: wow!

18:28 ole3: lpetit: there is a function called fix-namespace, which seem to do what you want

18:28 lpetit: ,(doc fix-namespace)

18:28 clojurebot: java.lang.Exception: Unable to resolve var: fix-namespace in this context

18:29 hiredman: oh

18:29 for doc don't use ,

18:29 ole3: ,(doc ns)

18:29 clojurebot: ------------------------- clojure.core/ns ([name & references]) Macro Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted.

18:29 hiredman: see, if you use "," the formating is bad

18:29 just do (doc ns) no ","

18:30 lpetit: (doc ns)

18:30 clojurebot: Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class ...), when supplied, defaults to :name corresponding to th

18:30 Chousuke: hiredman: you could rebind doc to use your version :/

18:30 ole3: not much difference :)

18:30 hiredman: still wonky, but better

18:30 Chousuke: I was thinking that

18:32 lpetit: ole3: no I did not look at it because I didn't know it was to be called eval-region ? (swank really is very focused on emacs : maybe technically reusable, but semantically very tight to !)

18:34 ole3: lpetit: as i understand it, it defines an rpc mechanism, and eval-region takes a string fixes the namespace thing and compiles it

18:35 lpetit: no eval needed

18:35 lpetit: (defn- eval-region

18:35 "Evaluate string, return the results of the last form as a list and

18:35 a secondary value the last form."

18:35 ([string]

18:35 (with-open [rdr (LineNumberingPushbackReader. (StringReader. string))]

18:35 (loop [form (read rdr false rdr), value nil, last-form nil]

18:36 (if (= form rdr)

18:36 [value last-form]

18:36 (recur (read rdr false rdr)

18:36 (eval form)

18:36 form))))))

18:36 eval is here, near the end

18:36 ole3: :)

18:37 lpetit: Sorry for the whole screen source code. Maybe it's not desirable to do that on IIRC ?

18:37 hiredman: irc

18:37 correct

18:37 lisppaste8: url

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

18:38 ole3: hm

18:38 (eval 'foo)

18:39 ,(eval 'foo)

18:39 clojurebot: DENIED

18:39 lisppaste8: lpetit pasted "test" at http://paste.lisp.org/display/73354

18:39 lpetit: wow, very cool indeed

18:39 ole3: ,(compile 'foo)

18:39 clojurebot: java.io.FileNotFoundException: Could not locate foo__init.class or foo.clj on classpath:

18:39 lpetit: ,*compile-path*

18:39 ole3: nevermind

18:39 lpetit: ,(prn *compile-path*)

18:39 clojurebot: nil

18:40 ole3: ,nil

18:40 nil

18:40 lpetit: ,(str *compile-path*)

18:40 clojurebot: ""

18:40 lpetit: ,(do *compile-path*)

18:40 clojurebot: nil

18:40 lpetit: (doc do)

18:40 clojurebot: It's greek to me.

18:40 lpetit: hihi

18:40 OK, I calm down

18:41 ole3: ,(pr 'hoo)

18:41 clojurebot: hoo

18:41 lpetit: Who is hosting clojurebot ?

18:41 hiredman: <-

18:41 ole3: ,(loop [i 0]

18:41 clojurebot: Eval-in-box threw an exception:EOF while reading

18:41 ole3: ,(loop (recur))

18:41 clojurebot: java.lang.ArrayIndexOutOfBoundsException: 1

18:41 Chousuke: ole3: it does not fall to that.

18:42 ,(loop [] (recur))

18:42 clojurebot: latest

18:42 clojurebot: Execution Timed Out

18:42 latest is 1207

18:42 ole3: safe

18:42 Chousuke: it's a small DOS though apparently :p

18:43 lpetit: I think we should avoid bad thinks with it, like calling format on C: ? :()

18:43 Chousuke: you can try

18:43 this happens:

18:43 ,(System/exit 0)

18:43 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.0)

18:43 lpetit: Hehe

18:43 hiredman: lpetit: go ahead

18:43 not windows, no C:

18:44 lpetit: ,(System/getProperties)

18:44 clojurebot: java.security.AccessControlException: access denied (java.util.PropertyPermission * read,write)

18:44 Chousuke: hiredman: does it run as its own user?

18:44 hiredman: nope

18:44 I guess I could (should?) do that, but meh

18:44 I am trusting in the jvm sandboxing, at least until it deletes all my files

18:47 lpetit: ,(java.io.File/listRoots)

18:47 clojurebot: #<File[] [Ljava.io.File;@e93999>

18:48 hiredman: ,(first (java.io.File/listRoots))

18:48 clojurebot: nil

18:48 hiredman: ,(apply vector (java.io.File/listRoots))

18:48 clojurebot: []

18:48 lpetit: ,(dorun #(.toString %) (java.io.File/listRoots))

18:48 clojurebot: nil

18:48 hiredman: hwa

18:48 Chousuke: noroots apparently :P

18:49 lpetit: ,(doall #(.toString %) (java.io.File/listRoots))

18:49 clojurebot: #<File[] [Ljava.io.File;@12a73d9>

18:49 lpetit: ,(seq (doall #(.toString %) (java.io.File/listRoots)))

18:49 clojurebot: nil

18:49 lpetit: ok ok

18:50 Chousuke: "If a security manager exists and its SecurityManager.checkRead(java.lang.String) method denies read access to a particular root directory, then that directory will not appear in the result. "

18:50 lpetit: And concerning my def evaluation problem ?

18:51 dreish: Are you guys trying to do (seq (java.io.File/listRoots)) ?

18:51 ole3: no, we tried already

18:51 lpetit: ,(.openConnection (new URL "http://www.clojure.org"))

18:51 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: URL

18:51 Chousuke: lpetit: that will fail

18:51 dreish: Oh, sandbox testing. I see.

18:52 lpetit: ,(.openConnection (new java.net.URL "http://www.clojure.org"))

18:52 clojurebot: #<HttpURLConnection sun.net.www.protocol.http.HttpURLConnection:http://www.clojure.org>

18:52 Chousuke: even if you had the full class name :P

18:52 wait, what.

18:52 or is that just connection object? not actually connected

18:53 it should not have any network permissions

18:53 dreish: ,'#=(eval (def what-about "this thing?"))

18:53 Chousuke: dreish: it needs to start with ,(

18:53 lpetit: ,(.getContent (.openConnection (new URL "http://www.clojure.org")))

18:53 dreish: ,(identity #=(eval (def forgot-the "parens")))

18:53 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: URL

18:53 #'clojure.core/forgot-the

18:53 lpetit: Argh

18:53 dreish: Yeah, still need to reject the string #=

18:53 hiredman: ,(.read (.openConnection (new java.net.URL "http://www.clojure.org")))

18:53 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.net.www.protocol.http)

18:53 lpetit: ,(.getContent (.openConnection (new java.net.URL "http://www.clojure.org")))

18:53 clojurebot: java.security.AccessControlException: access denied (java.net.SocketPermission www.clojure.org:80 connect,resolve)

18:54 Chousuke: ,(identity forgot-the)

18:54 clojurebot: java.lang.Exception: Unable to resolve symbol: forgot-the in this context

18:54 Chousuke: um.

18:54 dreish: ,(identity #=(eval forgot-the))

18:54 clojurebot: "parens"

18:54 Chousuke: ,(identity #=(eval '(System/exit 0))

18:54 clojurebot: Eval-in-box threw an exception:EOF while reading

18:54 Chousuke: ,(identity #=(eval '(System/exit 0)))

18:54 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.0)

18:54 Chousuke: phew.

18:54 ole3: )))))))))))))))))))))))))))0

18:54 dreish: Are you sure you want to do that?

18:55 ole3: ((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))

18:55 Chousuke: dreish: the worst would have been that clojurebot would have quit

18:55 ole3: ,(((((())))))))))))))))))))))

18:55 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn

18:55 hiredman: ,(identity #=(eval forgot-the))

18:55 clojurebot: "parens"

18:55 Chousuke: which would have been preferable to someone actually doing something destructive :P

18:55 dreish: Right.

18:55 ole3: ,(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))

18:55 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn

18:55 Chousuke: ,(identity #=(eval *ns*))

18:55 clojurebot: Titim gan �ir� ort.

18:56 dreish: Are those your extra parens, ole3? Can I use them?

18:56 hiredman: Chousuke: #= is a naughty form now

18:56 ole3: dreish: a gift, use them wise.

18:56 dreish: ,(identity #=(eval (+ 21 21)))

18:56 clojurebot: Excuse me?

18:57 lpetit: ,((fn toto [] (toto)))

18:57 clojurebot: java.lang.StackOverflowError

18:58 lpetit: Weird that nobody tried to make clojurebot compute the infinite fibonacci sequence yet ;-)

18:58 hiredman: *shrug*

18:58 no different then the infinite loop

18:59 ole3: it will give an memory exception, with enough time

18:59 hiredman: no

19:00 clojurebot execution times out after 10 seconds

19:00 (a little less infact)

19:00 ole3: the computer is then to slow!

19:00 hiredman: well, either that or stackoverflow

19:01 ole3: who needs a stack

19:01 lpetit: ,(do (doall (repeat "hello") nil)

19:01 clojurebot: Eval-in-box threw an exception:EOF while reading

19:02 ole3: nevermind

19:02 hiredman: anyway, you can abuse clojurebot via privmsg

19:03 ole3: everywhere i go, the singal/noise ratio drops. maybe i am part of it. good night!

19:06 lpetit: Is it possible to load from a string ?

19:08 If in clojure-dev, the user has this in a text editor : "(ns foo) (def bar 1)" -> and doesn't want to save the content of the editor, but still wants to send its content for evaluation to a remote clojure environment, how can I handle that in the remote clojure environment (hypothesis : I don' t use an out of the box - read swank - solution, and the remote clojure environment receives the...

19:08 ...content as a string) ?

19:10 Chouser re-explained me that with eval there's no possibility (the def's would be tied to the compiled value of *ns*, not the value of the last (ns) or (in-ns) found in the eval'd string

19:14 rhickey: lpetit: create a reader on the string and use load-reader?

19:15 lpetit: thank you !

19:20 rich : ok, it was in the docs ! I also found (load-string) that seems to do the with-open ... plumbing in the case of strings. Thank you so much !

19:24 Rich, do you know of an existing swank-clojure client written in clojure ? I think that if not, for a first version of clojure-dev, I will not attempt to master slime/swank/swank-clojure first (and not try to port eclipse cusp plugin), and go with a quick and (not so dirty I hope) homegrown solution ? A single server with no footprint on the distant REPL (a script loaded which defines no...

19:24 ...namespace, and adds no symbol to existing namespaces), and also, maybe, a way to even pilot the installation/deinstallation of helper functions on the server side by injecting them from the client side ! :-)

19:35 good night

19:43 fffej: say I've got a list of characters, how do I turn them into a nice string (e.g. [\f \o \o] => "foo")

19:44 Chouser: ,(apply str [\f \o \o])

19:44 clojurebot: "foo"

19:44 fffej: thanks!

21:29 wyclef: hello, all

21:29 i'm new to lisp programming, period. does anyone know of a step-by-step lisp tutorial for clojure?

21:30 Chousuke: hmm :/

21:30 sadly, the documentation is rather scattered.

21:32 wyclef: i've been looking at the documentation on clojure.org but i'm not well enough grounded in functional programming to make much headway

21:32 Chousuke: wyclef: I found this http://www.moxleystratton.com/article/clojure/for-non-lisp-programmers

21:33 hm, that page lists str as a special form

21:37 wyclef: it seems like a condensaton of the material from the screencasts

21:38 i think i'll use sicp, and try to make the necessary conversions as I go along

21:38 thanks for the help

21:38 Chousuke: practical common lisp might be good too

21:39 Chouser: Programming Clojure doesn't assume any lisp background, if you're willing to spring for it.

21:39 Chousuke: wyclef: with these: http://blog.thinkrelevance.com/2008/9/16/pcl-clojure

21:40 mmcgrana: sicp + drscheme would be a good way to get started with lisp as a general idea

21:41 drscheme is nice because it just works, unlike most other lisp environments

21:41 Chouser: is it really worth learning a non-clojure lisp first?

21:41 wyclef: thanks, i didn't know about either of those

21:42 Chouser: I read "on lisp" for free online, but that was my only significant lisp before clojure.

21:42 mmcgrana: yeah maybe not, maybe just jump right into the clojure repl

21:43 Chouser: Hm, I sense I'm being mocked. :-)

21:44 arbscht: I don't think so. it's a fine idea

21:45 Chousuke: I don't think you need previous lisp experience to get started with clojure

21:45 wyclef: very cool. a lot more information that i had a few minutes ago

21:46 mmcgrana: Chouser: not at all

21:46 Chouser: oh, ok. I do think it's worth reading some kind of lisp introduction, or at the very least watching Rich's "clojure for java programmers" series

21:47 mmcgrana: When I started trying to learn lisp a few years ago I couldn't get any environment set up other than Scheme, I guess I was just thankful for that. And +1 for the screencasts they are so mcuh fun.

21:47 Chousuke: though they're a slight bit outdated already :)

21:47 still valid though.

21:48 wyclef: i stumbled across the recorded lectures from the jvm language summit

21:48 that's where i heard about clojure

21:48 Chouser: I think it'd be great if someone transcribed the screencasts. Easier to keep up to date, easier to skim and search.

21:48 danlarkin: write some clojure to do it :)

21:49 Chouser: It'd really be taking one for the team, though. TDus.

21:50 Chousuke: hm

21:50 might actually be fun to write a tutorial

21:51 Chouser: right, that's what I meant by "TDus". "fun". Chousuke: go for it!

21:53 Chousuke: some kind of "groundwork" for people with no lisp experience so that they can at least understand the other stuff on the net.

21:54 but not now. now is time for sleep.

21:55 danlarkin: what's the recommended way to write an infinite loop? trampoline?

21:55 Chouser: danlarkin: 'iterate'?

21:56 loop/recur ?

21:56 wyclef: '(loop [] (recur))'?

21:56 danlarkin: oh... duh

21:56 Chouser: :-)

21:57 danlarkin: for some reason I was worrying about the stack, but obviously that was unfounded

21:58 that's my brain trying to say it's done programming for the day

21:58 but I'm not going to listen!

22:00 wyclef: find the nearest espresso machine

22:02 danlarkin: should I use an agent for watching certain files, or should I just use (new Thread ...)?

22:03 Chouser: (new Thread) is so tedious. :-)

22:04 if the thread is likely to terminate, 'send-off' works from a pool, which ought to improve efficiency.

22:06 danlarkin: nah, I just want to have an infinite loop on another thread watching for changes to files

22:06 so it won't terminate

22:08 Chouser: probably doesn't matter then. do what feels good. :-)

22:08 hm, an exception from (new Thread) probably dumps directly to your console. That might be convenient, compared to agent-errors.

22:09 danlarkin: Hmmmm that is true

22:11 although haven't agents yet, I think I'm going to now :)

22:19 Chouser: rhickey: did you see (meta #^:my-tag []) ==> nil ?

22:25 danlarkin: oh... is it bad form to have my agent performing side effects (if it detects changed files)? I guess it probably is... I suppose I should use (new Thread ...)

22:38 rankp: if i pass a {1 2 3 4} to a function in clojure and modify it so it is {1 2 3 4 5 6} then both of them exists? isnt that a huge memory hog? can I somehow tell Clojure to delete the old one?

22:40 rhickey: Chouser: no, thanks for the report

22:40 Chouser: all of clojure's collections have structural sharing, so if it's quite likely that especially in large collections, the new one will "contain" the old one.

22:40 rhickey: it's from the group. shall I create an Issue?

22:40 rhickey: Chouser: yes, thanks

22:40 Chouser: rankp: so that reduces the burden of creating a new one from an old one.

22:41 rankp: also, as soon as you no longer have any references to an object, it will be available for the JVM to garbage collect, freeing it up automatically.

22:41 rankp: in short: don't worry about it. :-)

22:43 rankp: Chouser: ah that's clever, i see

Logging service provided by n01se.net