2008-06-08
| 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 | slava | 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 | WardCunningham | 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 | slava | 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 | slava | 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 | slava | 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 | slava | 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 | slava | 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 | rhickey | amap and areduce are functional |
| 15:37 | rhickey | 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 | rhickey | all fns take/return Objects |
| 15:38 | slava | i'm suggesting something more along the lines of inference, not declaration. |
| 15:38 | slava | 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 | rhickey | and they might do the boxing elimination for me at some point too |
| 15:40 | slava | might :) |
| 15:41 | slava | i think in general, boxing elimination is hard on the jvm unless you have specific knowledge |
| 15:41 | slava | 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 | slava | 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 | rhickey | 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 | slava | because in CL, you cannot assume they have side effets; they're purely for optimization |
| 15:48 | slava | and in general, why did you decide to keep cons cells around? is it because they map trivially to the seq protocol? |
| 15:48 | slava | 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 | rhickey | lists reserved mode for code |
| 15:49 | rhickey | 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 | slava | 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 | rhickey | 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 | slava | appending two persistent vectors, though |
| 15:53 | rhickey | not supported directly |
| 15:53 | rhickey | 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 | slava | 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 | slava | 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 | slava | unless RT.seq(r) converts the vector to a cons list |
| 16:12 | rhickey | You can't do that and preserve persistency |
| 16:12 | rhickey | 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 | slava | not sure if that's a problem with the way this code is used |
| 16:13 | slava | 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 | rhickey | There are dual-list based queues with amortized persistency |
| 16:16 | rhickey | 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 | rhickey | 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 | Lau_of_DK | 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 | rsynnott | ah, cool, may give that a go |
| 16:54 | rsynnott | 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 | Lau_of_DK | 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 | Lau_of_DK | You can also check this out, just to see an easy little simulation with a GUI. http://ubuntuforums.org/showpost.php?p=5123892&postcount=16 |
| 16:57 | Lau_of_DK | Rich did something similar, his is better, but also a little bit more complicated |
| 17:25 | Lau_of_DK | 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 ? |