#clojure logs

2008-11-12

01:58sohailuhhh... what the f: http://commons.apache.org/jelly/
02:00tWipthat's the logical conclusion to xml-mania... making it turing complete
02:01Nafaisohail: Yes, jelly is very painful
02:01NafaiI've actually written a bit in it in the past
02:03sohailincroyable
02:04NafaiI've also done a bit in a workflow language called XPDL
02:05NafaiIt took 7 printed pages of XML to do a simple method implementation
02:05sohailwow
02:05sohailI bet that stuff pays well though
07:33Lau_of_DKGood afternoon gentlemen
08:07gnuvincemorning
09:58Carkis there any equivalent to CL's labels in clojure ?
09:58Carkso that i can recursively call a let function
09:59rhickeyCark: self-recursion is possible with (fn my-name [] ... (my-name ...))
09:59rhickeymutual local recursion a la labels/letrec is not currently supported
10:00Carkah too bad
10:00Carkthanks though
10:00rhickeyon the todo list
10:02gnuvincerhickey: would that mean that the order in which functions are defined would become unimportant?
10:03rhickeygnuvince: this is just about local/let-bound fns, but yes
10:04gnuvinceah ok.
10:37rhickeyChouser: http://clojure-log.n01se.net/ is down?
10:40abrooksrhickey: It appears to be. I'll check it out.
10:42Chouserabrooks: thanks
10:46abrooksChouser: Shoot. I need to go interview a candidate now. I'll continue after lunch.
10:50Chouserrhickey: back up
10:50rhickeyChouser: thanks!
10:51abrooksChouser: Was it Ruby?
10:52Chouserabrooks: maybe. I turned off mod_rails for clojurescript.n01se.net, and now it seems to work. Could be coincidence.
10:52ChouserI'll have to try fast-cgi or something instead.
11:05ChouserSeems like binding/set! might work for early termination of an enumerator
11:05rhickeyChouser: sounds scary
11:12Chouseralso Java uses enum to mean something completely different
11:18rhickeycgrand: thanks for the LFE post!
11:22cgrandrhickey: you're welcome
11:27cgrandchouser: I also thougt about using binding/set! and dismissed it immediatly
11:27cgrandtoo scary
11:30rhickeycgrand: you spent a lot of effort to support map, I wonder if it is as important as 'chunking', i.e. reducing at other than 1:1 ratio
11:31rhickeyfor me the inversion of control is much more about resource management than having someone else run the iteration
11:32cgrandyeah I also wondered about the practicality of suporting map (and came to no conclusion and since I was on my way...)
11:32rhickeymap is definitely a challenge
11:35rhickeyas far as supporting ordinary functions - the underlying protocol can be richer as adapters are easy
11:37cgrandWhat du you mean by "reducing at other than 1:1 ratio" : reducing N items at a time (N:1) or , for example, transforming an "enum" of char[]into an enum of lines (N:M)?
11:38rhickeythe 'slides' passed a stream to the reducing fn, not individual items
11:38rhickeyopens the door to consuming more than one item per step
11:39ChouserMy (very weak!) attempt at doing this passed a seq to the step function, which then could return however much of the seq it chose to not consume.
11:39rhickeychars to lines would be an example
11:41rhickeyChouser: yes, that's closer to the slides
11:42rhickeythere's a risk of leaking the seq, but that could be in the "don't do that" category AFAIC
11:42rhickeythe enum would close the resource and subsequent use of the seq would fail
11:43Chouseroh, if you passed the chunk-seq to outside the enum somehow?
11:43rhickeysure, it could be your return even
11:44rhickeyor passed to something in your worker code
11:44rhickeythe latter would still be in scope of enumeration
11:44Chouserok, yep, I see that.
11:46leafwrhickey, try: wn enumeration -synsn
11:46rhickeyThese internal iterations have the potential to be very fast, much faster than seqs (i.e. allocation-free), that's why I had the io/stream primitive notion under them, in my model that's what I passed. Would then go back and rebuild all the seqs on io/streams
11:46leafw(wordnet)
11:48rhickeyreducer?
11:49rhickeysupporting map would blow my model :(
11:49leafwdistiller?
11:49rhickeyvery tricky
11:49Chouseronly multi-seq map, right?
11:49rhickeyright
11:50Chousersimilar problem in ruby iterators, which I was able to solve with continuations. :-/
11:52cgrandrhickey: we had different goals: mine was to come up with a general collection "framework", yours is better IO. Fun vs practical :-)
11:52rhickeycgrand: I want both
11:56rhickeythis would be a very important addition to Clojure
11:58cgrandWorking on MFE made me thought wonder about replacing seqs by reducers as the basic building block...
11:58cgrandLFE
11:59rhickeyearly termination is not laziness
11:59rhickeyI do think the seqs can be built on ios
11:59rhickeyshould be
12:00rhickeysome ios are only available in resource managed contexts - reducers
12:00rhickeythose are the building blocks in my mind
12:01rhickeyI had played with seqs on iterators early on, but iterators are MT-broken
12:01rhickeyios can be made atomic
12:01rhickeymore primitive than iterators, just need EIO protocol
12:07cgrandI'm lost between ios and reducers. Are reducers specialized ios or two different things (ios being generators)?
12:08rhickeyios are simple streams/generators, reducers can be thought of as things that make ios available in a resource-managed context
12:09cgrandso ios aren't directly exposed in user code?
12:43cddrgeneral Java question coming up...
12:43cddrTo make a library threadsafe, must one wrap all uses of iterators inside a synchronized block?
12:45roblallyI think it is worse than that. Some Collections can't be modified whilst you iterate over them. So you have to protect the underlying collection as well as the iterator. Otherwise you get ( IIRC ) ConcurrentModificationExceptions thrown.
12:45cddryeah those are what I'm trying to fix
12:46cddralthough the underlying collections do seem to be Vectors rather than lists so maybe not so bad
12:47roblallyVector is one of the old collection classes that are synchronised by default. But that doesn't protect the iterators.
12:47roblallyIf it isn't too expensive, I copy the collection before iteration 'just to be sure'
12:48roblallyOf course that may not give you the right answer in every case.
12:50cddrI tried the copy (clone) approach before but it didn't seem to work (i.e. still got the same exception)
12:52roblallyI guess that you need to lock during the copy process ( since copying to another class that takes a Collection parameter in it's constructor will probably fall back to an internal iterator.
12:53cddrapologies for non #clojure related spam but I have asked this stuff on c.l.j and got nothing
12:53cddrI'll shut-up now, thanks roblally
12:54roblallyBut locking during copy should be less painful than locking during the whole iteration process. Basically you need to lock on every operation that touches the collection. Without the copy you need to lock on the collection plus the iterator ( which is much nastier in Java )
12:54roblallyHappy to try to help.
12:55roblally(As an aside, having a conversation that shows the pain of not using Clojure on a Clojure list will probably just make everyone here feel all warm inside)
12:56cddrlol
12:57Carkwell sometimes the java non-sense leaks to clojure too ...
12:57Carkthose tons of different and incompatible listener interfaces .... i hate these
12:58Carkdon't know how i could abstract that to a simple function call
12:59Carkso in the end, i make a proxy for ListSelectionListener, then another one for ChangeListener etc ... they all have the same single event parameter.. grrr
13:11ChousukeCark: maybe you could use a multimethod?
13:12ChousukeCark: that way, there would still be multiple functions for creating proxies but at least they'd be an implementation detail
13:19rhickeycgrand: sorry, got called away - ios could be exposed where safe
13:20rhickeyfor instance an io could be passed to the fn inside a reducer
13:21Carkchousuke : yep that makes sense
13:23Carkchousuke : but i still need to declare the type of listener for each callback invocation
13:24Carkstill shorter than a full proxy form tho
14:07ChouserCark: could you write a macro to abstract away whatever's in common between those proxies?
14:14Carkchouser : yes i'm in the process of doing so
14:15Carkactually i'll do that tomorrow, time to kick back and watch a movie ... see you all tomorrow
14:51drewrI've got a lazy stream that is exhausting my heap space.
14:51drewrI have a (count) in front of it. Would that be keeping objects around so that they're not GC'ed?
14:51rhickeydrewr: are you holding on to the head?
14:52rhickeyyeah, count will run it out
14:52drewrOK, let me get rid of that.
14:52drewrI've got a ref that I update with the count so I don't even need that.
15:03drewrWhat's the right way to kick something off asynchronously that itself uses agents to do other asynchronous things?
15:04drewrClojure doesn't seem to allow nested send-offs.
15:05rhickeydrewr: it does support nested actions
15:06rhickeythey don't fire until the sender's action completes
15:07rhickeyso lexically nested, but temporally chained
15:11drewrIs there any way that I could mess that up lexically so that they don't get chained temporally?
15:12rhickeynope, but if you send then block, those sends aren't going anywhere
15:12drewrOK.
15:17rhickeythere's always (.run (Thread. f))
15:18rhickeyI guess I could add a release-pending-actions, waiting until action complete is usually a feature
15:22drewrRemoving (count ...) kept my JVM from crashing, but now something is just blocking.
15:22drewrUgh.
15:35Chouseroh, cool. You can look at queued agents: (.getQueue Agent/pooledExecutor)
15:35Chouserwell, queued actions.
15:36abrooksAh, nifty. I've wanted to do that.
15:36Chouserbut that's only for send, not send-off
15:36ChouserI wonder why pooledExecutor is public but soloExecutor is not.
15:38rhickeyChouser: probably only public so I could debug something
15:38Chouserand the action has its agent, but that's also private.
15:38Chouserah. seems like runtime viewing of that stuff could be generally useful.
15:39Chouserwouldn't want people calling .shutdown I suppose.
15:39rhickeyI don't want people marrying implementation details
15:39ChouserI only want to flirt with them.
15:39rhickeyI've swapped out the pools and queues a few times
15:41Chouserare you at all sympathetic to a higher-level view-only feature? a way to get a sense of how backed up the agent queue is, for example.
15:42rhickeyChouser: yes, definitely, both agents and refs need more introspective capabilities
15:46kotarakIn how far, is it voodoo to access a private function from a macro via ns-resolve? Say foo.bar/macro uses foo.bar/private. Do I have to make private public? %)
15:47Chouserkotarak: excellent question. I've wondered that myself.
15:48kotarakOne can use ns-resolve. But that feels hacky like hell...
15:48ChouserSo far I've always just made such functions public, documented them, and assumed nobody would ever use the directly.
15:48kotarakAlso my way up to now.
15:49kotarak(ns foo) (defn- foo [] :Private) (in-ns 'use) ((ns-resolve 'foo 'foo)) => :Private, that works, but well, ... not really...
15:59rhickeyAOT shaping up, in 1094:
15:59rhickeyAOT compiler support
15:59rhickeybreaking change to load - no longer takes extension
15:59rhickeyload will load from classfile if newer than source
15:59rhickeyto compile, source dir and compile dir must be in classpath
15:59rhickey(compile 'my.cool.ns)
15:59rhickeywill compile my/cool/ns.clj and anything it loads directly or indirectly
16:00rhickeyrequire/use system should use classfiles if present and newer
16:00rhickeyjust move your files up a dir
16:00Chousersweet
16:01kotarak*thumbs up*, that saves my lots of directories containing a single file...
16:01rhickeyjust need to sync clojure.contrib and shake out anything we find
16:01duck1123_rhickey: when it's all done, will you be posting anything describing what needs to be changed if you haven't updated since before the AOT work?
16:01rhickeyone thing I was able to preserve was a ns defined by multiple files - clojure.core is
16:02duck1123_that's a very nice fix, much more Java-like
16:02rhickeyduck1123_: if you're using contrib you should let those guys shake that out first
16:02rhickeyother than moving your files up a dir, and dropping the extension on any manual load calls, AOT shouldn't change anything
16:03rhickeythe binding form changes are bigger from a source-level perspective
16:03duck1123_do you /have/ to move them up a level?
16:03rhickeyyup, namespaces now correspond to classes, not packages
16:04Chouserhm I just created a namespace dir last night and was happy to be able to put a README and support files in there.
16:04Chouserdumb, since I knew this was coming.
16:05kotarakChouser: you still can, no? Then you have foo/bar.clj and foo/bar/README.txt foo/bar/support.clj...
16:05rhickeyChouser: those related resources are the only thing that doesn't work well here, was an argument against this arrangement initially
16:05Chouseryeah, I suppose. don't know if anyone will think to look in the subdir for a readme.
16:06duck1123this will mean less typing when C-x C-f ing from file to file
16:06kotarakHmm.... How many projects, does a jar contain? Maybe /README.txt at the root is sufficient?
16:06cemerickrhickey: this will be huge. Many thanks.
16:07rhickeycemerick: genclass subsumption still to go
16:08rhickeyone thing to note is that this compile is a 'same-world' compiler, a side effect of compiling is loading, this to make macros and the fns they use avaiable
16:10rhickey*compile-files* will be true when compiling and can be used like this: (def a (when-not *compile-files* (my-big-init)))
16:10cemerickoh, that'll be very nice, as well
16:10rhickeyfor stuff you only want at runtime, or just put that work in function bodies
16:11rhickeyso no eval-when yet
16:13rhickeyback later...
17:14rhickeyeveryone ported to 1094?
17:14rhickey:)
17:14duck1123was it all for nothing? :)
17:14tomhickey=)
17:15kotarakHmm.. The hg mirror is still at 1091.
17:17duck1123github is up to date
17:22AWizzArdis 1094 the new 'stable' version?
17:22rhickeyAWizzArd: nothing has been unstable, but recent version have had breaking changes
17:23AWizzArdseems that AOT made a lot of progress so far *thumbs up*
17:24rhickeylooking for testers/feedback/bug reports
17:25AWizzArdsure, I'm in
17:25kotarakwill try also
17:35Chouseruser=> (find-ns 'clojure.xml)
17:35Chouser#<Namespace #<Namespace: clojure.xml>>
17:36Chouserclojure.contrib mmap and gen-interface are on 1094, seem to be working fine.
17:36rhickeyChouser: I saw that the other day, still chewing on default print currently #<(class x) (str x)>
17:37Chouserah, ok.
17:37rhickeyNamespace's toString does too much
17:38rhickeyfixed
17:38rhickeyuser=> (find-ns 'clojure.core)
17:38rhickey#<Namespace clojure.core>
17:39rhickeyChouser: thanks for the report on mmap and gen-interface
17:42Chouser.class files aren't generated unless asked for?
17:42rhickeyright, you have to (compile 'clojure.contrib.xxx)
17:43Chousermain() methods will come later?
17:43rhickeymain goes with the genclass fold-in
17:44rhickeyan easy option is to map main to main
17:45Chouser(compile ...) creates a classes dir in the CWD, not necessarily the one in your classpath.
17:47rhickeyclasses is just a default, you can set *compile-path* to whatever you want
17:47rhickeyis bound in repl, you can set! or use binding
17:47Chouserwild. So I just compiled a namespace, then imported it and used Java reflection on it.
17:48rhickeycool!
17:48rhickeyI want to get genclass folded in so it's just as easy
17:48rhickeyalso AOT proxy
17:49rhickeybasically want to be able to deliver Clojure apps w/o any need for custom classloader
17:49SimonAdameitHi, I have some problems with setting up clojure/slime. See http://paste.lisp.org/display/70249 for output. Any Idea whats going wrong?
17:50ChouserI have no idea what this is. a whole lot of const__xx that appear to vars and symbols. oh, return values from the top-level forms in my namespace .clj?
17:50Chouserrhickey: yeah, that's a truly worth goal.
17:53ChouserSimonAdameit: sorry, I don't use emacs, but many others here do. I'm sure someone will be along to help you.
17:54Chouserrhickey: hm, but if I (compile foo) without the right classes dir in my classpath, it looks like Clojure is unhappy about being able to find the class.
17:56SimonAdameitrhickey: My congrats to you, Clojure looks alot like the lisp in my daydreams :) .. I mean realy great.
17:57rhickeySimonAdameit: great - thanks!
17:57rhickeyChouser: right, you can put your classes wherever you want, and that dir has to be a)in your classpath, and b) set as *compiler-path*
17:59rhickeyChouser: the const__xxs are any vars or literals from compilation, they turn into static members
17:59Chouserzip-filter and zip-filter.xml required no changes other than file renames.
17:59rhickeyChouser: great!
18:00rhickeyare you compiling everything as you move it?
18:00Chouserscgilardi is hard at it, too.
18:00Chouserno
18:00Chousershould I?
18:00rhickeyChouser: if you can, that way we know that everything works the same when compiled
18:01Chouserand then test the compiled version.
18:01Chouseryeah, ok
18:01Chousergotta go. bbl.
18:03rhickeyme too
18:04SimonAdameitYay! - going back to revision 1088 solved the problem. as recommended in the group
18:46rhickeyhmm... why didn't my VM complain about a class called core-print?
20:05gnuvince_Is there a prettier way to do something like: (loop [coll coll, n n] ...)?
20:05gnuvince_(instead of inventing a bunch of names
21:41_Jordan_SLIME won't connect, just polls indefinitely even after the Clojure REPL prompt shows up... anyone seen this before?
21:48yangsx_Jordan_: you're using an interim subversion checkout, it seems
21:49_Jordan_yangsx: bummer... do I just wait then?
22:28drewr_Jordan_: No, just back up a few revs.
22:31_Jordan_drewr: thanks!
22:59yangsx_Jordan_: Now that rhickey completed AOT, you can fetch the latest. I actually can run it now, but a few changes to .emacs is necessary.
23:00_Jordan_yangsx: Thanks--I ended up just backing up a few revs as suggested, which I think will be sufficient for me to start having fun learning :)
23:01yangsxfor a quick trial, in your *inferior-lisp* buffer: (add-classpath "path-to-clojure-classes") (add-classpath "path-to-clojure/src/clj") and M-x slime-connect, it works for me
23:06_Jordan_This is neat! Now I just need to get it into my fingers to not spell it with an 's', and I'm golden :D
23:43larrytheliquidis there a let-like function that accepts a list of symbol/value pairs? ie: bindings-list => '(one 1); (let-like-function bindings-list one) => 1