#clojure logs

2008-08-27

07:19achim_phi!
07:20achim_pis there a way of concatenating vectors which is more efficient than (vec (concat v1 v2)) ?
07:29achim_p(vec (concat vec1 vec2)) takes linear time, as i understand, because concat only uses the sequential views of the vectors, right?
07:29achim_pi thought there might be a faster way, depending on the implementation of the vector type ...
08:33rhickeyachim_p: yes, sequential, there's no deque or virtual vectors yet
09:30achim_prhickey: okay, thanks!
09:31achim_pwhat are clojure vectors based on? are they bagwell vlists? i believe you mentioned it in one of the videos, but i can't find it now
09:31rhickeyachim_p: they are not vlists, but bitmapped hash tries like the maps, the difference being the keys are implied and the range is full
09:38ChouserI wouldn't think it'd be too hard to use proxy to whip up a virtually concatonated pair of vectors
09:42achim_prhickey: i'll have to dig deeper into this, i'm new to this functional stuff ;)
09:42achim_pthanks again - also for clojure, it's really exciting!
09:42rhickeyyou're welcome!
09:44blackdogrhickey, did you see this from jrose@sun on the jvm list? Folks, invokedynamic, continuations and tailcalls are brewing (in
09:44blackdogthree different locations) and interface injection will (I hope)
09:44blackdogbecome real after method handles go mainstream.
09:45blackdogtail calls? is that the tail call optimiation stuff?
09:46rhickeyblackdog: yes, that will be the real tailcalls. I'll be speaking at the JVM Languages Summit and hope to get the scoop on where things are at.
09:47blackdogyea, glad to see you going and getting the recognition
09:47blackdogjava luminary i think they say :)
09:47ChouserIt's pretty amazing how little tailcalls are needed in Clojure. I guess it'll be nice for mutual recursion.
09:48rhickeyChouser: well, I designed based on what was possible
09:49Chousersure, but even if there were real tailcalls, I would still prefer loop/recur when it would work -- I think it's actually clearer on a couple levels.
09:49rhickeyeven with all the talk now, so far that work is relegated to the playground JVM, and who knows when it will be in a JDK, and then how long before companies are willing to move to that JDK
09:51drewrWhat would be the advantage of real TCO over the tricks loop/recur does now? What it incur less overhead because you're having to mimic the behavior?
09:52rhickeydrewr: real TCO lets you call another (non-self) function without growing the stack, loop/recur is limited to internal calls
09:54drewrAh, I guess I've only ever needed internal calls.
09:55achim_pChouser: like a list/vector of vectors? that wouldn't be much better than a sequence. you'd have to visit each subvector and determine its count to figure out which element of which subvector a given (global) index maps to
09:56rhickeyyou need TCO when you are trying to create a concrete result using recursion, and at each step you will conditionally call a different function to process the rest. There are some elegant algorithms that require TCO.
09:58Chouserachim_p: Well it's probably not a good general solution, but if you had a particular case with a small number of very large vectors, you might be able to write something that performs better than just appending them all into a single vector.
10:00Chouserso is there any interest or desire to use something like setf in Clojure?
10:00Chouser(def m {:a1 {:b1 [:c1 :c2 {:d3 5}]}})
10:00Chouser(setf ((nth ((m :a1) :b1) 2) :d3) 9) => {:a1 {:b1 [:c1 :c2 {:d3 9}]}}
10:02rhickeyChouser: setf is based upon there being a 'place' that is changed, there's no place there as it is functional, so setf is not the model. We've talked about <- (analogous to ->) here before
10:02Chouserhm.
10:03rhickeyand yes, I'm waiting for <-, but no one has gotten desperate enough. I;'m surprised, as once you get nested it gets pretty arduous)
10:04rhickey(<- m :a1 :b1 2 :d3 9)
10:04Chouserhttp://clojure-log.n01se.net/date/2008-07-15.html#09:22
10:05ChouserParth Malwankar has posted related ideas to the forum recently.
10:11achim_pChouser: i'm looking for a data structure that suppports a fairly efficient (sub-linear) "drop-nth". my initial idea was concatenating two subvecs, but this is really slow on large vectors. a vector-of-vectors kind of thing will fragment very fast in my case, because i'll be dropping lots of nths ;) (all of them, eventually)
10:11rhickey(assoc-> m :a1 :b1 2 :d3 9) ?
10:11ChouserCurrently: (-> m :a1 :b1 (nth 2) :d3) => 5
10:11cemerickit'd be nice to be able to invoke Callables as fns...
10:12ChouserSo perhaps: (<- m :a1 :b1 (nth 2) :d3 9) ?
10:12rhickeycemerick: that would add a conditional to all invocations where there is none now
10:13cemerickyeah, I know it's unworkable -- just musing away
10:13Chouserachim_p: ah, I see. What about a sorted-map with integer keys?
10:15Chouser(<- m :a1 :b1 (nth 2) :d3 (do 9))
10:15rhickeyachim_p: you want drop nth and the result to still have fast indexed lookup?
10:17achim_pyeah, not sure whether that's possible at all ...
10:17rhickeyChouser: that's why I renamed to assoc->, the macro needs to know if can rebuild with assoc, so arbitrary accessors can't be supported (without getting into defsetf and places)
10:17rhickeyachim_p: not as far as I know
10:18Chouserrhickey: ok, so it could assume "get" on the way in and "assoc" on the way out.
10:19rhickeyChouser: maybe best not to get stuck on -> analogy, but idea is to just take keys followed by val and do nested assoc
10:19rhickeyright
10:19Chouserwhat of the final item -- a value or a function?
10:20ChouserIt looks like Parth's pretty close to this already.
10:22rhickeyin the original discussion there was the possibility of the last expression being either a value or a parenthesized function-expression of the (presumed existing) value, missing first arg, like: (+ 5) or (assoc k v)
10:24rhickeyor could have separate alter-> assoc->
11:01parth_m_rhickey: Just as Chousers mail on updating nested structures on the group.
11:01parth_m_I was wondering if you had a chance to see the field-write function here http://groups.google.com/group/clojure/msg/c312ba23efcf4c17
11:02parth_m_I needed it quite badly as I have started using 3-4 levels of nesting for a program I am writing.
11:03parth_m_The improved field-read posted by Graham Fawcett also seemed nice to me.
11:05Chouserparth_m_: I didn't understand your explanation for why field-write can't be a macro.
11:05Chouseroh, nm, I got it now. :-)
11:05rhickeythere's no need for field-read: (-> nx :a :b :c)
11:06Chouseryou want to be able to pass in a computed access-spec.
11:08Chouseroh cool -- with -> you can even provide default values: (-> nx :a (:b {}) :c)
11:08parth_m__sorry I got dropped off
11:08rhickey-> rocks
11:09Chouseralthough if you have vectors mixed in you need to name "nth" explicitly.
11:10parth_m__I would be happy to see field-write (or something like it) in clojure or contrib.
11:11parth_m__The use case I had for field-read was that as structures become nested, I don't really hand code the access-specification.
11:12Chouserdid you see you can use the -> macro?
11:12parth_m__I have a separate function get-access-path that takes a keyword and returns a vector that is the access-spec.
11:13parth_m__I am sorry, my client died and lost the messages.
11:13Chouser11:05 < rhickey> there's no need for field-read: (-> nx :a :b :c)
11:14parth_m__Is there a way to pass a "apply" a vector to ->? Maybe there is but I couldn't figure it out.
11:15ChouserI think you'd have to use (eval), which isn't too happy.
11:15parth_m__Oh.
11:16rhickeyparth_m_: (reduce get nx [:a :b :c])
11:17parth_m__Oh. Thats nice ... thanks :)
11:22Chouser"reduce get" works on vectors, but you lose the default-value feature of ->
11:24parth_m__I am not really thinking of (reduce get ..) as a replacing ->. Just a complement for field-write which has a similar use and feel.
11:25Chouseroh, of course. -> is much more general than (reduce get ...)
11:26ChouserIt just seems like it'd be nice to have a symmetrical get and set, but for that to work you need a comprehensive get.
11:27Chouserif the different ways to do nested get have different feature sets, it's harder to have a symmetrical set to go with them.
11:28rhickeyChouser: CL's places are the general solution, but for Clojure without the in-place aspect
11:28parth_m__Chouser: Are you thinking of something like nested sets etc?
11:30parth_m__Specifically for field-write/read struct, accepting vectors is an important use case in my view as access-path [:a :b :c] etc. may be generated at runtime based on the final key. At least thats how I am using it.
11:31parth_m__It allows me to build layers on top of the field-write ... e.g. (def reg-write [core reg value ] (field-write core :content value (reg-path reg)))
11:42Chouserbeing a function (instead of a macro) would be helpful for integrating with commute and alter as well.
11:44mac__Hello, can someone help me out with gen-and-load-class? I'm trying to generate a class in order to specify a finalizer (yes I know that's considered bad java but humor me) but I can't get it right. This is what I got: (in-ns 'test)
11:44mac__(clojure/refer 'clojure)
11:44mac__(gen-and-load-class 'test.Hello)
11:44mac__(defn Hello-finalize []
11:44mac__ (println "oh no!"))
11:44mac__And it works if I make up some own method and put it in with a :method parameter to gen-class but this does not seem to work. Is it because finalize is protected or something?
11:44mac__oops, sorry for the linebreaks, just pasted in some stuff :)
11:45Chousergen-class doesn't generate finalize methods
11:45mac__I see, so I would have to do that in java then?
11:46ChouserIt used to (for all classes), but it made all gen-class classes much slower at runtime, so that feature was backed out.
11:46mac__Well that's sound I guess since .. .yeah ^^ the gc would go crazy
11:46mac__Could be an optional thing though
11:47ChouserI guess for now you would have to use Java, though I don't think it'd be too hard to give gen-class -- right, an option to generate finalize.
11:47mac__like :finalize or something in the arguments
11:47Chouserright
11:47mac__ok thanks
11:48Chouserrhickey: what do you think, would you accept a ":gen-finalize true" patch for gen-class?
11:50rhickeyChouser: can you get one by using :methods currently?
11:50mac__I tried but just got exceptions.. don't know if I got the syntax right though
11:50ChouserHm, I may have jumped to a conclusion there. Hang on.
11:50rhickeyif not, yes, patch ok
11:51mac__Would it look like this? :methods [['finalize []]]
11:51mac__Cause that won't work for me :)
11:53Chousermac__: try: (gen-and-load-class 'foo.Hello :methods [['finalize [] Void/TYPE]])
11:54mac__ah Void/TYPE, cool didn't know about that. Trying...
11:56ChouserI seem to be able to define the class and instantiate a bunch, but I'm not sure if finalize is getting called or not.
11:56ChouserI don't really know Java well enough to be sure.
11:56cemerickfinalize is never guaranteed to be called
11:57mac__Yeah it's hard to verify if that worked :) but at least there is a finalize method on that class now.
11:57Chouseryou'd think after making 10000 foo.Hellos, that some would go away...
11:58mac__Yeah if you don't hang on to them
11:58mac__Try doing (System/gc), not guaranteed to do anything but it may help
11:58cemerickmy understanding is that, even if a foo.Hello is gc'd, the finalize method isn't guaranteed to be called
11:58mac__I got nothing when I did it
11:59ChouserI'm also not sure of the context finalize would be called in -- will it still have access to stdout?
11:59cemerickas long as the jvm isn't in the process of exiting, then yes
11:59mac__Yeah you can do anything from a finalize pretty much.
12:01ChouserThe finalize method generated this way is "public" -- does that signature differ enough from the "protected" one provided by Object that it won't be called by the gc?
12:01mac__And they are not guaranteed to be called before exit of the jvm but in a lenghty process they should get called before the gc reclaims the objects memory.
12:02mac__Chouser: I don't know but it doesn't seem to work anyway. I did a java test earlier today and got printouts from finalize when doing a System.gc
12:02mac__So I smell a difference
12:02Chouserhm
12:03parth_mrhickey: Do you see value in field-write (and possibly its complement field-read - for usability) being added to clojure? or contrib?
12:05rhickeyparth_m: yes, but the interface matters a lot to me, field and write are bad names
12:06parth_mAgreed. This was just something I started doing because I needed it.
12:06parth_mAny suggestion? On names. Possibly any implementation improvements?
12:13Chousermac__: I'm not sure what's going on. A quick hack to generate protected finalize methods still doesn't generate any output.
12:16Chouseroh, got it.
12:16mac__Solved it :) Did you put any argument in your clojure finalize method? I didn't at first and it will get sent the java object... so it worked for me now that I added an argument to it
12:16Chouserright :-)
12:16Chouser(defn Hello-finalize [this] (println "finalize"))
12:16mac__yep
12:17Chouserwithout the arg it was throwing an exception which is of course ignored in finalize.
12:17mac__Exactly. So in conclusion, it works with :methods if you just do it right ;)
12:17Chouser:-)
12:20mac__Well thanks for the help anyway, might have just given up and done it in java if I didn't have someone to discuss it with.
12:22Chousernever give up and do it in java. ;-)
12:24mac__That's a good quote
12:25hoeckrhickey: hi, i made the multimethod version of print, dispatching on class
12:26hoecksorry, i mean hi all :)
12:30parth_mHello :)
12:35rhickeyhoeck: cool - have you sent in a CA?
12:38hoeckrhickey: yes, about 2 weeks ago
12:38rhickeyhoeck: ok - I've been on vacation and haven't checked the box since returning
12:40hoeckrhickey: ah, should i email you the file or add it to clojure-contrib or the like?
12:41rhickeyyou can put it as an attachment in a message to the group
12:43hoeckrhickey: okay
12:45lisppaste8parth_m_ pasted "field-read/field-write" at http://paste.lisp.org/display/65959
12:46parth_mrhickey: any suggestions on the names ... I am quite bad with names. I have pasted the latest version.
13:08parth_mrhickey: Got to go. Please mail any suggestions you might have on the group and I can roll them in. Good day!
13:29mac__I need help with gen-class again.. How do I define a constructor that has a different signature from the superclass (Object in my case). Is this not correct if I want a constructor that takes an Object as it's argument? :constructors {[Object] []} I'm getting this exception when trying to instantiate it: java.lang.UnsupportedOperationException: nth not supported on this type: PersistentHashMap
13:32mac__hmm might be something else
13:37mac__yep, I made a mistake with the return value from init.
14:00notyouravgjoeljava -cp jline-0.9.91.jar:clojure.jar jline.ConsoleRunner clojure.lang.Repl << will this still work with the newest clojure?
14:01ChouserI haven't used jline, but I can't think of any recent changes that would break that if it used to work.
14:02notyouravgjoelk; getting started has it listed, but it isnt working
14:04Chouserhm. you're getting errors?
14:05notyouravgjoel'Exception in thread "main" java.lang.NoClassDefFoundError: jline/ConsoleRunner
14:05notyouravgjoeljava.lang.NoClassDefFoundError: jline/ConsoleRunner
14:06ChouserDoes it work without the jline stuff?
14:07notyouravgjoelyep
14:08notyouravgjoelah, just figured it out
14:08notyouravgjoelsorry, was rather stupid on my part
14:11Chousernp.
14:23rhickeylisppaste8: url
14:23lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
14:24lisppaste8rhickey pasted "Multi-key get/assoc" at http://paste.lisp.org/display/65964
14:25cemerickrhickey: ooh, that looks nice
14:27rhickeycemerick: the other option is to force the 'multi-key' into a vector
14:28cemerickit seems quite pleasant the way it is
14:29rhickeyI agree, Parth's not here to explain his use-case, but this method is much more efficient than his whatever the interface
14:31ChouserI wonder if it would be useful to be able to provide defaults to allow building out the initial structure.
14:31ChouserParth may be content with (apply mk-assoc nx v)
14:35lisppaste8rhickey annotated #65964 with "mk-assoc that builds" at http://paste.lisp.org/display/65964#1
14:39Chouserthat's fine for maps
14:39Chouserfoo=> (mk-assoc {:a [:b0 :b1 {:c 9}]} :a 2 :c 7)
14:39Chouser{:a [:b0 :b1 {:c 7}]}
14:39Chouserfoo=> (mk-assoc {} :a 2 :c 7)
14:39Chouser{:a {2 {:c 7}}}
14:41rhickeyChouser: what do you want the second one to do?
14:42ChouserI'd have to specify that I want to build a vector at that level instead of a map
14:42ChouserI haven't thought of a good API
14:42Chouser(mk-assoc {} :a '(2 []) :c 7)
14:42Chouserick
14:42rhickeyI don't think it's a real problem
14:42Chouserok