#clojure logs

2008-07-03

00:13slavaChouser: in the jvm, a 'try' block has zero cost if no exception is thrown
00:13Chouserslava: cool, thanks!
00:14slavai assume clojure compiles to intelligent bytecode for exception handling, then it won't be a performance issue at all
03:27hoeckcgrand: tried cryoPID on a clojured jvm, it somehow suspends and awakes, but it seems to close all file descriptors (at least the cryopid i built on my machine)
03:43cgrandhoeck: wow, I was kidding :-) Btw, I tried it myself yesterday and I ran into 2 pbs, one can easily be fixed (unlinking the file where hotspot stores runtime statistics so as to have cryopid embed this file in the snapshot), and the other one requires more work: cryopid works only on single threaded processes :-(
04:27hoeckcgrand: i was curious about that, it would be nice to suspend the jvm under certain conditions, but as my 'sessions' mostly include swing frames, it wouldn't be of great use for me.
04:36cgrandhoeck: there's other checkpointing solutions: https://lists.linux-foundation.org/pipermail/clusters_sig/attachments/20051025/88ed8b30/Comparison-CR-0001.pdf but restoring a swing app is certainly tricky
04:42hoecki'm wondering that there is no suspend capability built into the jvm, that should be easier than suspending the whole jvm process
04:45hoeckBTW, i've got a laptop with working acpi-suspend-to-ram, so i can at least save one single clojure session :)
04:46cgrand:-)
05:37Ycroshoeck: if you're on linux you could try http://cryopid.berlios.de/
06:15hoeckycros: yeah, cgrand already suggested it, and i tried it too, but it didn't work properly on my machine
10:18cemerickanyone planning to go to oopsla?
10:22Chouser_rhickey_: I'm in awe of drop-last's implementation. And thanks, I need it for lazy-xml.
10:33Chouser_If s is not itself a sequence, (seq s) will create a cache for the results as it walks along, right? Then won't the call to seq inside (drop n s) create its own separate cache?
10:37rhickey_a seq is a cursor, there isn't a lingering cache unless the interim seqs are held, but it will create 2 cursors unless you pass it a seq
10:38rhickey_I can add a (let [s (seq s)] ...
10:39Chouser_right, I was just trying to figure out if that would help anything or not
10:41Chouser_seems like it wouldn't really. You'd mainly want to make sure that if computing (rest s) takes any real work that it doesn't do it again just to track the offset. But if s was built with (lazy-cons) both calls to (seq) will just point to the original, so there wouldn't be a problem.
10:41rhickey_not if it's already a seq, then the drop seq is creating cache that the head will reuse
10:42Chouser_right
10:43Chouser_which leaves things like maps and vectors, where I assume advancing a seq is pretty lightweight.
10:43rhickey_Chouser_: yes, and you don't ever lose the advancing cost
10:44Chouser_and wouldn't be cached anyway ... right, ok.
10:45rhickey_one advantage of 2 cursors is you won't be holding onto n seqs in the interval, _unless_ you were passed a seq in the first place
10:49Chouser_I wrote a lazy-but-last a couple days ago and thought briefly about how much more code it would take to handle n>1; I was nowhere close to your implementation.
10:56rhickey_Chouser_: I constantly have to remind myself to try to use a higher-order fn, because lazy-cons is so easy
10:57Chouser_yeah, mine used destructuring to look ahead and lazy-cons to build the result. I thought I was all clever.
11:01rhickey_Chouser_: cgrand had the right idea earlier this week, just did work map already does: http://clj-me.blogspot.com/2008/07/lazy-butlast.html
11:04rhickey_Chouser_: I saw your case - one of the things Lisp cases do is take multiple test values that match to a single expr
11:07Chouser_I hadn't seen cgrand's blog. He did a lazy-in-another-thread too.
11:10rhickey_Chouser_: yeah, it's a one-ahead IIRC. I didn't see the need to go to Executors/Futures rather than use agents
11:11Chouser_yep, one-ahead. But it's interesting to me that he, I, and abrooks apparently all started thinking about that basic idea within the last week or so.
11:36cemerickrhickey_: Are there any plans to support overloads with the same arity but different signatures? (e.g. (defn foo ([#^String a] a) ([#^Integer a] a))
11:36rhickey_cemerick: no
11:36rhickey_multimethods?
11:37cemerickI'm thinking about that only in connection with proxy / gen-class.
11:37rhickey_proxy routes to a single handler, but gen-class can do that now
11:38cemerickright, right, param-types.
11:40rhickey_then independent handlers foo-String, foo-int
11:40rhickey_hmm... looks like that feature is not documented
12:31rhickey_lisppaste8: ?
12:32Chouser_rhickey_: are you opposed to an :else in case? Seems like it would be handy if the keyform is complex.
12:33rhickey_what if the keyform is :else ?
12:33Chouser_[:else]
12:33Chouser_same if you need to match a vector
12:33rhickey_what if the keyform is [:else] ?
12:34Chouser_[[:else]]
12:34Chouser_[1 2 3] will match 1 or 2 or 3
12:34rhickey_are you always requiring [] ?
12:35Chouser_no, any non-vector gets one vector wrapped around it
12:35Chouser_[[1 2 3] 4] will match [1 2 3] or 4
12:36rhickey_:a becomes [:a] in the expansion?
12:36Chouser_[:a :else 5] matches :a, :else, or 5; [:else] matches just [:else]; :else matches everything
12:37Chouser_[:a] and :a both become (or (= key :a))
12:38rhickey_hmm... maybe lists for grouping?
12:38Chouser_I guess requiring [] wouldn't hurt too bad, but I think not requiring it will be more helpful than confusing. I dunno, maybe I've got that backwards.
12:39Chouser_well, right now I'm evalling the keys so non-constants are allowed, so lists would require quoting.
12:40rhickey_most cases don't allow non-constants
12:40Chouser_between that and the fact that [] are visually different from the likely () used in the result expressions led me to use vectors.
12:41lisppaste8rhickey pasted "seque redux" at http://paste.lisp.org/display/63224
12:43Chouser_ah, sure
12:45rhickey_Chouser_: I'm not sure more configurability than pluggable queue is needed
12:46Chouser_ok
12:50Chouser_I figured out a way to put a finally clause back instead of catching and re-throwing the exception, but it only saves one line of code and puts the try block inside the loop. I didn't know if that was really better or not.
12:51rhickey_exception only has overhead when you have one, in which case efficiency isn't your problem :)
12:53rhickey_Thanks for your input on this. If no one sees any obvious deficiencies, I'll add that seque to Clojure
12:54Chouser_you're welcome, it's been fun.
12:55Chouser_I might yet take one more swing at a configurable fill to allow me my ugly *enqueue* thing. Maybe SAX parsers are the only thing that will ever need it, but I just wouldn't be surprised if some other Java interop could use it.
12:58lisppaste8Chouser annotated #63224 with "finally instead of catch/throw (if it matters)" at http://paste.lisp.org/display/63224#1
13:00Chouser_no, don't use that. If .offer throws something we'll be in bad shape
13:02Lau_of_DKEvening Gents
13:11StartsWithKWhy do examples of gen-and-save-class (http://paste.lisp.org/display/63177 http://is.gd/Ljy) use (clojure/refere 'clojure) but when i do it i get a error saying that defs from clojure are allready in my ns http://pastebin.com/d3d640c0b
13:11StartsWithKi tried, but its just insane to prefix everything with clojure/
13:18Lau_of_DKI think its due to your initial (in-ns) , but its just a hunch
13:18Lau_of_DKdoes that ns refer clojure?
13:18Chouser_StartsWithK: yeah, you can also try using :exclude or :only in your (refer), but that also gets a bit painful.
13:19StartsWithKLau_of_DK, how else will i implement functions that will map to class methods?
13:19Chouser_rhickey outlined a solution but I don't think he's started work on it yet.
13:19Lau_of_DKDoes (com.paulbarry.HelloWorldServlet) refer Clojure ?
13:19StartsWithKChouser, but ill have to exclude every function i use
13:20StartsWithKand not only that, but ill have to do it in every .clj file i have
13:20StartsWithKnot only in that one..
13:22Chouser_well, just in your com.paulbarry.HelloWorldServlet ns, you would say (clojure/refer 'clojure :exclude '(print)) and such
13:22Chouser_you might have several more besides print, but you'd only need to do it in genclass namespaces, not all your other ones.
13:23StartsWithKbut i then use (clojure/refer 'gl) or any other ns i have, and i get the same error for that file..
13:24StartsWithKi wouldn't like to put that :exclude in every file ill use
13:25Chouser_is 'gl a genclass namespace?
13:25StartsWithKno
13:25Chouser_but it defines a print function?
13:26StartsWithKno
13:26StartsWithKbut it starts with (cojure/in-ns 'gl) (clojure/refer 'clojure)
13:27Chouser_and that gives you an error? what name is conflicting between 'gl and 'clojure?
13:28StartsWithKprint
13:29StartsWithKbut i guess thats just first conflict it finds so it stops there
13:30Chouser_ok, I'm still missing something. 'clojure defines print. if you have a conflict on (refer 'clojure) in 'gl, then 'gl must define print, either manually or via genclass
13:30Chouser_maybe you can paste a small standalone example of the failure?
13:36StartsWithKhttp://freehg.org/u/kresimir/neman/file/73d324443f70/ in examples directory is GearsApplet.clj and in neman subdirectory there is a gl.clj, error i get is http://pastebin.com/d3d640c0b
13:39rhickey_gen-class is going to create vars in your ns for _every_ non-private method in all superclasses/interfaces, so if one of your superclasses has print, that's all it takes
13:39rhickey_looks like java.awt.Container has print
13:41StartsWithKso ill have to exclude everything that some superclass implements when refering to clojure namespace?
13:41rhickey_or :only the things you use in the refer call, at least until I change this
14:41cemerickrhickey: any reason why delay is private?
14:43rhickeycemerick: I don't want to promise its continued existence - was an implementation helper at one point
14:46Chouser_hashes seem to return int keys in sorted order.
14:47cemerickit, or something similar is pretty necessary, IMO. A lazy companion is worthwhile, too (thinking here of the plt promise lib).
14:49cemerickI've got a delay-fn macro around here somewhere that expands into a delay that can take arguments, which can be handy.
14:53rhickey_I'm not opposed, I just don't want people reinventing lazy seqs...
14:54rhickey_when I first released Clojure I had to spend a lot of time explaining how and why it was different from Scheme
14:55rhickey_cemerick: isn't delay inherently lazy?
14:56cemerickrhickey_: Ah, no, I mean a function named "lazy" (or something like the scheme function of the same name). i.e. http://docs.plt-scheme.org/reference/Delayed_Evaluation.html
14:57cemerickI never liked the 'force' mechanic -- simply evaluating the thunk provided by delay or lazy always seemed more reasonable to me.
14:57rhickey_That's what delay does, just that it supports IFn, so the way to force it is to call it
14:57cemerickexactly -- much better 'usability', IMO
14:58cemerickI'm surprised you fielded questions about clojure w.r.t. scheme similarities/differences. There's plenty of variation out there, already.
14:59rhickey_(import '(clojure.lang Delay))
14:59rhickey_(def p (Delay. #(println "Hello")))
14:59rhickey_(p)
14:59rhickey_(p)
15:00rhickey_no TCO is the big difference from Scheme
15:00cemerickYeah, I could do that. I'm using my own delay macro until I know clojure.lang.Delay is sticking around. :-)
15:00rhickey_many other superficial differences
15:01rhickey_cemerick: what does you delay macro use?
15:01rhickey_your
15:01cemerickFeh. (almost) pointless academic pissing matches, IMO.
15:11Lau_of_DKrhickey_: Isnt it about time, that you make (time ) produce some nicer output?
15:21Chouser_ah, such fun: (defn perm [r m p] (if (> m 0) (mapcat #(perm (disj r %) (dec m) (conj p %)) r) [p]))
15:22Chouser_(perm #{0 1 2} 3 []) => ([0 1 2] [0 2 1] [1 0 2] [1 2 0] [2 0 1] [2 1 0])
15:23rhickey_neart
15:23rhickey_neat
15:25Chouser_I can generate a million permutations of 10 digits in about 11 seconds.
15:26rhickey_cool
15:27rhickey_where's lazy-perm?
15:27rhickey_:)
15:27Chouser_hmph
15:28Chouser_I'll write it as soon as I can find lazy-mapcat in boot.clj
15:28rhickey_do you need that? won't it be lazy-cat .. map ...
15:29Chouser_hm, dunno, I just spoke without really thinking. hardly ever happens. ;-)
15:29Chouser_that is lazy, isn't it?
15:30Chouser_yeah, it is. I wrote lazy-perm already. leave me alone. I've got a database to resintall...
15:30Chouser_and a C++ app to recompile
15:33lisppaste8Chouser annotated #63135 with "case with vectors and :else" at http://paste.lisp.org/display/63135#1
15:37cemerickrhickey_: my delay macro isn't anything special. It just takes a function body, and then keeps a map in a ref that holds the thunk, and then the "forced" value after the fn that the macro generates is evaled.
15:38rhickey_how does it know it's been forced?
15:38cemerickIt checks the map in the ref for a value in a :result slot.
15:39cemerickI have a "fancier" one that will accept arguments on the "force", but then it's a little weird in that it'll return the same forced value for any arguments provided afterwards. I thought it was such a good idea, until I didn't. ;-)
15:41rhickey_if your thunk has side effects or takes a long time, might be incompatible with the transaction running multiple times
15:42cemerickYeah, it has the same dynamics as memoize (I think).
15:43cemerickI don't double-check the ref's map (like you double-check around the synchronize in clojure.lang.Delay), but it Works For Me (tm).
15:43cemerickI suppose I could add that *shrug*
15:44rhickey_if the delayed expression has side effects you can't use transactions for this
15:46lisppaste8cemerick pasted "delay macro" at http://paste.lisp.org/display/63238
15:46Chouser_shouldn't use anything with side effects in a transaction, right? Actually, I should stop talking, since I've been staring at the implementation of Delay and still don't get it.
15:47cemerickwell, if you're trying to delay something you know has side effects, and you know you want those side effects to apply on every access of that delayed expression, then you're not using delay properly, right?
15:47cemerickby that I mean, all delay mechanisms have this problem, no?
15:48cemericks/problem/"problem"
15:48rhickey_no, delay is run once, cache result
15:48Chouser_oh!
15:48cemerickok
15:49rhickey_cemerick: this stuff is tricky
15:50rhickey_the macro has a few problems independent of the semantics of delay. You are doing several 'flying reads', i.e. outside the transaction, of values that matter to you in the transaction. Those reads should be in the transaction
15:51cemerickrhickey_: Yeah, I know. I just knocked it out last night when I saw that boot.clj's delay wasn't open for business.
15:52cemerickI wanted to check with you on its status/future before bullet-proofing it.
15:52cemerick"it" referring to two different things there, of course...
15:53cemerickrhickey_: are you concerned in general about people wandering into using delay inappropriately, etc?
16:08rhickey_I made it so the resulting object implements both IFn and IRef, so you can 'force/read' it with either (x) or @x
16:09cemerickooooh, shiny :-)
16:10Chouser_like memoizing a function with no args
16:11lisppaste8cemerick annotated #63238 with "fixes to my delay macro, if anyone's interested" at http://paste.lisp.org/display/63238#1
16:13rhickey_cemerick: you would still want to check :fn before calling it
16:19cemerickah, I see that now. 'twas my first usage of transactions. Thanks for the pointer.
16:33Chouser_with seque's fill now leaving the thread instead of blocking, it has diverged even further from what I need to wrap a SAX parser.
16:34rhickey_right, because seque is pull and SAX is push
16:34Chouser_What torments me is I'll still need the LBQ, the agent management, exception propagation, etc. So it'll still look really similar, but different enough to be unusable.
16:35Chouser_but I think I just need to get over myself.
16:35rhickey_I had the seque in 2 parts, as I had described, seq->queue, queue->seq, with the only connecting point being the weak-ref
16:36rhickey_then I got discouraged about the weak ref.
16:36Chouser_heh. yeah. :-/
16:36rhickey_you still have to solve the close problem
16:37rhickey_After ECOOP, I'm going to look hard at Closeable for LazySeq, and also for direct cde-gen for LazySeq, as it has become so important to Clojure
16:37Chouser_cool.
16:38Chouser_that starts week from now?
16:38Chouser_are you ready?
16:38rhickey_I give talks on Monday and Tuesday - working on my slides now
16:38Chouser_huh. I thought you were working on seque and delay. ;-)
17:02jgracinIf I have a Clojure script in the classpath, is there a way to load it from REPL?
17:03Chouser_(.loadResourceScript RT "foo.clj")
17:03Chouser_(.loadResourceScript clojure.lang.RT "foo.clj")
17:04jgracinChouser_: Beautiful! Thanks!
17:04Chouser_np
18:00StartsWithKhi
18:01StartsWithKi now have running gears demo as clojure applet at http://kreso.mooo.com/gears.html
18:01StartsWithKbut, i had to copy all needed file in GearsApplet.clj..
18:03bpattisongeospatial=> (defn f2 [ x y ] (pr "f2=" x y))
18:03bpattison#'geospatial/f2
18:03bpattisongeospatial=> (defn f3 [x & more] (let [s (seq more)] (pr x) (f2 s) ) )
18:03bpattison#'geospatial/f3
18:03bpattisongeospatial=> (f3 1 2 3)
18:03bpattison1java.lang.IllegalArgumentException: Wrong number of args passed to: f2
18:03bpattisonI'm stuck trying to get the right number of arguments to f2 -- any ideas?
18:47rhickey_bpattison: if a function takes args and you want to use the contents of a seq as the args, you need to apply the function. If you just call it, the seq will be passed as a single arg:
18:47rhickey_(defn f3 [x & more] (let [s (seq more)] (pr x) (apply f2 s)))
20:14bpattisonrhickey: thank you -- I was struggling with that for a while
23:40arohnerhello. Is this a good place to ask newbie questions?
23:40arohnerI have
23:40rhickey_sure
23:41arohner(def foo [a b c] (println a b c))
23:41arohneris there a way to pass a seq of length 3 as an argument to foo?
23:42arohnerI believe that's called splatting in ruby
23:42rhickey_(apply foo [1 2 3])
23:42arohnerah, thanks
23:47arohnercan you call apply on a java method?
23:50rhickey_no
23:52arohnerok, thanks
23:53arohnerBTW, thanks for creating clojure. I've been really happy with it
23:56rhickey_you're welcome!