#clojure logs

2008-09-02

07:50parth_mHello
07:52parth_mIf I am to write a print-decorator http://groups.google.com/group/clojure/msg/cb7a45124bbf92f5 what would be a good way to get the name of the function being decorated at runtime?
07:53parth_mIn the method suggested, having to switch namespaces seems a little weird.
07:53parth_mIf I don't switch ns, there is stack overflow.
08:01hoeckparth_m: why not just taking the functions classname at runtime?
08:02parth_mhoeck: as (class f)?
08:03parth_mThis works, actually just a print also works but it shows the compiled form .. e.g user.foo__2372@5388b5
08:03parth_mI was wondering if I can get "foo"
08:03hoeckof course, with some string and regex matching
08:04hoeckand it has the advantage of working with (named) anonymous functions (which i use very often) :)
08:05parth_mYes .. I could do that.
08:05parth_mI am not too clear on using meta data. I know the info exists ... just not sure how to get it.
08:05parth_muser=> (meta (var foo))
08:05parth_m{:arglists ([]), :file "NO_SOURCE_FILE", :line 9, :ns #<Namespace: user>, :name foo}
08:06parth_mSo, "foo" is definitely there somewhere ... but in the decorator scenario it doesn't seem to work. Throws an exception: http://groups.google.com/group/clojure/msg/91b028c63ec440d6
08:10parth_mIts not a big thing ... I was just wondering in case there is a idiomatic way of doing this.
08:11hoeckmhh, aren't vars resolved at compile-time?
08:12parth_mI suppose so.
08:14parth_mBut if we pass "foo" to "print-decorate" isn't the meta-data attached to "foo"? This may be a silly question but I still don't understand clojure meta-data fully.
08:15hoeckno, metadata is only attached to vars and a few clojure data-structures
08:16parth_mAh. I think I get it now. So what gets passed is a function ... so there is no metadata attached. Right?
08:17hoeckyes, the metadata you create with defn gets only attached to the var holding the function object
08:18hoeckbut the AFn Class actually has a withMeta method, but it throws an unsupported operation exception, so in theory, you could attach metadata to functions too
08:19parth_mHaving metadata with functions would be nice ... I suppose that needs to fit into the overall introspection picture.
08:20parth_mThanks hoeck. I understand this much better now.
08:20parth_mSo when we do #'foo its a var. and just 'foo' is a function being passed.
08:25hoeckyeah, #'foo is a shortcut for (var foo), and foo evaluates to the value of foo (in this case a function)
08:26parth_mCommon Lisp had me confused ... I thought #'foo was a function as with CL :)
08:26parth_mThanks hoeck. Will use the class for now.
08:27hoeckme too, but clojure has only one namespace for functions and values, which I find pretty handy btw
08:28parth_mI agree. Its much nicer to say (map foo ..) rather than (map #'foo ..)
09:23cemerickrhickey: it turns out that the NB profiler chokes on clojure in general (though your genclass patch stops it from tossing a hard error); the process being profiled "hangs" (for lack of a better term) as soon as clojure.lang.RT is statically referenced.
09:24rhickeycemerick: that's bad, last time I tried it it ran no problem but only profiled the Java bits of Clojure
09:24rhickeycemerick: I see you got the 18-arg patch
09:25cemerickyeah I did; so, you set up the profiler to instrument only clojure.lang.*?
09:26rhickeyI don't remember too well, but I think I asked for everything but standard Java libs, got only Java calls
09:27cemerickFWIW, dumping profiling data via -hprof options works just fine (which I load up in hpjmeter) -- crude, but effective.
09:31rhickeysoneone suggested JiP at one point: http://jiprof.sourceforge.net/
09:31rhickeysomeone
10:11cemerickrhickey: thanks for the link; I think I'll try yourkit next, just to see if NB is the problem, or if clojure/asm/whatever is somehow at odds with JVMPI itself.
11:42cemerickyourkit profiles the same NB project without a problem; however, a super-small project I put together that contains only clojure.jar and a main class that references clojure.lang.RT is successfully profiled by NB....so, now I'm pretty confused.
15:13lisppaste8jamii pasted "qt-repl" at http://paste.lisp.org/display/66213
16:19jgracinrhickey, hi! how come there are no tests in Clojure's implementation?
16:19jgracinI'm obviously asking about your opinion on automatic testing. :-)
16:32rhickeyjgracin: no one's written any yet
16:32abrooks_Heh.
16:33rhickeya test suite would be a welcome contribution
16:35Chouserpeople have talked some about how a test suite would be structured. It'll happen eventually.
16:36rhickeyuntil then I'll just keep trying to get it right the first time :)
16:40jgracinrhickey, nice strategy. :-)
17:36lisppaste8jamii pasted "qt repl and slots in action" at http://paste.lisp.org/display/66224
17:44jamiiHow do I create instances of generic classes?
17:44jamiieg Signal1<Object>
17:44Chouserignore the generic part
17:44Chouserso, just Signal1
17:44jamiiHmmm. Qt might not like that. Ill give it a try
17:51jamiiHow do I use a nested class? I would have thought (import '(com.trolltech.qt.QSignalEmitter Signal0)) would work
17:52kotarakTry QSignalEmitter$Signal0
17:53jamiiYep, that worked.
17:53jamiiIs the $ specific to imports?
17:53kotarakNo, it's for nested classes.
17:53jamiiOk. Cheers
18:11jamiiDamn, I wish new wasnt a macro.
18:14kotarakIt's not. It's a special form, AFAIK. What do you want to do?
18:18jamiikotorak: I need to create one of Signal0 to Signal10 depending on the argument number
18:19jamiisomething like: (defn signal [n] (new (sym "Signal" (str n))))
18:20jamiiI dont think its possible with new though. Is there another primitive for constructing objects?
18:20kotarakNot that I am aware of...
18:21jamiiOh well. cond it is then
18:21kotarakYou could resolve to ugly anti-features:
18:21kotarak(let [c TheClassYouNeed] (eval `(new ~c)))
18:23jamiiThat'll do. It doesnt have to be pretty
18:23kotarakcond is probably the better solution. Also not pretty, but one has a good conscience.
19:42Chouseris it any prettier to do the evals up front?
19:43jamiiIs there a way to add java fields to a class using proxy? Signals can only appear as a field of a subclass of QSignalEmitter. Which is a little annoying. I've been trying to do this using gen-and-load-class but the :state option is causing problems
19:43Chouser(def sigs (vec (for [i (range 10)] (eval `(fn [] (new ~(symbol (str "Signal" i))))))))
19:44jamiiChouser: Im using almost exactly that code :-)
19:44Chouserjamii: no, you'll have to use gen-class to add a field.
19:44jamiiSo i need to use :state and :init
19:45jamiiHow does the scoping work in :init - it keeps complaining that my init function isnt defined
19:45jamiiThis is what I have at the moment:
19:45jamii(defn- make-signal-holder [n]
19:45jamii (gen-and-load-class
19:45jamii (symbol (str "slot.SignalHolder" n))
19:45jamii :extends QSignalEmitter
19:45jamii :constructors {[(eval (symbol (str "QSignalEmitter$Signal" n)))] []}
19:45jamii :init 'signal-holder-init
19:45jamii :state 'signal))
19:46Chouseryou're running the last release, or latest SVN?
19:46jamiiSomewhere in between... svn 1-2 weeks old
19:47Chouserok, your defn probably needs to use the name SignalHolder-signal-holder-init
19:49rhickeyjamii: for no-arg dynamic new - (.newInstance (Class/forName str))
19:49jamiirhickey: Thanks
19:52jamiiHang on, that needs to be (.. (Class/forName str) (getConstructor types) (newInstance))
19:53rhickeyjamii: are there args? your examples didn't have any
19:54jamiiSorry. The examples didnt have any because the jambi docs are wrong. There is in fact a single mystery arg
19:55rhickey(clojure.lang.Reflector/invokeConstructor (Class/forName str) (to-array args))
19:56jamiicool
19:57rhickeybetter still, use RT.classForName which will leverage Clojure's classpath stuff
19:59rhickey(resolve (symbol "java.util.ArrayList")) is another way to look at it
20:06jamiiIt seems that jambi is not fooled by gen-and-load-class: "java.lang.RuntimeException: Signals must be declared as members of QSignalEmitter subclasses"
20:06rhickeyjamii: are you extending that class?
20:07jamiiYes
20:07jamiiAnd putting the signal in the :state slot
20:09jamiigoogle has nothing. Does :state produce a real field. Maybe I should try a property instead
20:10rhickeyhttp://doc.troll.no/qtjambi-4.3.4_01/doc/html/com/trolltech/qt/qtjambi-signalsandslots.html says: All normal member methods can be used as slots, so there are no specific requirements for a method to function as a slot.
20:11jamiiSignals and slots are not the same. I've managed to wrap clojure functions as slots quite easily. The trouble is that new signals have to be created as members of a QSignalEmitter
20:18rhickeyjamii: :state does produce a public final field of type Object.
20:19rhickeybut it seems like you can define accessor methods for signals, rather than use fields, as implied by "It is customary to declare signals as public rather than to provide access methods for them."
20:20jamiiI'll try using :exposes
20:21rhickeyjamii: that's just for exposing an existing protected field of a superclass
20:21jamiiDamn
20:31Chouserdoes final mean everything inside that object will be immutable, or is it just that the top-level value of that field cannot change?
20:36rhickeyChouser: the latter
21:09jamiiTo import a java file in clojure do I have to do anything beyond compile it and set the classpath?
21:18shooverjamii: That should do it. If the file is compiled to a .class, put the directory on the classpath. If the .class is part of a jar, put the jar on the classpath.
21:20jamiiOk, i probably have a typo buried deep in the folder hierarchy
21:34jamiirhickey: Turns out signals have to be declared inside the scope of the QSignalEmitter subclass. Dropping into java seems to be the way forward
21:34jamiis/declared/instantiated
21:35jamiipublic Signal0 signal = new Signal0(); is the single only way it will be accepted
22:05Chouserno way to get to "this" from the init function?
22:27Chouserwouldn't matter anyway -- Qt's using getDeclaredFields to poke through the Emitter's parentage looking for a matching Signal member.
22:43jamiiChouser: I have it sort of working. It gives me an exception the first time I use a signal and works fine thereafter. I'm tempted to just have the wrapper force and catch that first exception before returning the signal. A little hacky though
22:43Chouserhm...
22:47Chouserthat's with Java code for the signals?
22:48jamiiI hava a java class that looks like:
22:48jamii public static class QField extends QObject {
22:48jamii public QField() {
22:48jamii super();
22:48jamii }
22:48jamii
22:48jamii public Object field;
22:48jamii }
22:49jamiiBecause I couldnt figure out how to do fields properly from withing clojure
22:49jamiiThen I set! field with a new signal. The mystery arg in the signal turned out to be because they're non-static inner classes - they need an instance of their container class which in this case is QField
23:03jamiisvn ~2 weeks out of date
23:04jamiioops
23:12jamiijava.lang.RuntimeException: Signal initialization failed
23:12jamiiThats a new on
23:12jamii*one
23:15jamiiChouser: All signals are failing on the first emit with "Signals must be declared as members of QSignalEmitter subclasses". Zero arity signals work fine afterwards but others fail with "Signal initialization failed". I have no idea whats going on
23:17ChouserI'm looking at the source for resolveSignal() in QSignalEmitterInternal -- but I'm don't really understand it.
23:38jamiifetchSignal is native. im getting the qt source now
23:59jamiiI think I have it