#clojure logs

2008-05-23

00:53drewrWhen 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?
08:19asbjxrnAny plans for when the next release will be?
08:21rhickeyI 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.
08:21rhickeyThere's also a very hot math/inlining optimization I'm working on that I might try to squeeze in
08:22cgrandwow
08:23rhickeyMade naive fib 4x as fast
08:23cgrandinlined but still boxed I presume
08:24rhickeyBoxed across call boundaries. The cool thing is the inlining is done by HotSpot, if the code path looks right
08:25rhickeyso the inlining on my part is just to typed method calls, no primitive op support in code gen
08:29asbjxrnCan't give you much feedback, I'm afraid. The little time I do get to spend on clojure is mostly spent fumbling around...
08:58blackdognewbie alert, how do i get command line arguments?
08:59rhickey*command-line-args*
08:59blackdogah, thanks
10:20drewrRegarding *command-line-args*, how do you pass program arguments through the JVM invocation?
10:20rhickeyat the end
10:21drewrThe java binary thinks it's an argument for him.
10:21drewrLike, another source file.
10:21drewr$ java -cp ~/tmp/src/clojure/clojure.jar clojure.lang.Script cmdline.clj foo bar
10:21drewrjava.io.FileNotFoundException: foo (No such file or directory)
10:21rhickeysorry, after -- at the end
10:21drewrcmdline.clj contains: (prn *command-line-args*)
10:22drewrAh, normal shell semantics. How dare they! :-)
10:22rhickeyno, that's a Clojure thing I forgot
10:22rhickey-- separates scripts from args
10:23drewrWell then, kudos to you for making it logical.
10:23rhickeyit was a user request :)
10:49drewrI'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:49drewrI'm not trying to extend String, btw.
10:49rhickeyString is final
10:49drewrJust the first thing that came to mind.
10:50rhickeyproxy returns an instance of an anonymous class that extends/implements the supplied supers
10:51drewrCan I add methods to it?
10:51drewrI'm trying to utilize a Java library that wants me to create a derived class for and fill in the holes.
10:51drewrs/ for//
10:52rhickeyno additional methods, but you can override any methods
10:52rhickeygenclass lets you add methods
10:52rhickeyif you think about it, since your proxy is anonymous, how could anyone know about any additional methods?
10:54rhickeyany support code you need does not need to be in methods, can be in regular Clojure fns
10:54drewrI guess the methods are defined in the base class. I've been working in dynamic languages too long.
10:54drewrThey're just meant to be overridden.
10:55rhickeyso you don't need to add methods, proxy should be adequate
10:55drewrAny code of record that makes use of this?
10:55drewrWow, GEN-CLASS is a beast.
10:57rhickeygen-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:58rhickeyproxy usages in xml.clj, bean (in proxy.clj), the swing demo in the docs
11:01ozzileerhickey: 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:01ozzileeUh, let me know if that doesn't make sense :-)
11:01rhickeydoesn't yet :(
11:02rhickeydid you load the file containing the macros first?
11:02ozzileeYeah. I define the macro in "bar.clj", then load a file "foo.clj" that uses it.
11:03ozzileeLet me see if I can come up with a simpler test case than my current rats-nest code.
11:03rhickeygood idea
11:07ozzileeBugger, looks like that's not the problem. Sorry.
11:14ozzileeBah, stupidity on my part. Changes something from a keyword to a symbol and forgot to change a (keyword?) call.
11:15ozzilee*Changed
11:24ozzileeWoo! (defget ["foo" x "bar"] x)
11:25ozzilee(navigates to localhost:8080/foo/ozzi/bar)
11:25ozzilee"ozzi"
11:25ozzilee:-)
11:53drewrIf I've made a Ref like: (def *messages* (ref []))
11:54drewr...wouldn't the way to append things to that vector be:
11:54drewr(alter *messages* (conj *messages* message))
11:54drewrSorry, (dosync (alter *messages* (conj *messages* message))).
11:56cgranddrewr: (dosync (alter *messages* conj message))
12:00drewrcgrand: Thanks. :-)
12:09drewrImmutability is nice. I just accidentally wrote something concurrently safe.
12:09rhickeythere you go!
12:12drewrI'm still a little confused with Vars though.
12:12drewrThe thing they point at can't be changed, but you can reassign the symbol to something else, right?
12:13rhickeyvars are a type of reference, so they can be made to refer to something else, just like refs and agents
12:15rhickeythere 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:16drewrWhat does vars.html mean by "mutable storage location?"
12:17rhickeyan atomic reference that can be made to refer to different things over its lifetime
12:18drewrAh, so the thing *in* the storage location isn't mutable. The location is.
12:18rhickeyright
12:18drewrThat's what I originally understood but I started to confuse myself.
12:18rhickeyalthough you could put a mutable (Java) thing in a reference, it would normally be wrong to do so
12:19drewrBecause it breaks the abstraction, or because that would be bad anyway?
12:20rhickeyall the goodness Clojure brings can get destroyed if you mutate things outside of its control
12:20rhickeythat said, if you put something that was technically mutable in a reference, but treated it as immutable, that would work
12:20drewrThat makes sense.
12:21drewrI 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:22rhickeythat's the best approach - get out of Java as soon as possible
12:25dudleyfSo defs are globally visible with their original binding, but can only be mutated within a thread?
12:26rhickeyyou 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:27drewrrhickey: BTW, I'm going to test drive parallel.clj; just haven't had a chance this week.
12:27rhickeyhave you got a multicore box?
12:28drewrYeah, a MBP.
12:28rhickeyfine
12:28drewr...and access to many multicore Linux servers that I'd like to try out.
12:28rhickeycool
12:31drewrInside a proxy class, is the instance of that class implied when you call a method like a function?
12:32rhickeyno, you must pass this
12:32drewrIn xml.clj, (startDocument []) calls that method on the derived ContentHandler class I'm assuming.
12:32rhickeythat's a definition, not a call
12:33drewrOh you're right. Didn't read the indentation correctly.
12:51drewrCan I alter the constructor of an proxy class? I'm proxying an abstract class which really wants me to do my own initialization.
12:52rhickeyyou can close over any state you need
13:18rhickeyuser=> (time (reduce + (range 1000000)))
13:18rhickey"Elapsed time: 173.82 msecs"
13:18rhickey499999500000
13:18rhickeyuser=> (time (reduce long/+ (range 1000000)))
13:18rhickey"Elapsed time: 33.251 msecs"
13:18rhickey499999500000
13:18Chouserwow
13:18drewrd00d
13:19rhickeyuse with care:
13:19rhickeyuser=> (time (reduce int/+ (range 1000000)))
13:19rhickey"Elapsed time: 35.002 msecs"
13:19rhickey1783293664
13:19rhickeynote wrong answer
13:19drewrWrap?
13:19rhickeyright
13:20rhickeybut a valuable tool in perf-sensitive inner loops
13:20drewrneat.
13:20rhickeyalso float and double versions, which are safe and just plain faster
13:23rhickeyuser=> (time (fib 35))
13:23rhickey"Elapsed time: 2659.155 msecs"
13:23rhickey9227465
13:23rhickeyuser=> (time (fibi 35))
13:23rhickey"Elapsed time: 565.412 msecs"
13:23rhickey9227465
13:25rhickeyup now, rev 875
13:59drewrA protected method should be accessible to children, no?
14:13drewrI was trying to call a protected method as a client of an instance.
14:13drewrSo how do you override the constructor of the parent class in a PROXY definition.
14:24drewrI guess the question is how do you create a ctor of the anonymous class.
16:02rhickeydrewr: no - protected members are not accessible in a proxy
16:03drewrAh, OK.
16:03drewrI made a real Java class to workaround it.
16:04drewrWork around it too.
16:05Chouserdrewr: you can do it with gen-class
16:05rhickeythe 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:05Chouserstop writing java code! ;-)
16:06drewrrhickey: I don't know what you mean by closing over data in the proxy.
16:09rhickeyall 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:10drewrOK, I understand that. I think that doesn't help me in this particular case.
16:11drewrThe abstract class I'm extending has (protected) mutators for some of its state.
16:24rhickeydrer: then gen-class will do it for you - you can expose protected fields, and protected methods become public.
16:33drewrCan I not specify genclass.clj after clojure.lang.Repl on the command line?
16:33drewrI'm trying to get it loaded by default.
16:37drewrHm. for(String file : RT.processCommandLine(args)) seems like it would.
16:38drewrMaybe it got loaded and I'm just not seeing it.
16:42drewrWhen I C-c C-k the buffer I can do (doc clojure/gen-class).
17:16drewrShouldn't I be able to do (new (gen-class 'Foo))?
17:17drewrI get Unable to resolve classname: clojure.lang.PersistentList@ebfa2702.
17:17rhickeydrewr: you should be using either gen-and-load-class or gen-and-save-class
17:20drewr(new (clojure/gen-and-load-class 'Foo)) gives me the same result.
17:21rhickeygen-and-load-class is something you call once to create the Foo class. Then Foo is available like any other class - (new Foo ...)
17:21drewrOK, the side effect of the bytecode loading is what I'm after there. I get it.
17:22rhickeyright
17:23drewrDoes it load it in any particular namespace? (new Foo) tells me it can't resolve classname Foo.
17:23drewr(It successfully generated the bytecode.
17:23drewr)
17:24rhickeyyou should supply a package name
17:24rhickeyto gen-class
17:24rhickeygen-*-class
17:24drewrAh, that worked.
17:27drewrCan I use :expose if I don't know what the protected member is called? I only know the mutators.
17:27drewrDoesn't it break encapsulation to have to know the member name?
17:28rhickeythe mutators will be public in your derived class - so you can use them
17:28drewrIt's telling me "No matching method found."
17:30drewrPublic setters are working okay.
17:30rhickeyis the mutator final?
17:31drewrYes. :-(
17:31rhickeyoh well, that's it
17:31drewrBugger.
17:32drewrGuess I'll stay with my native Java class.
17:33rhickeywhat were you trying to derive from, if I might ask?
17:33drewrThis guy: http://www.jibble.org/javadocs/pircbot/org/jibble/pircbot/PircBot.html.
17:34drewr,foo
17:34clojurebotI don't yet know what "foo" means.
17:34drewr,learn foo
17:34clojurebotI don't yet know what "learn foo" means.
17:34drewrWell shucks. :-)
17:36rhickey,uh oh
17:36drewrIt times out after a minute or two.
17:44Chouserdrewr: do you have a good sandbox for that bot?
17:44drewrChouser: I was in #clojure- all day.
17:45ChouserI was thinking an ajaxy REPL might be nice for people to dabble a little without having to install anything.
17:45Chouser...but obviously I don't want them to be able to do anything to my server.
17:46drewrThe dangerous parts can be disabled if we can identify what they are.
17:46rhickeyor use Java's security mechanisms
17:47drewrThat's more than I know. ;-)
17:47drewrAny guesses as to the approach?
17:49ChouserI guess I'd start looking at applet containers, but that's a long way from a working solution.
17:49dudleyfhttp://java.sun.com/javase/6/docs/technotes/guides/security/index.html
17:49ChouserAnd also a chroot on the server to be extra safe.
17:49dudleyf.. but that's a long way from a working solution ;-)
17:49Chouser:-)
17:52Chouserhttp://java.sun.com/javase/6/docs/technotes/guides/security/permissions.html
17:52Chousera tiny bit closer.
17:54drewrHaha, http://yaml.org/.
17:55Chousercute