0:53 drewr: When I say (proxy [some.package.Foo]), what is it that I get back? Is it a derived anonymous class inherited from Foo that I can then instantiate?
8:19 asbjxrn: Any plans for when the next release will be?
8:21 rhickey: I was hoping for some more feedback about the most recent additions - genclass and parallel, and for any final feedback on the Java syntax sugar. I could do a release soon.
8:21 There's also a very hot math/inlining optimization I'm working on that I might try to squeeze in
8:22 cgrand: wow
8:23 rhickey: Made naive fib 4x as fast
8:23 cgrand: inlined but still boxed I presume
8:24 rhickey: Boxed across call boundaries. The cool thing is the inlining is done by HotSpot, if the code path looks right
8:25 so the inlining on my part is just to typed method calls, no primitive op support in code gen
8:29 asbjxrn: Can't give you much feedback, I'm afraid. The little time I do get to spend on clojure is mostly spent fumbling around...
8:58 blackdog: newbie alert, how do i get command line arguments?
8:59 rhickey: *command-line-args*
8:59 blackdog: ah, thanks
10:20 drewr: Regarding *command-line-args*, how do you pass program arguments through the JVM invocation?
10:20 rhickey: at the end
10:21 drewr: The java binary thinks it's an argument for him.
10:21 Like, another source file.
10:21 $ java -cp ~/tmp/src/clojure/clojure.jar clojure.lang.Script cmdline.clj foo bar
10:21 java.io.FileNotFoundException: foo (No such file or directory)
10:21 rhickey: sorry, after -- at the end
10:21 drewr: cmdline.clj contains: (prn *command-line-args*)
10:22 Ah, normal shell semantics. How dare they! :-)
10:22 rhickey: no, that's a Clojure thing I forgot
10:22 -- separates scripts from args
10:23 drewr: Well then, kudos to you for making it logical.
10:23 rhickey: it was a user request :)
10:49 drewr: I'm a little confused about how to create a derived class. Can I use PROXY for that? What does (proxy [java.lang.String]) return exactly?
10:49 I'm not trying to extend String, btw.
10:49 rhickey: String is final
10:49 drewr: Just the first thing that came to mind.
10:50 rhickey: proxy returns an instance of an anonymous class that extends/implements the supplied supers
10:51 drewr: Can I add methods to it?
10:51 I'm trying to utilize a Java library that wants me to create a derived class for and fill in the holes.
10:51 s/ for//
10:52 rhickey: no additional methods, but you can override any methods
10:52 genclass lets you add methods
10:52 if you think about it, since your proxy is anonymous, how could anyone know about any additional methods?
10:54 any support code you need does not need to be in methods, can be in regular Clojure fns
10:54 drewr: I guess the methods are defined in the base class. I've been working in dynamic languages too long.
10:54 They're just meant to be overridden.
10:55 rhickey: so you don't need to add methods, proxy should be adequate
10:55 drewr: Any code of record that makes use of this?
10:55 Wow, GEN-CLASS is a beast.
10:57 rhickey: gen-class solves many java integration problems, but shouldn't be needed for your case unless you need to supply a class name to the Java consumer side
10:58 proxy usages in xml.clj, bean (in proxy.clj), the swing demo in the docs
11:01 ozzilee: rhickey: Is there a way to tell (load-file foo) about macros that I've defined outside of foo? It appears to be trying to resolve symbols inside my macro call.
11:01 Uh, let me know if that doesn't make sense :-)
11:01 rhickey: doesn't yet :(
11:02 did you load the file containing the macros first?
11:02 ozzilee: Yeah. I define the macro in "bar.clj", then load a file "foo.clj" that uses it.
11:03 Let me see if I can come up with a simpler test case than my current rats-nest code.
11:03 rhickey: good idea
11:07 ozzilee: Bugger, looks like that's not the problem. Sorry.
11:14 Bah, stupidity on my part. Changes something from a keyword to a symbol and forgot to change a (keyword?) call.
11:24 Woo! (defget ["foo" x "bar"] x)
11:25 (navigates to localhost:8080/foo/ozzi/bar)
11:53 drewr: If I've made a Ref like: (def *messages* (ref ))
11:54 ...wouldn't the way to append things to that vector be:
11:54 (alter *messages* (conj *messages* message))
11:54 Sorry, (dosync (alter *messages* (conj *messages* message))).
11:56 cgrand: drewr: (dosync (alter *messages* conj message))
12:00 drewr: cgrand: Thanks. :-)
12:09 Immutability is nice. I just accidentally wrote something concurrently safe.
12:09 rhickey: there you go!
12:12 drewr: I'm still a little confused with Vars though.
12:12 The thing they point at can't be changed, but you can reassign the symbol to something else, right?
12:13 rhickey: vars are a type of reference, so they can be made to refer to something else, just like refs and agents
12:15 there are 3 ways to make them refer to something else, def, which is like old-fashioned global state, binding, which establishes a thread-local meaning, and set!, which changes the thread-local meaning
12:16 drewr: What does vars.html mean by "mutable storage location?"
12:17 rhickey: an atomic reference that can be made to refer to different things over its lifetime
12:18 drewr: Ah, so the thing *in* the storage location isn't mutable. The location is.
12:18 rhickey: right
12:18 drewr: That's what I originally understood but I started to confuse myself.
12:18 rhickey: although you could put a mutable (Java) thing in a reference, it would normally be wrong to do so
12:19 drewr: Because it breaks the abstraction, or because that would be bad anyway?
12:20 rhickey: all the goodness Clojure brings can get destroyed if you mutate things outside of its control
12:20 that said, if you put something that was technically mutable in a reference, but treated it as immutable, that would work
12:20 drewr: That makes sense.
12:21 I was getting concerned lately that Java was leaking too much into Clojure, but I'm finding that once I get the class interop set up with whatever I'm doing I can generally focus only on Clojure.
12:22 rhickey: that's the best approach - get out of Java as soon as possible
12:25 dudleyf: So defs are globally visible with their original binding, but can only be mutated within a thread?
12:26 rhickey: you can rebind them using def again - that's how you fix bugs in running programs, but otherwise you shouldn't use def like assignment
12:27 drewr: rhickey: BTW, I'm going to test drive parallel.clj; just haven't had a chance this week.
12:27 rhickey: have you got a multicore box?
12:28 drewr: Yeah, a MBP.
12:28 rhickey: fine
12:28 drewr: ...and access to many multicore Linux servers that I'd like to try out.
12:28 rhickey: cool
12:31 drewr: Inside a proxy class, is the instance of that class implied when you call a method like a function?
12:32 rhickey: no, you must pass this
12:32 drewr: In xml.clj, (startDocument ) calls that method on the derived ContentHandler class I'm assuming.
12:32 rhickey: that's a definition, not a call
12:33 drewr: Oh you're right. Didn't read the indentation correctly.
12:51 Can I alter the constructor of an proxy class? I'm proxying an abstract class which really wants me to do my own initialization.
12:52 rhickey: you can close over any state you need
13:18 user=> (time (reduce + (range 1000000)))
13:18 "Elapsed time: 173.82 msecs"
13:18 user=> (time (reduce long/+ (range 1000000)))
13:18 "Elapsed time: 33.251 msecs"
13:18 Chouser: wow
13:18 drewr: d00d
13:19 rhickey: use with care:
13:19 user=> (time (reduce int/+ (range 1000000)))
13:19 "Elapsed time: 35.002 msecs"
13:19 note wrong answer
13:19 drewr: Wrap?
13:19 rhickey: right
13:20 but a valuable tool in perf-sensitive inner loops
13:20 drewr: neat.
13:20 rhickey: also float and double versions, which are safe and just plain faster
13:23 user=> (time (fib 35))
13:23 "Elapsed time: 2659.155 msecs"
13:23 user=> (time (fibi 35))
13:23 "Elapsed time: 565.412 msecs"
13:25 up now, rev 875
13:59 drewr: A protected method should be accessible to children, no?
14:13 I was trying to call a protected method as a client of an instance.
14:13 So how do you override the constructor of the parent class in a PROXY definition.
14:24 I guess the question is how do you create a ctor of the anonymous class.
16:02 rhickey: drewr: no - protected members are not accessible in a proxy
16:03 drewr: Ah, OK.
16:03 I made a real Java class to workaround it.
16:04 Work around it too.
16:05 Chouser: drewr: you can do it with gen-class
16:05 rhickey: the proxy has the same ctors as its super, and you can specify the args in the proxy call. any other data you can close over
16:05 Chouser: stop writing java code! ;-)
16:06 drewr: rhickey: I don't know what you mean by closing over data in the proxy.
16:09 rhickey: all of the 'methods' you define in a proxy call are really Clojure fns, and they can close over the state ofthe context in which they were created - i.e. they are closures
16:10 drewr: OK, I understand that. I think that doesn't help me in this particular case.
16:11 The abstract class I'm extending has (protected) mutators for some of its state.
16:24 rhickey: drer: then gen-class will do it for you - you can expose protected fields, and protected methods become public.
16:33 drewr: Can I not specify genclass.clj after clojure.lang.Repl on the command line?
16:33 I'm trying to get it loaded by default.
16:37 Hm. for(String file : RT.processCommandLine(args)) seems like it would.
16:38 Maybe it got loaded and I'm just not seeing it.
16:42 When I C-c C-k the buffer I can do (doc clojure/gen-class).
17:16 Shouldn't I be able to do (new (gen-class 'Foo))?
17:17 I get Unable to resolve classname: clojure.lang.PersistentList@ebfa2702.
17:17 rhickey: drewr: you should be using either gen-and-load-class or gen-and-save-class
17:20 drewr: (new (clojure/gen-and-load-class 'Foo)) gives me the same result.
17:21 rhickey: gen-and-load-class is something you call once to create the Foo class. Then Foo is available like any other class - (new Foo ...)
17:21 drewr: OK, the side effect of the bytecode loading is what I'm after there. I get it.
17:22 rhickey: right
17:23 drewr: Does it load it in any particular namespace? (new Foo) tells me it can't resolve classname Foo.
17:23 (It successfully generated the bytecode.
17:24 rhickey: you should supply a package name
17:24 to gen-class
17:24 drewr: Ah, that worked.
17:27 Can I use :expose if I don't know what the protected member is called? I only know the mutators.
17:27 Doesn't it break encapsulation to have to know the member name?
17:28 rhickey: the mutators will be public in your derived class - so you can use them
17:28 drewr: It's telling me "No matching method found."
17:30 Public setters are working okay.
17:30 rhickey: is the mutator final?
17:31 drewr: Yes. :-(
17:31 rhickey: oh well, that's it
17:31 drewr: Bugger.
17:32 Guess I'll stay with my native Java class.
17:33 rhickey: what were you trying to derive from, if I might ask?
17:34 clojurebot: I don't yet know what "foo" means.
17:34 drewr: ,learn foo
17:34 clojurebot: I don't yet know what "learn foo" means.
17:34 drewr: Well shucks. :-)
17:36 rhickey: ,uh oh
17:36 drewr: It times out after a minute or two.
17:44 Chouser: drewr: do you have a good sandbox for that bot?
17:44 drewr: Chouser: I was in #clojure- all day.
17:45 Chouser: I was thinking an ajaxy REPL might be nice for people to dabble a little without having to install anything.
17:45 ...but obviously I don't want them to be able to do anything to my server.
17:46 drewr: The dangerous parts can be disabled if we can identify what they are.
17:46 rhickey: or use Java's security mechanisms
17:46 * rhickey only knows they exist
17:47 drewr: That's more than I know. ;-)
17:47 Any guesses as to the approach?
17:49 Chouser: I guess I'd start looking at applet containers, but that's a long way from a working solution.
17:49 Chouser: And also a chroot on the server to be extra safe.
17:49 dudleyf: .. but that's a long way from a working solution ;-)
17:49 Chouser: :-)
17:52 a tiny bit closer.
17:55 Chouser: cute