14:50 Lau_of_DK: Any functional-p guru here, who can tell me if there's some neat way to do a prime factorization of x ?
15:26 slava: Lau_of_DK: asymtotically, all algorithms are exponential-time
15:26 hi WardCunningham
15:27 WardCunningham: hello slava
15:27 slava: if you're _that_ WardCunningham, I spent much time browsing through the c2 wiki back in the day. it was quite educational when I was getting into the whole "languages other than Java" thing. :)
15:28 WardCunningham: Yes, that is my site. Thanks for the kind words.
15:29 Are you a clojure geek now? Or just looking around like me?
15:29 slava: i think clojure is really neat. i don't see myself using it for projects any time soon, but it has a lot of good ideas and I like to learn new languages
15:30 WardCunningham: agree.
15:30 slava: in particular, its approach to immutability and concurrency strikes me as the Right Thing.
15:31 you can still have mutable state, but the library gives you top-notch persistent collections.
15:31 WardCunningham: and stm.
15:31 slava: and as far as concurrency goes, you get STM and message passing.
15:32 yup.
15:32 Lau_of_DK: slava, Cloure is the right thing, resistance is futile
15:33 slava: as far as collections go, persistent collections probably work fine in most cases. I think you still need mutable specialized arrays for numerics
15:34 hmm. if the only mutable arrays are those specialized to hold a single numeric type, you avoid co-variance/contra-variance issues in the type system.
15:34 rhickey: Lau_of_DK: please no fighting or taunting here
15:34 Lau_of_DK: rhickey, dont worry, Im a man of peace
15:34 rhickey: Clojure has typed access to Java arrays of primitives
15:34 slava: does all the seq stuff work there?
15:35 rhickey: yup, but with boxing overhead
15:35 slava: how far are you going to go with compiler optimizations?
15:35 WardCunningham: slava: nice to meet you. I'm going back to just lurking ... saving my wrists for work.
15:35 rhickey: there's also higher-level but super-efficient whole-array transforming macros like amap and areduce
15:35 slava: if you implement some analysis you can avoid creating the iterator if its entirely consumed without being returned or used for its object identity
15:36 rhickey: right; i'm suggesting that you can implemenet map, reduce etc gnerally using seqs and optimize the case where the seq is iterating over a known type
15:36 depends on how much effort you want to put into the compiler, of course
15:36 rhickey: I might do that at some point, but there are lots of issues, as the 'mapped' function must be typed as well
15:37 amap and areduce are functional
15:37 i.e. return new arrays
15:37 slava: i don't think the mapped function must be typed; it doesn't see the iterator directly, does it?
15:37 rhickey: I'd like to avoid devolving into Java-like typing
15:38 all fns take/return Objects
15:38 slava: i'm suggesting something more along the lines of inference, not declaration.
15:38 if the fn is small, you can inline it and avoid the boxing at the procedure call boundary
15:39 rhickey: I understand, a lot of work
15:39 slava: yup :)
15:39 rhickey: Right now I'm getting terrific optimizations for free from HotSpot
15:39 slava: less work than writing a native compiler, though. once you get past the high-level optimizations, you get the rest from hotspot.
15:40 rhickey: right
15:40 and they might do the boxing elimination for me at some point too
15:40 slava: might :)
15:41 i think in general, boxing elimination is hard on the jvm unless you have specific knowledge
15:41 there are too many ways to 'observe' the identity of an object
15:41 rhickey: I've added enough so that people who have to do number crunching don't have to leave Clojure. Other optimizations are premature for me right now.
15:42 slava: are you using/going to use clojure for commercial projects?
15:43 rhickey: starting to
15:43 slava: nice
15:44 clojure seems really well designed. have you spent a lot of time working with scheme and cl in the past?
15:44 rhickey: CL
15:46 In many ways Clojure is a challenge to Lisps to change
15:47 slava: yeah, CL is pretty stagnant. I worry that in 10 years, it will be mostly forgotten, which is a real shame because it has features you don't see in many languages (multiple dispatch, MOP, setf, procedural macros)
15:47 rhickey: it is a treasure-trove of ideas
15:47 slava: seeing your efficient persistent collections made me realize that the destructive list operations are mostly obsolete
15:48 because in CL, you cannot assume they have side effets; they're purely for optimization
15:48 and in general, why did you decide to keep cons cells around? is it because they map trivially to the seq protocol?
15:48 it seems that in most cases persistent vectors can replace them
15:49 rhickey: consing at the front is useful, but yes, in practice vectors get a lot more use, at least in idiomatic Clojure code
15:49 lists reserved mode for code
15:49 more
15:50 slava: is it possible to make persistent vectors efficient for consing on the front? it seems like you could add a 'head' slot that works like 'tail', but i'm not sure if the tree rebalancing gets hairy
15:50 i haven't thought about this before
15:50 rhickey: you could use the vectors backwards as lists
15:50 slava: ah, true
15:51 rhickey: both support a 'stack' protocol where you ignore the order
15:52 using vectors for data and lists for code gives a nice separation vs Lisps where you use lists for both
15:52 slava: oh, i didn't find this in the code: how is append implemented on persistent vectors?
15:52 rhickey: conj adds to end of a vector
15:52 slava: i've found that having separate sequence types for code and data is nice too. it can catch mistakes and makes code easier to understand -- you know what the resulting sequence will be used for
15:52 appending two persistent vectors, though
15:53 rhickey: not supported directly
15:53 basically O(n) add one to the other
15:53 slava: i wonder if there's a way to do that more efficiently knowing the structure of persistent vectors
15:54 it would still be o(n), just a constant speedup
15:54 rhickey: if the first was a multiple of 32 in size, easy
15:55 slava: yup
15:58 i just realized that one can implement a persistent-vector with double ended consing as a pair of persistent vectors :)
15:59 rhickey: There's a PersistentQueue in the Clojure lib, not yet exposed in the API
16:03 slava: i see a potential problem there in that popped entries won't be GC'd until the entire queue is empty
16:04 unless RT.seq(r) converts the vector to a cons list
16:12 rhickey: You can't do that and preserve persistency
16:12 retention of the vector depends on push/pop patterns
16:13 slava: that's what i meant; if you don't hold on to the old version of the queue, the values might not be GC'd anyway
16:13 not sure if that's a problem with the way this code is used
16:13 if you expose it to the user it will be something to address though
16:15 rhickey: if someone allows n items to be pushed before consuming any, nothing implies they ought to be GC'ed prior to n pops
16:15 There are dual-list based queues with amortized persistency
16:16 My queue is not amortized since seq of the vector is O(1)
16:17 slava: yup
16:17 rhickey: variant on Okasaki's
16:17 enabled by persistent vectors
16:23 Lau_of_DK: Ive never used VIM but I noticed that there's a clojure plugin for it on the wiki. Does it have the features that emacs have like repl interaction, autocomplete, all that stuff?
16:45 Guess VIM doesn't have much of a user-core in here
16:46 rsynnott: is there an emacs repl for clojure?
16:47 Lau_of_DK: yea, you can connect to slime and get a REPL directly in emacs, if thats what you mean
16:53 rsynnott: ah, there's slime for clojure?
16:54 Lau_of_DK: Well, there's a swank-clojure package
16:54 rsynnott: (I havn't really used clojure as yet; I'm more of a CL persn. It looks interesting, though)
16:54 ah, cool, may give that a go
16:54 main thing putting me off was percieved lack of a proper ide
16:54 Lau_of_DK: Yea, want me to find a link for you ?
16:54 Have you ever tried some of the Eulers ?
16:54 rsynnott: got it
16:56 Lau_of_DK: I re-did some of the Eulers in clojure, just to try and get that functional feel, it was fun - and most effective
16:57 You can also check this out, just to see an easy little simulation with a GUI. http://
16:57 Rich did something similar, his is better, but also a little bit more complicated
17:25 rhickey, are there any tools to help setup more complex GUIs, or does it have to be done manually ?
17:26 rhickey: Some people are using Netbeans' Matisse to build a GUI they drive with Clojure
17:28 Lau_of_DK: How do they import it, so as to drive it ?