#clojure logs

2008-05-02

09:31Chouser"Downloads: not available" ... how often should I be clicking reload on that page?
09:31ChouserIs every 5 seconds too much?
09:31rhickey:)
09:31jteoemacs should be good enough for anyone
09:36Chouserbecause elisp is as good as Clojure?
09:38jteolet's not go there. :)
09:40Chouser:-)
09:41Chouserseriously though, the ancientness of elisp (and other parts of emacs) are major contriubtors to my failure so far to switch away from vim.
09:42ChouserNot that viml (vim's scripting "language") can even be mentioned with a straight face in this context...
10:01rhickeyI'm working on:
10:01rhickey(gen-class
10:01rhickey package-qualified-name
10:01rhickey ;all below are optional
10:01rhickey :extends aclass
10:01rhickey :implements [interface ...]
10:01rhickey :constructors {[param-types] [super-param-types], ...}
10:01rhickey :methods {name [return-type [param-types]], ...}
10:01rhickey :main boolean
10:01rhickey :factory name
10:01rhickey :exposes {protected-field {:get name :set name}, ...})
10:01rhickeywill spit out bytecode you can load immediately or store as .class file
10:01rhickeyFully statically accessible name
10:02rhickeyFully dynamic implementation, code goes in clojure namespace with same name
10:05rhickeythoughts?
10:05cgrandVery nice! What does :factory stands for? A static method name?
10:05Chouserwow.
10:05rhickeycgrand: yees, set of static methods matching ctor sigs
10:06rhickeyctor calls will flow through clojure init fn, if provided, allows you to morph args to super ctor and supply a state for the class
10:07Chouserpeople are going to try to use this for more than just Java interop, as part of the design of the clojure apps.
10:07rhickeyaah, but state is final
10:07Chouserhehe. ok, nice.
10:07rhickeybut can be actor or ref, so resulting objects are Clojure-savvy
10:08rhickeytransactional or asynch state for POJOs
10:09Chouserclass name is required?
10:10rhickeyyes, that is how the binding to Clojure code works - classname-->namespace-name
10:11rhickeyThe idea is you'll gen-class once, then proceed to implement incrementally/iteratively in Clojure
10:11rhickeyThe only part that's locked-down is what is supplied to gen-class
10:12rhickeychanging that means restarting JVM
10:18rhickeycgrand: this is why I've held up on servlets, I'm hoping gen-class can be used to generate servlets and any other stubs that used to require Java
10:19cgrandrhickey: that was my first thought while reading this: no more hand-coded java stubs :-)
10:19Chouserrhickey: ah, so once you're done (gen-class foo ...), you can're reuse the name "foo" without restarting the JVM.
10:19rhickeychouser: yes,that's the static nature of Java I can't change
10:19rhickeyI've tried in this design to maximize the dynamic parts
10:20rhickeybut classnames are load-once-per-classloader
10:23cgrandwhat about providing an (optional) file name which would be loaded in static init? Or should all the init stuff be done in user.clj? (won't asnwer, must go)
10:23Chouserthe methods list has no method bodies, does it -- just the interface description?
10:24rhickeymethods is just for additional methods, the generated class will have all methods of superclasses, and yes, no code in gen-class at all
10:25Chouserok, so you're generally do (gen-class Foo ...) and later (proxy [Foo] ...).
10:26ChouserSorry if I'm a little slow on the uptake here.
10:27rhickeygen-class builds a class that redirects method calls to vars named classname/methodname
10:27ericthorsenrich: how close are u to putting up the work?
10:27ericthorsenI'm ready!
10:27rhickeyit's in svn, but not done
10:28Chouserohhh... gen-class links a Clojure namespace to a new Java class
10:29ericthorsenok
10:29rhickeyright
10:29Chouserwhich I now see you said up at the top.
10:29Chouserthe method functions get an extra first param for the class instance?
10:30rhickeyyes
10:30rhickey(gen-class org.clojure.MyComparator :implements [Comparator])
10:30rhickey(in-ns 'org.clojure.MyComparator)
10:30rhickey(defn compare [this x y] ...)
11:59cgrandrhickey: you mentioned that instances can hold state (as a final field?) how would one declare it and access it?
12:01rhickeywas hardwired (to __state) when we last spoke, now there is a :state key, and an :init key which name the state and constructor initializer respectively
12:02rhickeyaccess like a normal field, will be public like all members in these classes
12:02rhickeyif :state not supplied, no state
12:04rhickeyinit takes ctor-args and returns [[super-ctor-args] state]
12:05rhickeys/returns/must return
12:05cgrandok I understand now
12:14cgrandSo, prior to instantiation the namespace and its functions must be defined. This means that when the user doesn't control object creation (because he's using some framework) everything must be initialized as soon as Clojure ends initializing (eg through user.clj). Am I right?
12:18rhickeyPartially. The generated class will create the namespace as a side-effect of having static Var fields. If there is no init, then objects can be created right away. Code will need to be loaded prior to method calls in order to avoid UnsupportedOperation. But in general, yes, user.clj is the path to pre-loading.
12:25rhickeycgrand: I'm not averse to your suggestion of an option for the class to load its own code, need to think about any circularities
14:13leafwis there any way to set stdout in clojure?
14:13leafw(with-out-str ...) works inconsistently
14:14rhickeyleafw: bind *out*
14:22lisppaste8Chouser pasted "exception trying to implement a Map" at http://paste.lisp.org/display/60112
14:24ChouserHow could I do dissoc correctly, but mess up assoc? Anyone have any ideas?
14:25leafw'bind' is not a keyword in boot.clj
14:25leafw'binding'?
14:25rhickeyyes, bind *out* with 'binding'
14:26rhickeylike with-out-str does
14:28leafwI a using with-out-str
14:28leafwbut half the times it ends up not printing anything ,i.e. "prn" calls don't print anywhere
14:28rhickeywith-out-str prints to a string
14:29rhickeywhat do you do with the string it returns?
14:29leafwIjust print it
14:29leafwprints with quoed newline and quoted quotes chars
14:30leafwI know this may not sound ver yhelpful.
14:31leafwcode is at http://pacific.mpi-cbg.de/cgi-bin/gitweb.cgi?p=fiji.git;a=blob;f=src-plugins/Clojure/Clojure_Interpreter.java;h=8f664da07b8424cccdb1d38d746cc3c0b632927c;hb=1435e05539abc332386b515f7a4aa2df1f1236ac#l144
14:32leafwI created an interpreter, consisting of two JTextArea
14:32leafwexists in superclass AbstractInterpreter.
14:32leafwthe ListThread is called via 'eval(String text)' method
14:33abrooksrhickey: I'd suggest that your respectable mop of hair may make up for lack of facial hair but you may want to consider growing a beard for good measure: http://blogs.microsoft.co.il/blogs/tamir/archive/2008/04/28/computer-languages-and-facial-hair-take-two.aspx
14:33abrooks;-)
14:33rhickeyleafw: could you post a small example of your problem to paste.lisp.org?
14:34leafwI think I saw part of the problem
14:34leafwcertainly on my side
14:34leafwI am returning from the while loop ... not ok if the parsing is not done.
14:36leafwyes, fixed. Oh well. thanks anyway.
14:40rhickeyenclojure got dzoned - better get a download up soon :)
14:41leafwas long as java exists, there'll be those who bypass the pain by using clojure.
14:41rhickeyChouser: I can reproduce, looking at it now
14:48rhickeyChouser: I'm guessing it has to do with the covariant return type
14:49rhickeyAssociative.assoc returns Associative and IPersistentMap.assoc returns IPersistentMap
14:52abrooksrhickey: Going back to the awaiting a set of agents which mutually send to eachother. No, I don't know the number of jobs a priori. CountDownLatch isn't going to help me. Since almost exclusively all the jobs set to an agent are not originating from a thread outside of the agent pool, I don't have any way (that I can think of) to know when all queued jobs are done.
14:53abrooksAgents feel like a good fit for the problem but I don't know how to know when they're done.
14:54rhickeyhow do you know to stop creating jobs?
14:54leafwAfter much testing, I remain clueless: the fallowing fails. (binding *out* (. System out)) -- but with-out-str never fails, and uses a similar construct
14:54leafwoh Isee
14:54leafwbinding is like a let.
14:55Chouserrhickey: thanks. I'll try to turn that nugget into a fix.
14:58abrooksrhickey: An agent only adds jobs when it sees work to do. Eventually, there's no more work todo. The problem is finding the lowest cost path across a the matrix (where nodes have cost and edges are free).
14:59rhickeyabrooks: are the agents in a list somewhere?
15:00rhickeyabrooks: could you countdown agent idleness rather than jobs?
15:02abrooksrhickey: I have the agents in a map. How can I detect their idleness?
15:04rhickeyabrooks: nothing automatic here, just brainstorming, they would have to report their idleness somehow
15:04abrooksAh. Gotcha.
15:06abrooksWhat about some sort of barrier that you could send off to a set of agents wait for?
15:07rhickeythere is CyclicBarrier
15:07abrooksIs that a Java object?
15:07rhickeyyeah in java.util.concurrent
15:08rhickeyif you have a fixed number of agents and they each know when they are done, that could work
15:08abrooksI'll take a look at that. Thanks.
15:08rhickeyshame you can't increment CountDownLatch...
15:09abrooksAh, here's the catch. A particular job knows when it's done but the agent does not.
15:09rhickeythat's what I mant about incrementing countdownlatch, then each job issued would increment, each completed would decrement
15:10abrooksI could track the number of jobs going to zero but that would create a lot of contention on a single object.
15:10abrooks(i.e. count up on send, count down on job completion)
15:11rhickeyright
15:11rhickeythe problem isn't contention - AtomicInteger is plenty fast, the problem is polling for done
15:11abrooksRight.
15:11rhickeyvs blocking for done
15:14rhickeygot it - use atomicinteger and exchanger - job setting count to zero enters exchanger, master waits on exchanger
15:14abrooksRight, but jobs could check the value before they exit and perhaps trigger some thread wakeup.
15:14rhickey?
15:16abrooksIf the "master" thread were to sleep or enter some sort of Java blocking primitive that I know nothing about but imagine it exists, the jobs could do the count up and count down. A job, before exiting could check the counter and unblock the master thread if the count was zero.
15:16rhickeyevery job issuer increments and every completing job decrements
15:16rhickeySee AtomicInteger and Exchanger
15:17abrooksRight. And following that decrement the completing job could wake up the master so the master can block instead of be polling.
15:17rhickeyno peeking, decrementAndGet
15:17rhickeywhen 0, exchange
15:18abrooksOkay, that. :) I don't know what Java offers. I've largely avoided Java for other languages when possible...
15:18rhickeyjava.util.concurrent rocks
15:20abrooksrhickey: I'll familiarize myself with it (and try to stop asking ignorant questions). Thanks!
15:21rhickeyabrooks: you're welcome
15:56abrooksrhickey: java.util.concurrent does have some nifty tools. FutureTask is something I've wanted on a number of occasions and needed to fall back on periodic polling in the work thread on a cancellation flag.
15:57ericthorsen1st alpha of enclojure is up. Please read the Getting Started page before you begin.
16:11rhickeyabrooks: and remember Clojure fns are Callable, so plug right into that framework
16:11abrooksabrooks: Duly noted. :)
16:13rhickeyericthorsen: congrats! and thanks
16:14abrooksrhickey: Hm. I really need to stop talking to myself in IRC. The above was, of course, meant for you. :-/
16:50rhickeyChouser: your proxy problem is fixed
16:51Chouserrhickey: oh! I thought the problem was on my end.
16:52rhickeyno, proxy needed to gen 2 methods when returns types are covariant
16:52rhickeynow it does
16:54Chouserbeautiful.
16:59bgeroncan take some time, though ;)
17:01Chouseroh! Yes, git is also beautiful, but I meant rhickey's fix.
17:01bgeronoh okay ;)
17:01Chouserabrooks: you saw my paste earlier? That's (the beginning of) that default-hash you wanted.
17:02abrooksChouser: I didn't. Thanks for pointing that out.
17:05abrooksJust as an FYI. Sourceforge can host Mercurial projects. I'm not sure about git but suspect that it's doable. Public (free) git hosting is also available here: http://repo.or.cz/
17:05abrooks... if Clojure would ever want to be hosted in either DVCS. %coughs%
17:06abrooksIs there anything blocking that?
17:06rhickeynot sure about IntelliJ support
17:06rhickeylack of spare time
17:07rhickeyimprove Clojure vs fiddle with VCS
17:08abrooksrhickey: Good reason. We don't want to distract you from Clojure. :)
17:18rhickeyfor the intrepid, if you want to play with gen-class in progress, what I just put up supports :extends, :implements, :state, :init, and :constructors