#clojure logs

2008-06-30

08:19StartsWithKanyone knows did yrb maybe changed his nick or something? two week ago we had discussion about wrapper for jogl lib and he expressed interest in using it.
08:20StartsWithKrepo is still at http://freehg.org/u/kresimir/neman/ not finished, but there are now 6 examples and i uploaded couple of other thigs.
08:20StartsWithKso.. if anyone is interested
10:20cemerickSo, I'd like to use a namespace via some alias -- e.g. say there's a foobarbaz namespace that I want to use, but its name is too long, or it conflicts with some name I want to use, and I don't want to refer it (i.e. (refer 'foobarbaz)). What I'd like to do is something like (alias 'foobarbaz 'someprettyname), and then be able to use foobarbaz defs and such via someprettyname/*.
10:21cemerickI put together a macro that sorta-kinda works, but:
10:22cemerick(a) I'm not sure I'm touching everything I need to in order to "ball up" the referred-to namespace into one that has the more preferable name,
10:22cemerickand (b) this route leads to serious namespace pollution (i.e. lots of top-level namespaces that exist only as aliases)
10:23rhickeythere will be namespace aliases at some point
10:23cemerickOK. I won't plumb down that dead end anymore, then.
10:23rhickeyI can't imagine a good user-level solution
10:23cemerickYeah, it got pretty messy pretty quick for me.
10:24cemerickFWIW, I'm putting this out there to resolve the long-namespace problem related to aligning namespaces with Java packages (brought up here: http://groups.google.com/group/clojure/browse_frm/thread/4b875918d3255119?hl=en)
10:26rhickeyI think Clojure will move towards Java-style namespaces, which are long, so aliases will be needed. Also to putting clj files in directories mirroring what Java does. This will allow me to compile bytecode with the Clojure namespaces and have Java tooling be able to find it
10:28cemerickNice. I wasn't sure where you were heading with that, as previous comments you made in the group sounded skeptical of having one-to-one relationships between directories and packages/namespaces. +1 to that, IMO.
10:32rhickeywhen in Rome...
10:39ChouserComing from C++-land, I've never been sure I liked Java's mapping of namespaces to directories, so I appreciate that hasn't been assumed all along here.
10:40ChouserEnding up that way for good reasons, though, is entirely fine by me. :-)
10:41rhickeyThere are lots of things that leverage classpath-relativity
10:42ChouserDid create-struct used to act like defstruct does now?
10:43rhickeyit's used by defstruct
10:44elgn i
10:44elg-chat then i
10:44elgoh, wrong channel sorry. (stupid client)
10:44rhickeyChouser: did you see seque?
10:46rhickeyI was wondering why you used Deque? (not in Java 1.5)
10:48Chouserrhickey: I did, I'm still picking through it.
10:49ChouserHandling of nil and false is very nice.
10:50ChouserThe reason I did *enqueue* the way I did is because my initial use-case will have a sax parser as the producer, so I won't have the opportunity to return my seq members. Hence *enqueue*.
10:51ChouserBut perhaps it would be better to decompose those two parts (seque and *enqueue*) somehow.
10:51rhickeyYou can't make a lazy-seq on the parser?
10:51ChouserI'm gratified you caught the purpose @agt :-)
10:52Chouser(to propogate exceptions)
10:52rhickeythanks for the docs :)
10:52rhickeyI didn't at first
10:52Chouserthis *is* how I'm making a lazy-seq of the parser!
10:52rhickeyoh, sax parser is callback based...
10:53Chouserright.
10:53rhickeyyuck
10:53Chouserthere are pull-parsers out there, which is a much nicer model, but they're not bundled with Java.
10:54rhickeyif we standardize the sentinels, we could have a queue-seq
10:54rhickeythen just have your callback fill a queue
10:55rhickeyseque could use queue-seq
10:55ChouserI think I'd still need a separate thread for the parser and callbacks.
10:55rhickeyQNIL, QEOS
10:57ChouserI did have a question that pertains to seque and my original ... if nobody consumes to the end of the seq, we've got a blocked thread hanging out there.
10:57ChouserWill the thread be GC'ed?
10:57rhickeynope
10:58Chouseryeah, that was my guess. so it'd be easy to use the seq in a lazy context and leak threads. :-/
10:58rhickeyyeah, I thought about a weak ref to the queue in the agent fn
11:00rhickeyjava.lang.ref.WeakReference
11:01abrookshttp://www.usenix.org/events/usenix08/tech/full_papers/tang/tang_html/index.html
11:02ChouserAre threads ever GC'ed while they're still running (or blocked)? I kinda assumed they wouldn't be.
11:02abrooksOnly tangentially related but I thought it was interesting and perhaps of general interest.
11:03abrooksEr, this is a better link: http://www.usenix.org/events/usenix08/tech/tang.html
11:03rhickeyabrooks: very neat. What's nice for Clojure is as things like this end up in the JVM, Clojure gets them for free
11:03abrooksrhickey: Right.
11:10Chouserrhickey: I used Deque because I'm a complete Java noob. I wanted "Linked" instead of "Array", and didn't notice there was a "Queue" version. I spent a couple minutes trying to figure out what the difference was, but since it worked for me I just gave up and used it.
11:10ChouserI see now that Deque is a Double Ended Queue, and I don't need that at all of course.
11:11rhickeyah. I just use the 1.5 JavaDoc so I don't even see things I can't use
11:11rhickeytrying to keep Clojure 1.5 compatible
11:13drewrrhickey: Those of us still on OS X 10.4 thank you. :-)
11:13rhickeythat would be me too :)
11:14ChouserHm, and my wife. So I guess I should also be greatful.
11:15drewrWhat are the big improvements 1.5 -> 1.6?
11:16ChouserWell, mainly these nifty double-ended queues.
11:16Chouser;-)
11:17drewrInteresting. I've never seen native support for deques in any language before.
11:22abrooksdrewr: Python has deques: http://docs.python.org/lib/deque-objects.html
11:22abrooksPython 2.4
11:23abrooksGoogle reminded me.
11:23drewrabrooks: By the beard of Zeus! I've never noticed that.
11:23abrooks:)
11:24lisppaste8rhickey pasted "seque with reclamation" at http://paste.lisp.org/display/63042
11:25drewrI check out PEPs too, but generally after the fact to see the motivation for a particular feature.
11:26lisppaste8rhickey annotated #63042 with "seque" at http://paste.lisp.org/display/63042#1
11:26abrooksdrewr: http://www.python.org/dev/peps/peps.rss
11:28rhickeyChouser: that one cleans up threads when no one is using the seq anymore - even works for unbounded seques on infinite seqs, if you don't run out of memory first
11:28drewrabrooks: Thanks.
11:28Chouserrhickey: very cool.
11:29Chouseris it using weak-NIL to notice when it's no longer needed?
11:29Chouserit == agent, I guess.
11:29rhickeyright - the consuming seq has a strong reference to NIL, the agent doesn't
11:30Chouserif you constrain the size of the queue and cause the agent to block, might it get stuck there and no go around again to discover it's not needed?
11:31cemerickWe still need to keep PDFTextStream JDK 1.4 compatible -- there's a *lot* of people still on 1.3/1.4, and not planning on moving any time soon.
11:31rhickeyChouser: ugh, yup
11:31Chouserrhickey: sorry to snipe. :-/
11:33ChouserWeakReference doesn't seem to have a way to get some code run when the reference is broken. :-(
11:34rhickeythat wouldn't work - but it can put them on a queue
11:34rhickeyI could use timeouts...
11:34Chouseroh! a timeout wouldn't be too bad.
11:35Chouser.poll
11:36rhickeyno, on the offer side
11:37Chouserbut for all your work to do my use case any good, I've got to figure out how get callbacks in there.
11:37Chouseroh, right. .offer
11:38ChouserI'd rather not have 2 extra threads when I really only need 1.
11:49Chouserhm, ([s] ... [[... :as s] s]) ... you'd never know s is immutable. ;-)
12:05kotarakis creating a closure with fn cheap?
12:19rhickeykotarak: yes, the fn gets compiled once and the fn value is a simple ctor call
12:22kotarak_ok. the problem was (is?) a macro which is needed because not all arguments are to be evaluated immediately.
12:22kotarak_now I wondered whether to put everything in a macro or into a driver function with a small macro wrapper.
12:23rhickeythe latter
12:23kotarak_The wrapper creates a fn which may (or may not) be called by the driver
12:23kotarak_ah. ok.
13:01lisppaste8rhickey annotated #63042 with "seque w/timeout" at http://paste.lisp.org/display/63042#2
13:23Chouserrhickey: cool. Now for my sax parser... ;-)
13:24Chousermy general approach of providing *enqueue* as a binding that my callbacks can use is sound, right?
13:24rhickeycan we not just Lego-ize the seque code?
13:25ChouserI hope so, but I want to make sure I'm headed in the right direction.
13:26ChouserI don't see how to get sax+callbacks to populate a seq or queue without it having its own thread.
13:26Chousermy callbacks have to push data somewhere, and the place that makes sense is an LBQ
13:26rhickeycan you just send an agent off with the sax parse method?
13:27rhickeyyes, push onto LBQ
13:27Chouseryes, that's what I was using the original seque (or with-bg-queue) agent and LBQ for.
13:29ChouserI guess what I think I have to do is have something almost exactly like your seque (hopefully built out of the same parts) with the only difference being the agent fn
13:29rhickeywhen I look at seque, I see <-seq<-queue<-seq
13:30rhickeyand your parse: <-seq<-queue<-parser
13:30rhickeyso, queue-seq: <-seq<-queue seems to be a common part
13:32Chouseryes, but seque is controls the loop for the right-hand <-seq part, and is calling rest on it. I can't make my parser behave like that without essentially doing my original with-bg-queue stuff again.
13:33Chouserso I guess I'd like to be able to ask seque (or a slightly different version of it) to still provide *enqueque* or *lbq*
13:33rhickey(defn seque [n s]
13:33rhickey (queue->seq (seq->queue n s)))
13:34Chouserin fact *enqueue* ought to now do the keep-alive detection stuff and throw an exception or something the unwind the sax parser if its not needed.
13:35Chousers/the unwind/to unwind/
13:37rhickey(defn sax-seq [n xml]
13:37rhickey (let [q (LBQ n)]
13:37rhickey (send-off agent sax->queue xml q)
13:37rhickey (queue->seq q)))
13:38rhickeypseudocode of course, keep-alive the trick
13:40rhickeyqueue/seq protocol will have to define eos/nil/exception sentinels
13:41rhickeyi.e. put exceptions in queue rather than tie consumer to producer agent
13:47Chouserok, maybe I'm beginning to understand how that might work.
14:00Chouserof course somebody in that agent needs to know about the sentinels and how to use them. If LBQ is the stock Java class, then sax->queue itself would have to be dealing with keep-alive, NIL, .offer, etc. which seems a shame.
14:01rhickeya function can hide some of that
14:01Chouseryes
14:02ChouserI think we're actually approaching the same solution. But I'm still trying to understand if my *enqueue* is Bad or not.
14:27Lau_of_DKChouser: Are you working on lazy xml ?
14:31ChouserLau_of_DK: yep
14:31Lau_of_DKInteresting - How close are you to finishing ?
14:31Chouserwell "working" is a bit of a stretch, but yeah that's the goal.
14:31Chouserquite a ways.
14:31Lau_of_DKPlease let me know when you complete, I'd love to see it
14:32Chouseronce we've got seque hammered out, it'll be easy to generate a lazy seq of sax events. That's very close to done.
14:32Lau_of_DKIts it buggy or just not running ?
14:33Chouserbut then I've got to build a lazy tree from that seq. I have a plan, but it's another whole stage.
14:33Chouserthe pieces just aren't written yet. no bugs. ;-)
14:33Lau_of_DKk
14:51lisppaste8Chouser annotated #63042 with "seque and with-seque" at http://paste.lisp.org/display/63042#3
14:52Chouserrhickey: I'm sure you'll hate the ugliness of using *enqueue* internally in seque, but it gets the job done without extra threads or duplicating code.
16:45ChouserI can't use :when and :while in the same for?
16:46rhickeyno, do you need to?
16:47bpattisonshould (pr "\u0022") produce "\"" with an extra backslash? I was expecting just a double quote (")
16:49rhickeypr prints readably, try print
16:50Chouseryeah, I want (filter p1 (take-while p2 s))
16:50bpattisonokay -- that works -- thanks
16:51ChouserI was hoping to write that (for [i s] :when p1 :while p2)
16:52Chouserno big deal. the classic formation's nearly as good as the for-comprehension would be.
16:53kotarakclojure is so much fun: I'm trying to understand monads and I implemented a let-bind which is in no way more wordy than Haskell's >>= notation. :)
16:54rhickeywhat does let-bind do?
16:56kotarakit does basically simplify: (bind m1 (fn [x1] (bind m2 (fn [x2] (do-something-with x1 x2)))))) to (let-bind [x1 m1 x2 m2] (do-something-with x1 x2))
16:58rhickeywhat does bind do?
16:59kotarakbind does: (defn bind [m k] (fn [x] (let [y (m x)] ((k y))))
16:59kotarakoops. just a second. confusion
17:01kotarakok. It depends on the monad, I suppose (as I as said: just trying to understand). For the identity monad it is: (defn bind [a k] (k a))
17:04kotarakFor the error monad (whatever this may be): (defn [[t a] k] (cond (= t 'success) (k a) (= t 'failure) ['failure a]))
17:04kotarakdefn bind, of course
18:52meredyddWhat's the current status on regexps?
18:52meredyddI heard rhickey talking about the possibility of making #"patterns" no longer instances of java.util.Pattern
18:53meredydd(for the purpose of making them invokable)
18:53meredyddAnd what's the situation wrt escapes?
19:18rhickeymeredydd: no changes near term on regex
19:19meredyddOkay. So, it's still good old-fashioned leaning toothpicks?
19:19rhickeyyup
19:20meredyddNative reader syntax for regexps is such a win to start with, it feels churlish to complain :)
19:21rhickeythere have been several threads but each has petered out before consensus
20:29slavarhickey: does clojure allow reader macros?
20:33rhickeyslava: no
21:58Chouseris having both drop and nthrest intentional?
22:01Chousermore importantly, is there a function that takes a seq and returns the same lazy seq except shorter by one?
22:03slavarest?
22:04Chouserah. :-) right, but shorter on the other end.
22:05ChouserSorry I didn't make that clear.
22:05blackdogbutlast?
22:05Chouserright!
22:05Chouseroh, it's there already. perfect, thanks.
22:05blackdogbut it's not lazy?
22:05slavait can't be lazy, it has to evaluate the sequence to get the length
22:08Chouserit could be lazy, just ahead by one. Which is what I need, so I guess I'll write it.
22:10Chouser(defn but-last [[n & r]] (when r (lazy-cons n (but-last r))))
22:10Chousernot too painful I guess
22:10Chouserrhickey: any reason the builtin butlast should be eager?
22:15Chouserhm, I guess mine chokes if you give it a zero-length seq. that's ok for my use case though.
22:30rhickeyChouser: no reason, cgrand pointed that out, will fix at some point
23:33Chouserwell, I've got lazy xml parsing working. a drop-in replacement for src/xml.clj
23:51ChouserIt's still pretty rough, but here it is in case anyone wants to throw rotten tomatoes: http://n01se.net/paste/nRFa