# #clojure log - Mar 12 2009

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:06 Raynes: Mec: Why would you do such a thing to learn Clojure. No body does that shit in real life. :|

0:06 Mec: boredom

0:06 cooldude127: these vimclojure rainbow parentheses are really trippy

0:07 Raynes: Mec: Same reason I did the first problem last night :D

0:07 Mec: Could I see your implementation of Problem 1?

0:09 durka42: you guys should use the wiki

0:11 ~euler

0:11 clojurebot: euler is http://clojure-euler.wikispaces.com/

0:11 cooldude127: interesting

0:12 Raynes: ,(time (rem 3 3))

0:12 clojurebot: 0

0:12 "Elapsed time: 0.121 msecs"

0:12 Raynes: ,(time (mod 3 3))

0:12 clojurebot: 0

0:12 "Elapsed time: 0.152 msecs"

0:12 Raynes: Mec: ^

0:12 In this case, rem wins by a hair.

0:13 Mec: lol

0:13 durka42: that's a thin hair

0:13 Raynes: A very thin hair.

0:13 Mec: ,(time (rem 23523 235))

0:13 clojurebot: 23

0:13 "Elapsed time: 0.115 msecs"

0:13 durka42: it would be hard to split that hair

0:13 cooldude127: less time?

0:13 Mec: ,(time (mod 23523 235))

0:13 clojurebot: 23

0:13 "Elapsed time: 0.158 msecs"

0:13 Raynes: Rem wins!

0:13 Weeee

0:13 Mec: so it is

0:14 i dunno why but when i see rem i dont think remainder

0:14 cooldude127: remove?

0:14 Mec: ya

0:14 Raynes: (doc remove)

0:14 clojurebot: Returns a lazy sequence of the items in coll for which (pred item) returns false. pred must be free of side-effects.; arglists ([pred coll])

0:14 durka42: i mean, you would expect rem to win. mod calls rem and then does some checks

0:14 cooldude127: what kind of checks?

0:14 Mec: so is remove the opposite of filter?

0:14 Raynes: cooldude127: Cooldude checks.

0:14 cooldude127: lol

0:14 Mec: i think so

0:15 durka42: whether it should switch the sign

0:15 ~source omd

0:15 ~source mod

0:15 cooldude127: ,(rem -3 3)

0:15 clojurebot: 0

0:15 cooldude127: ,(rem -3 2)

0:15 clojurebot: -1

0:15 Raynes: ~source remove

0:15 cooldude127: ,(mod -3 2)

0:15 clojurebot: 1

0:15 durka42: ,(mod -3 2)

0:15 cooldude127: oh i see

0:15 clojurebot: 1

0:15 durka42: there's a discussion somewhere

0:15 Raynes: ~source filter

0:16 cooldude127: so basically if you know the sign is gonna be positive or you don't care, you should use rem?

0:16 Raynes: durka42: Stop being smarter than me.

0:16 Filter is defined directly above remove. Should of looked.

0:17 cmvkk: now now, what is the clojurebot even for then?

0:17 after all, you could just open your own copy of core.clj and do a search.

0:17 Raynes: Mec: remove calls filter and complements the predicate to do the opposite of what filter normally does.

0:17 ,(complement true)

0:17 clojurebot: #<core\$complement__3478\$fn__3480 clojure.core\$complement__3478\$fn__3480@189acb5>

0:18 Raynes: O.O

0:18 cmvkk: heh

0:18 cooldude127: cmvkk: don't you know some people here don't even use their own repl? they just use clojurebot

0:18 Mec: ,((complement true))

0:18 clojurebot: java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn

0:18 Mec: meh

0:18 durka42: ,((complement true) (= 42 42))

0:18 Mec: im stuck on this lcm problem :x

0:18 clojurebot: java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn

0:18 durka42: oh, duh

0:18 cooldude127: complement needs a function

0:18 :)

0:18 durka42: ,((complement =) 42 42)

0:18 clojurebot: false

0:18 Raynes: Oh duh.

0:19 replaca: I have a weakness for absurdly complex constructions that show the obvious:

0:19 ,(map count (map #(.getParameterTypes %) (filter #(= (.getName %) "invoke") (.getMethods clojure.lang.IFn))))

0:19 clojurebot: (1 2 3 4 5 6 7 8 9 10 0 12 13 14 15 16 17 18 19 20 21 11)

0:19 cooldude127: haha

0:20 the ordering there is kinda odd

0:20 replaca: interesting, clojurebot gets a different order than my REPL

0:20 my REPL shows 0 to 21 in order

0:20 durka42: mine too

0:20 cmvkk: if you keep going, will it do (... 32 22 ...) ?

0:21 replaca: maybe clojurebot is on a different Java or clojure version

0:21 lisppaste8: Rayne annotated #76793 "fixed towers-of-hanoi to take large input - abuses trampoline" at http://paste.lisp.org/display/76793#2

0:21 replaca: no, that's all there are

0:21 it's all the arities of invoke

0:21 cmvkk: oh

0:21 replaca: or "the 22 names of IFn"

0:21 :) brb

0:21 cmvkk: wait, is that how multiple arities are done? by creating a possibility for every single arity?

0:22 Mec: yup

0:22 cooldude127: replaca: i get the same order as clojurebot

0:22 durka42: Raynes: trampoline AND recur?

0:22 the mind boggles

0:22 cooldude127: cmvkk: up to a point. then it uses a varargs one

0:22 cmvkk: and what's the ceiling on that?

0:22 i want to make a function with a thousand arguments.

0:22 Mec: replaca: what does that do?

0:23 cooldude127: cmvkk: you can

0:23 durka42: Raynes: wait, does that work. i would think the do throws away the #()

0:23 Raynes: durka42: I would of had to redesign the whole thing to use a loop .. recur so I just trampolined the bitch.

0:23 Works great.

0:23 cmvkk: can i make one with a hundred billion arguments?

0:23 Raynes: Tested it with 10000 discs.

0:23 cmvkk: memory permitting

0:23 cooldude127: cmvkk: technically nothing stopping you

0:23 cmvkk: excellent.

0:24 cooldude127: cmvkk: the first twenty are just an optimization

0:24 cmvkk: i don't want it to package the args as a vector behind the scenes either.

0:24 every argument gets its own special place on the stack.

0:24 durka42: Raynes: the #() does nothing

0:25 ,(do 1 2 3)

0:25 clojurebot: 3

0:25 cooldude127: cmvkk: oh, then probably not

0:25 cmvkk: :(

0:26 cooldude127: cmvkk: clojure functions are java objects, so unless you define 100 billion versions of invoke, you're going to resort to an array at some point

0:26 * durka42 looks up a random java varargs method

0:26 durka42: The maximum number of arguments is limited by the maximum dimension of a Java array as defined by the Java Virtual Machine Specification.

0:26 you can always use apply

0:27 Raynes: Oh... I never actually /tested/ to see if the output was correct...

0:27 Fuck.

0:27 cmvkk: time to calculate how much disk space I would need to store a clojure file with a function definition of arity 100-billion.

0:27 durka42: well, i don't know if it's correct

0:27 but it's the same without the closure

0:28 Raynes: I'm not sure how to convert it to a loop and recur, and I really don't feel like thinking about it right now so I'll save this one for later :\

0:30 cooldude127: yay for putting things off!

0:31 Raynes: There should totally be a recur for non-tail recursion.

0:31 cooldude127: Raynes: isn't that what just calling the function is?

0:31 Raynes: cooldude127: Yes, but I needs the optimization. Damn you JVM.

0:32 cooldude127: Raynes: what would be optimized there? if it's not tail?

0:32 Raynes: It still blows the stack. Like I said, I need to rewrite it to use a loop-recur.

0:32 cooldude127: yeah probably

0:33 Raynes: cooldude127: In case you didn't notice I was joking about the recur for non-tail recursion :p

0:33 cooldude127: Raynes: oh my bad lol

0:33 Raynes: And not probably, it's certainly. Unless I'm missing something.

0:33 cooldude127: yeah that's correct. i've been spending too much time in java world

0:34 Raynes: This would be so easy with TCO.

0:34 cooldude127: Raynes: without TCO, you should just be able to replace the tail call with recur and be done

0:37 replaca: ok, back

0:37 * cooldude127 is bored cuz he doesn't have any actual work to do on his code

0:38 replaca: Mec: it shows all the different numbers of arguments that you get with invoke

0:38 but as cooldude127 points out, it does more via varargs

0:38 Mec: right, i saw that in the java file and was wondering why he hard coded so many

0:39 replaca: I think he may compile directly to them for common cases

0:39 so he doesn't have to choose the method at runtime and doesn't have to "box/unbox" into an array

0:40 cooldude127: yeah since function calls are pretty common, it was a good idea to optimize that

0:41 replaca: esp. in a language that encourages composing lots of small funcs & first order operations

0:41 cooldude127: yes

0:50 Mec: is the list for returns lazy?

0:50 replaca: mec: I don't understand

0:51 durka42: (doc for)

0:51 clojurebot: List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost fastest, and nested coll-exprs can refer to bindings created in prior binding-forms. Supported modifiers are: :let [binding-form expr ...], :while test, :when test. (take 100 (for [x (range 1

0:51 durka42: yes

0:51 Mec: ok goodie

0:52 replaca: oh, I completely mis-parsed that sentence :-)

0:52 Mec: ya i couldnt rephrase any better

1:08 cmvkk: why is it that every time i go "it'll be quick and easy to make a framework to do this, it'll take hardly any code at all!"

1:08 i end up with these ridiculously complicated macros

1:11 durka42: heh

1:11 famous last words

2:13 Mec: what's the java squareroot function?

2:15 shouldnt it be Math/sqrt?

2:15 hiredman: Math/sqrt

2:15 Yes

2:15 Mec: weird it works but you cant call it to see if it is something

2:15 ,Math/sqrt

2:15 clojurebot: java.lang.Exception: No such namespace: Math

2:18 hiredman: because it is not a clojure fn, or symbol

2:18 it is java

2:18 ,(marcoexpand '(Math/sqrt 5))

2:18 clojurebot: java.lang.Exception: Unable to resolve symbol: marcoexpand in this context

2:19 hiredman: ,(macroexpand '(Math/sqrt 5))

2:19 clojurebot: (. Math sqrt 5)

2:19 Mec: i see

2:27 bradbev: has it always been the case that refs to maps/vectors/sets don't need de-refing? ((ref {:a 0 :b 1}) :b) => 1

2:28 cmvkk: weird.

2:28 if you do it backwards, using the keyword as a key, it doesn't work.

2:28 bradbev: yeah, I tried that too :)

2:30 * Raynes huggles cmvkk

2:39 Raynes: Why is it that this http://paste.pocoo.org/show/107524/ will blow the stack if given big input (I understand that it's because the stackoverflows) but an implementation written in Scheme which calls itself at a non-tail position doesn't? Is it something to do with the JVM stack being smaller or something?

2:39 stack overflows*

2:39 * Raynes isn't so smart about the JVM.

2:44 cmvkk: if it's called in a non-tail position, it's going to use up stack space, even in the scheme version.

2:44 (i guess, anyway)

2:45 you should be able to find a large enough value to blow the stack in the scheme version too.

2:46 Raynes: cmvkk: I knew that. I just got tired of waiting on the scheme version to run out of stack space. In Clojure it happens in about 6 seconds. That's what lead me to ask the question.

2:47 cmvkk: what, how long did you wait for the scheme version to do it?

2:47 Raynes: About 2 1/2 minutes with a value of 10000 with the same algorithm.

2:47 I run out of patience fast.

2:47 :|

2:47 cmvkk: heh

2:51 Raynes: cmvkk: The reason is I've been thinking about it, is I believe it's better to just let it blow the stack when needed than try to make it otherwise. The algorithm I used is a very Lispy algorithm. It's not like anyone will actually use it anyways.

2:52 cmvkk: sure; towers of hanoi doesn't need to be practical.

2:52 Raynes: Agreed.

2:53 cmvkk: on the flip side, though, it never hurts to have experience transforming recursive algorithms into a tail configuration

2:55 Raynes: I've never seen a tail algorithm of towers of hanoi done before.

2:55 cmvkk: i assume it's possible;

2:55 Raynes: May be, but I don't intend to be the one to find out ;) not at this level of experience anyways.

2:56 I added my Clojure implementation here. http://www.rosettacode.org/wiki/Towers_of_Hanoi#Clojure If anyone comes up with something better, feel free to add it.

2:56 Cark: that algorithm is imperative, might be interesting to have it return a data structure with all moves instead

2:57 you could then try to make it tail recursive

2:57 Raynes: Cark: I intend to try to get that done tomorrow. I saw a pure Haskell version that did that.

2:58 * Raynes changes his vhost on SynIRC to www.clojure.org and goes to bed

2:58 Raynes: Night guys. Thanks for the help :)

2:59 Cark: goodnight

6:29 djpowell: how do you make a gen-class method that returns void?

6:33 #^{:static true}[runInitScript [] java.lang.Void] doesn't work - it literally returns java.lang.Void; nil doesn't work as the return type either

6:34 ah, just 'void' on its own seems to do it

6:38 karmazilla: heh, it was one of those "nah, that's too easy. Let's try something else" :)

6:54 AWizzArd: clojurebot: max people

6:54 clojurebot: max people is 158

6:54 AWizzArd: Aha, again 2 more.

7:00 Does Windows CE run a full JRE? (so, it can run Clojure)

7:05 djpowell: Probably not

7:06 Windows CE is like some sort of meta-OS, where for different applications, different things are compiled in. So smartphones, get less than PDAs, and there are some higher-end builds that are very windows like

7:07 But as microsoft doesn't support its old JVM anymore then I doubt there will be one built in to any version of CE

7:08 I think there are 3rd party JVMs, but I have a feeling that they won't be very up to date, and you probably have to pay for them

7:12 AWizzArd: I see

7:12 So much about "write once, run anywhere".

7:17 djpowell: Most phones have J2ME, but it would be a lot of work to get clojure to run on it. The class libraries are tiny, even the Collection classes aren't included.

7:19 AWizzArd: I would like to target Windows CE. And I guess it would need a full JRE to support Clojure.

7:42 djpowell: Anyone using *use_context_classloader*?

7:43 I'm not entirely convinced it is working properly. Seems to work for my AOT classes, but if I had a script to the classpath it seems to fail to load functions that it defines

7:46 er I mean, *use-context-classloader*

7:51 Lau_of_DK: Hey guys

7:51 2 things, any update on Tony Morris, and any compojure gents in here?

7:55 karmazilla: I have not heard anything new on Tony since last night. I think #scala is place to ask.

7:56 Lau_of_DK: k

7:56 Compojure any1?

8:16 in Compojure, if I go with (defservlet serv (GET "/:action" (... (route :action))) then I can pass that to a function, which can read params like //localhost/param1=10&param2=20, but this doesnt fly well with forms who GET values, because they are prepended with ?, so //localhost/?param1=10&param2=20, how do I trap that ?

8:44 karmazilla: Lau_of_DK: http://twitter.com/DRMacIver

8:52 Lau_of_DK: Shameful behaviour, that some people would use such an event as grounds for jokes

10:01 tbb: hi all, i have a quick question

10:02 is there a way to retrieve the argument list of a function? so for example: (get-arguments list?) -> (x)

10:02 gnuvince: see the meta data

10:02 ,(meta list?)

10:02 clojurebot: nil

10:03 gnuvince: ,(meta #'list?)

10:03 clojurebot: {:ns #<Namespace clojure.core>, :name list?, :file "core.clj", :line 3787, :arglists ([x]), :doc "Returns true if x implements IPersistentList"}

10:03 tbb: ah! very cool

10:03 thank you :)

10:10 pjstadig: CLABANGO!

10:10 cooldude127: WOOO

10:15 does nobody have any clojure problems? has the language become perfect?

10:16 pjstadig: clojure is a futuristic ninja robot

10:16 what more could you want?

10:16 cooldude127: lol

10:18 Drakeson: is there a clojurey way to fetch a file over http (with sending POST data along with the request)

10:19 cooldude127: i actually have a question: why do objects made with proxy wrap up their toString methods with #<Object\$Associative\$IFn 2009-03-11 00:00:00>

10:19 like in that example the date part is all that toString makes, the rest is added automatically

10:25 Chouser: cooldude127: that's not proxy, is it? It's the default print-method

10:25 ,(java.util.Date.)

10:25 clojurebot: #<Date Thu Mar 12 07:27:43 PDT 2009>

10:25 Chouser: it's #<ClassName toString-output>

10:26 cooldude127: o rly?

10:26 Chouser: if you call str or toString on the proxy object itself, you may see what you expect.

10:26 cooldude127: oh ok

10:27 it's just so ugly with proxies

10:27 cuz you get object + every interface they implement

10:27 is gen-interface the only way around that?

10:27 Chouser: right, proxy classes have big ugly names.

10:29 cooldude127: :(

10:29 even gen-interface would only make that Object\$ChronoDate

10:30 proxies suck (and rule at the same time)

10:30 Chouser: I expect there will be something eventually like proxy but which can take a class name for the class to create.

10:31 cooldude127: that would be nice

10:31 Chouser: I also expect it to allow access to protected fields

11:02 Mec: recurs on both branches of if should count as tail recursion right?

11:02 Drakeson: is there a function like `doc' in the repl that takes me to the source its argument (not just the documentation)

11:05 Chouser: Mec: yes

11:05 Drakeson: clojure.contrib.repl-utils/source

11:09 Drakeson: Chouser: cool, thanks

11:18 Mec: any library function that tells you what position an item is in a seq

11:19 Chouser: a set or map is faster and more convenient than searching a seq in almost every use case.

11:19 however, if you're sure you want to linearly walk through a seq looking for a value, try 'some'

11:20 hm, thought that won't give you the index.

11:20 though

11:20 leafw: Chouser: sure, but I had a need for an "index-of" as well in numerous occasions. I wish there was a tree-map that autoupdated its numbers to be always naturals, starting at 0.

11:20 Chouser: ,(.indexOf '(a b c d e f) 'c)

11:20 clojurebot: 2

11:21 leafw: Chouser: is that efficient for very large lists?

11:21 that's not a map.

11:21 kotarak: ,(first (some #(= (% 1) 2) (map #(vector %1 %2) (iterate inc 0) (list 1 2 3 4 5))))

11:21 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Boolean

11:21 Chouser: no, it's a linear search. Don't use it. :-)

11:21 kotarak: -.- silly me

11:22 Mec: well I'm mapping over (range 1000000) and I need to find the max value and then the position (starting number) for it, maybe there is a better way

11:23 Drakeson: will this form be supported? : (defn foo ([#^type1 x] (do-something x)) ([#^type2 x] (do-something-else x)))

11:23 Mec: i suppose i could just loop instead of map

11:23 Chouser: Drakeson: It isn't now, and I wouldn't expect it to be anytime soon.

11:24 kotarak: Mec: Maybe reduce? You walk the whole range anyway to get the maximum value.

11:24 Drakeson: so we have to write multiple dispatched "by hand", now?

11:24 Mec: i need to know at what position the max value occurs tho

11:24 Chouser: Drakeson: if you want to dispatch on type, look at multimethods

11:25 Drakeson: or use and 'if', whichever makes sense for the case at hand.

11:25 cooldude127: if you want to dispatch on any number of things, use multimethods

11:27 kotarak: Mec: (first (reduce (fn [[pos cur-pos last-max] v] (if (< last-max v) [cur-pos (inc cur-pos) v] [pos (inc cur-pos) last-max])) your-seq)), ugly but should work, no?

11:27 oops the [0 0 0] init is missing.

11:27 Mec: that just hurts to look at this early in the morning

11:28 kotarak: as I said: ugly

11:28 Drakeson: Chouser: I am thinking of a multi-dispatch slurp. currently slurp only reads from a file. it could read from InputStream, url, etc.

11:30 Chouser: Drakeson: sure. have you looked at clojure.contrib.duck-streams?

11:30 Mec: i just did it as a loop instead of map and kept track of the highest value and index ;p

11:30 cooldude127: that's probably how i would have done it

11:32 loop is my friend

11:32 Mec: when i write loops they always seem inelegant

11:33 is there a clojure pasty site?

11:33 cooldude127: ~lisppaste

11:33 clojurebot: No entiendo

11:33 Chouser: sometimes loops are the most elegant solution available

11:33 cooldude127: lisppaste8: url?

11:33 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

11:33 Drakeson: Chouser: wow, thanks.

11:33 kotarak: Most of the time I write a loop, stare at it for 2hours and then it suddenly turns into a map or recur, which us half as long and twice as elegant.

11:34 Chouser: on the other hand, indexes seem generally inelegant to me these days.

11:34 kotarak: reduce instead of recur

11:34 cooldude127: i use loops a lot when i have something that would almost work for reduce, except i don't have a sequence to work on at the start

11:34 i just have some data and i know when i'm finished

11:34 Chouser: cooldude127: yes. and in such cases 'iterate' will sometimes work but can make things really messy.

11:35 cooldude127: i have yet to use iterate for anything yet. maybe it would help in some cases, but really loop/recur is doing quite well for me

11:35 kotarak: First I had problems, when reduce should stop somewhere in the middle of the seq. Then I had the idea of (reduce ... (take-while ....))... Many loops killed. :)

11:35 lisppaste8: mec pasted "random loop" at http://paste.lisp.org/display/76898

11:35 Mec: oo nifty

11:36 cooldude127: Mec: i actually think max-key would be helpful here

11:37 Mec: i can't tell what it does from the discription

11:38 cooldude127: Mec: it does a max, but based on a function called on the data, rather than the actual value

11:38 Mec: hmm

11:39 cooldude127: Mec: if you did a map to turn [a b c] into [[0 a] [1 b] [2 c]]

11:39 Mec: so (apply max-keys f (range 1 1000000))

11:39 cooldude127: not quite i think

11:39 well yeah

11:40 but after you attach indices

11:40 rzezeski: Can anyone tell me why gen-class allows me to specify the type sig of a method (e.g. [foo [Object] void]), and then pass said method an instance of class Bar which has method fubar, and then inside the impl-fn I can call fubar on the argument (e.g. (defn -foo [obj] (.fubar obj)) )

11:41 Mec: o dont even have to do that, it still works

11:41 Chouser: , (let [most #(if (pos? (compare % %2)) % %2)] (reduce most (map vector (map #(* 2 %) (range 100)) (iterate inc 0))))

11:41 clojurebot: [198 99]

11:42 Mec: i need to look at the implemenation of max-keys, its pretty nifty

11:43 not sure if it's faster than my loop tho, it's taking a while

11:43 Chouser: rzezeski: Clojure will do reflection at runtime if needed to make such things work.

11:43 rzezeski: If I did the same in Java, I would get a compiler error unless I either cast the object or modify the type signature. I'm guessing this has something to do with the way Clojure calls back into Java?

11:44 Chouser: Anytime you say (.fubar obj x y), it will at compile time try to figure out which method fubar you mean.

11:44 rzezeski: So basically, you can uses Object in gen-class as a catch-all, but still call the methods specific to that class/instance

11:45 Chouser: if it knows (or is told via type hints) at compile time the class of obj, and can find a method that matches the arity and types of the args, it will emit bytecode that assumes that particular method.

11:45 this is independant of gen-class.

11:46 but if it can't find exactly one method that matches at compile time, it will emit code that checks at runtime for the fubar method of whatever obj actually is, and calls that.

11:46 this latter case is substantially slower at runtime than the former.

11:47 Mec: oo max-key used like that calls f twice on everything, not so good then

11:50 rzezeski: ok, lets say I'm actually passing the AOT-ed class a String, but in the gen-class method I declare it as type Object. If I understand you correctly it will emit bytecode that uses reflection to find the correct method? However, if I change the type to String (in the gen-class method declaration), it will emit bytecode that directly calls the method? Or do I also have to type hint the impl-fn?

11:51 sohail: OT: any news on this tony morris guy

11:51 Chouser: you'd probably have to type-hint the arg in the impl-fn. To find out for sure, try it with (set! *warn-on-reflection* true)

11:52 with that on, anytime reflection code is emitted at compile time, it'll warn you.

11:53 rzezeski: crap, I gotta run, thx for the help Chris

11:53 Chouser: rzezeski: np

12:04 Mec: is (count string) O(1)?

12:05 cgrand: Mec: yes

12:05 Mec: excelent

12:06 * cooldude127 wants a decent Java repl

12:06 kefka: Is it bad form or dangerous to have a ref to something mutable, e.g. a ref to a map whose values are refs?

12:07 cooldude127: first person to suggest using clojure as my java repl gets a sharp stick in the eye

12:07 kotarak: cooldude127: beanshell?

12:08 Mec: you could implement java in clojure and then have a java repl ;p

12:09 * cooldude127 did not know beanshell had a console

12:10 Chouser: kefka: that's not necessarily bad

12:12 kefka: Chouser: Ok, because what I'm looking for is a map of refs/pointers so that I can synchronously change individual pointers without locking down the whole map

12:13 Chouser: So, thinking about it, is the right approach to make the map an atom and the values refs?

12:24 walters: cooldude127: i use groovy for that

12:26 cooldude127: walters: groovy has a repl?

12:27 walters: cooldude127: yeah, there's a console one and a swing one; and this shell i'm very slowly developing also uses groovy

12:27 cooldude127: hmm. the problem i had with beanshell was getting my java code to run inside

12:27 Chouser: kefka: will you want to coordinate changes to multiple sub-maps at the same time?

12:29 fogus: I think all the real-time tweets about Rich's persistent datastructures presentation broke Twitter.

12:29 Chousuke: is there a video of it already available somewhere?

12:31 fogus: Not that i'm aware of

12:31 From the tweets it appears to have just happened

12:32 kotarak: I hope there will a video or a podcast of some sort.

12:35 replaca: today was Rich's second talk

12:35 he gave a Clojure overview yesterday

12:35 and is talking about functional data structures today

12:36 I assume there will be video up - I've seen lots of videos from past QCONs online

12:36 AWizzArd: sounds nice

12:36 fogus: link?

12:37 fogus: I was just joking about breaking Twitter. But there has been a lot of buzz flying around about Clojure after his two talks. http://search.twitter.com/search?q=clojure

12:39 leafw: are the talks online somewhere?

12:40 replaca: There's been a lot of mainstream media attention on twitter the last few weeks. I bet their usage is *way* up. So it's back to the fail whale :-).

12:41 leafw: twitter needs a sugar daddy, aka google, who sees value in all the information flying within twitter.

12:41 defn: I don't think the information twitter produces is even remotely valuable.

12:41 :X

12:41 fogus: I'm not aware of any qcon content available yet, but the likely place to look is at http://www.infoq.com/qcon/

12:42 defn: It's like a place for all of the incomplete garbage text to live

12:42 a lot of investors obviously disagree with me

12:42 fogus: defn: I think it is highly valuable to know what Charles Nutter is eating for lunch.

12:42 :p

12:42 defn: but i think its just too novel to be useful

12:42 fogus: hehe

12:43 leafw: defn: human relationships and the study of motivation and information encoding and transmission; there's the value.

12:43 djpowell: what is the best way to remove an element from a set?

12:43 defn: leafw: yeah i can definitely see that, but i just dont know if you get a valuable assessment of motivation,relationships

12:44 the latter point you make is certainly worth developign though

12:44 developing*

12:44 djpowell: - ah 'disj' - I was looking for something in clojure.set

12:51 replaca: twitter just raised \$35M. I don't think money's their problem. But they keep going through crazy growth spurts.

12:53 fogus: djpowell: (clojure.set/difference #{:a :b :c} #{:a}) ?

12:59 defn: danlarkin: Needs moar Clabango.

13:01 fogus: does anyone recall the link to the recent (within 1-2 weeks) thread about the -> macro?

13:02 doing a search for -> is less than helpful

13:02 replaca: fogus: you mean with ?-> for doing nil short-circuiting?

13:02 hiredman: he means on the google group

13:03 replaca: yeah, that was both here and there

13:03 hiredman: I see a few "best presentation ever" in reference to rhickey's qcon talk

13:04 fogus: replaca: possibly, I was hoping to pick the thread up again

13:04 replaca: hiredman: one of Clojure's big advantages is that rhickey is a very compelling presenter. I definitely got hooked on the Clojure for Lisp programmers podcast

13:04 fogus: what I recall was that there were a few excellent simple explanantions about what -> does

13:04 I'm trying to explain it to a co-worker, but cannot find the words

13:05 hiredman: it expands into itsself

13:06 replaca: fogus: yeah, I was thinking of a different thread, sorry

13:06 hiredman: (-> a b c) becomes (-> (b a) c) becomes (c (b a))

13:06 "threading operator"

13:07 fogus: that's one of those explanations that makes sense only if you already know what it means. ;)

13:07 But it's still better than what I can come up with

13:10 hiredman: I think the best way might be to write out an expression using (-> ) and then walk through all it's intermediate expansions

13:17 Raynes: Good morning fellow parenthesis lovers.

13:38 * Holcxjo will soon be off to hear Rich talk at Skills Mater Ltd :-)

13:38 gnuvince: Holcxjo: that's tonight, right?

13:38 Holcxjo: In 1 hour

13:39 gnuvince: Holcxjo: are you gonna twitter it?

13:39 Holcxjo: Probably busy taking notes...

13:39 not sure they'll have the Wifi up either

13:39 but if so, I'll post it here in IRC if wanted

13:40 gnuvince: Cool

13:40 He's doing his "Clojure for Java programmer" talk, right?

13:40 Holcxjo: yes :-(

13:40 but it's about �450 cheaper than the talk he gave today

13:42 gnuvince: heh :)

13:46 Mec: if I have a list of strings, how might i (reduce .concat strings) since you cant actually do that?

13:46 i guess i can just make a function

13:46 cooldude127: Mec: (apply str strings) ?

13:47 Mec: thanks

13:47 cooldude127: ,(apply str '("bob" "fred" "joe"))

13:47 clojurebot: "bobfredjoe"

13:47 cooldude127: yay

13:47 Mec: i didnt know str would concat like that

13:47 cooldude127: yeah

13:47 ,(str "hello " "my friend")

13:47 clojurebot: "hello my friend"

13:48 Mec: hmm apparently it doesnt

13:48 cooldude127: Mec: what do you mean?

13:49 Mec: i ran it thru and it returned "\"1\" \"2\"" etc

13:49 cooldude127: Mec: maybe paste the code?

13:49 Mec: nvm missed apply

13:49 cooldude127: that sounds right

13:53 Mec: wow now my answer is just wrong because i cant spell :x

13:57 theres "four" but "forty" so i thought "forteen" but no no

13:57 cooldude127: lol

14:38 Mec: will this use up the stack: (def fib ((fn rfib [a b] (lazy-cons a (rfib b (+ a b)))) 0 1))

14:38 Chousuke: ooh, a pretty-printer

14:40 cmvkk_: Mec any recursion that doesn't use the 'recur' function will use up the stack, in Clojure.

14:40 well actually...

14:41 Cark: this should not use stack space

14:41 cmvkk_: yeah,

14:41 that's a lazy sequence so it won't

14:41 Mec: i shouldnt think so, but it does seem like it should

14:42 cmvkk_: well "lazy-cons" doesn't execute the recursion, it just returns, which is why it doesn't.

14:42 Mec: it still has to save the values somehow, is a closure not a stack layer?

14:43 Cark: right but you only have one stack frame at all time

14:43 cmvkk_: as an aside, none of the newest versions of clojure have 'lazy-cons' anymore

14:44 Mec: what do they have?

14:44 cmvkk_: lazy-seq.

14:44 Chouser: Mec: a closure is not a stack layer.

14:44 Mec: whats the dif?

14:44 for cmvkk_ ;p

14:44 Chouser: a closure can include values from any layer of a stack, so each of the values needed is stored on its own

14:44 Cark: chouser : depends on the implementation doesn't it ,

14:45 Chouser: I'm referring to Clojure. :-)

14:45 Mec: i thought lazy-cons returns a lazy sequence, is it just renamed?

14:45 cmvkk_: lazy-seq works slightly differently, there's a page for it somewhere...but if you're using lazy-cons you should consider updating

14:45 Cark: ah yes, sorry =P

14:45 Chouser: But I think even in other languages/implementations, if it captures the whole stack it is a continuation, not just a closure.

14:46 Mec: my version doesnt even have lazy-seq so i guess its moot

14:46 Cark: chouser : i beleive in some schemes it will captuer only the revelant stack frames

14:47 mec : you should update

14:47 lazy-seq is here to stay

14:47 Mec: im too scared of breaking emacs now that i finally got it working ;p

14:47 Cark: or i hope so anyways

14:47 Chouser: except it's a breaking change, so don't until you're ready.

14:47 cmvkk_: i have a long question:

14:47 Mec: lazy-seq isnt even in the api?

14:48 cmvkk_: my framework has these data structures called tracks, which are just vectors of vectors (one big one holding many small ones), but

14:48 Cark: ,(doc lazy-seq)

14:48 clojurebot: "([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls. Any closed over locals will be cleared prior to the tail call of body."

14:48 cmvkk_: the first element in the vector is a map containing type information and type-specific attributes for the track.

14:48 Chouser: Mec: http://clojure.org/lazy

14:48 cmvkk_: i want to make them lazy-seqs instead (so that they can be infinite), but i don't know what to do with the map at the front. Before I figure that out, is this the sort of thing that I should be using metadata for?

14:49 Mec: Chouser: thanks

14:49 cmvkk_: I don't feel like I have a good grasp on what metadata is really 'for'.

14:49 Chouser: cmvkk_: the central rule is that metadata does not participate in equality

14:49 gnuvince: cmvkk_: anything you want

14:49 Cark: i don't like the idea on having type information in meta-data

14:50 gnuvince: cmvkk_: Clojure does not dictate what you put into it. Usually, you put in things that don't belong in the data itself.

14:50 Cark: if it's a different type, it should not be =

14:50 cmvkk_: So I feel like in this case that a track with different elements in the map might sound different when rendered (because I am using that data), so I guess it's not metadata?

14:50 Chouser: cmvkk_: that seems likely

14:50 gnuvince: ,(= (list 1 2 3) [1 2 3])

14:50 clojurebot: true

14:50 Chouser: cmvkk_: so, you can either go ahead and put your map as the first element of the lazy seq

14:50 Cark: gnuvince : both are sequences !

14:51 Chouser: Cark: no

14:51 a vector is not a sequence.

14:51 cmvkk_: or you could store the lazy seq inside the map

14:51 cmvkk_: Chouser, I'm thinking that's what I'll do, thanks.

14:51 Chouser: cmvkk_: or make a new top-level structure (a map? a two-element vector?) that holds the map and the lazy seq

14:52 cmvkk_: but with that said, I still can't think of a good use for metadata. what kind of data would you want that doesn't change the value of the element in question?

14:52 Cark: mhh so by which virtue are these = ?

14:53 Chouser: they're both Sequential IPersistentCollections that contain = values.

14:54 Cark: you mean they have some type in common

14:55 cmvkk_: they both define their equality by the equality of their constituents, I assume

14:56 Chouser: I guess I'm not very sure of the details of the equality rules. There's a paper on the subject I've so far avoided reading.

14:57 ,(= {:a 1 :b 2} [[:a 1] [:b 2]])

14:57 clojurebot: false

14:57 Chouser: ,(= (seq {:a 1 :b 2}) [[:a 1] [:b 2]])

14:57 clojurebot: true

14:57 Mec: man, it took me a long time to finally understand lazy-cons, lazy-seq is just a big woosh

15:01 danlarkin: Lau_of_DK where oh where are you :(

15:17 * Holcxjo is listening to Rich -- envy me! ;-)

15:18 Raynes: ~source ref

15:19 cooldude127: Holcxjo: i do

15:22 maacl: When I try to launch slime with swank-clojure-jar-path set to the compojure clojure.jar I get java.lang.ExceptionInInitializerError (NO_SOURCE_FILE:0) - the REPL seems to work if I abort - any ideas why ?

15:23 * kotarak search for the dagger looking at Holcxjo ;)

15:25 Chouser: that's what I'm doing for my birthday.

15:26 WizardofWestmarc: later guys, meeting time where I get to present *weee*

15:26 maacl: Setting up emacs/slime to work interactively with compojure is a nightmare - does anyone know of a guide ?

15:28 cooldude127: i don't remember compojure being that difficult

15:28 but i haven't looked in a little while

15:31 maacl: cooldude127: I have all the jars in my classpath, but I get the error I just posted when I start slime. If I then do (use 'compojure) at the repl I can eval / compile a file the uses compojure otherwise I just get errors about missing source files

15:38 pjstadig: clojurebot: pastebin

15:38 clojurebot: I don't understand.

15:39 pjstadig: clojurebot: pastebin link

15:39 clojurebot: Huh?

15:39 cmvkk_: ~paste

15:39 clojurebot: lisppaste8, url

15:39 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

15:39 pjstadig pasted "reading a file" at http://paste.lisp.org/display/76917

15:39 pjstadig: am i missing something?

15:40 I'm trying to read from an input stream and write to an output stream

15:40 buff is 1K

15:41 the loop is stopping after one iteration

15:41 writing a 1K file

15:41 cmvkk_: why the ==?

15:41 pjstadig: i tried =

15:41 was getting weird behavior and started randomly changing things for no reason

15:42 cmvkk_: you're reading into the buffer then writing all at once, is that right?

15:43 pjstadig: reading a chunk at a time using buff which is a 1K buffer

15:43 cmvkk_: you might want to use 'when' rather than 'if'. becuase you're only recurring when you' aren't writing.

15:43 pjstadig: oh

15:43 yes

15:43 stupid me!

15:43 hehe

15:43 maacl: Anybody who can help me getting compojure up and running with emacs/slime? this driving me nuts

15:44 pjstadig: i knew it had to be something stupid

15:44 cmvkk_: i think when you're doing something iterative it's a lot easier to get tripped up with if's syntax.

15:44 something mutable

15:54 noidi: is there an easy way to read a string? like (read (some-stream-wrapper-thingy "(1 2 3)")) --> (1 2 3)

15:56 kotarak: noidi: read-string

15:56 noidi: argh, read-string

15:56 yup :)

15:56 kotarak: (doc read-string)

15:56 clojurebot: Reads one object from the string s; arglists ([s])

15:56 noidi: sorry, should've googled that

15:57 kotarak: (doc find-doc)

15:57 clojurebot: Prints documentation for any var whose documentation or name contains a match for re-string-or-pattern; arglists ([re-string-or-pattern])

15:57 kotarak: ;)

15:57 noidi: funny that it's not mentioned in http://clojure.org/reader

15:58 danlarkin: clojurebot: max people

15:58 clojurebot: max people is 161

15:58 danlarkin: ~whoah, that's a ..... surprise

15:58 clojurebot: Pardon?

15:58 danlarkin: bah

15:58 joke ruined

15:58 cmvkk_: heh

15:59 Chouser: ~there used to be 160, then suddenly...

15:59 clojurebot: CLABANGO!

15:59 Raynes: My chicken exploded.

16:01 danlarkin: ah there we go

16:01 suddenly

16:04 kotarak: Does anyone have a sane ant setup, where some Java class depends on some gen-class stuff, and some other clojure stuff depends on the Java stuff?

16:06 danlarkin: kotarak: I've got one doing gen-class and AOT'ing the rest, but that's not really what you're after

16:08 kotarak: danlarkin: it's basically some clj -> java -> some clj in the dependency chain. I'm annoyed by programs like javac which claim to do a better job than make.... They don't!

16:08 pjstadig: ~surprise!

16:08 clojurebot: surprise is CLABANGO!

16:08 pjstadig: d'oh

16:09 cmvkk_: heh

16:09 hiredman: use <reply>

16:09 pjstadig: i'm must have told him wrong

16:09 kotarak: And then suddenly...

16:09 pjstadig: oh

16:09 ~surprise

16:09 clojurebot: CLABANGO!

16:16 danlarkin: have you guys seen this? "Uncomfortably Parallel"... it's hiiiilarious http://www.youtube.com/watch?v=1yH_j8-VVLo

16:20 noidi: is there a way to convert (1 2 3 4 5 6) into ((1 2) (3 4) (5 6))?

16:21 i wrote a function to do that, but it's so ugly that it must be wrong :)

16:21 Chouser: ,(partition 2 (1 2 3 4 5 6))

16:21 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

16:21 Chouser: ,(partition 2 '(1 2 3 4 5 6))

16:21 clojurebot: ((1 2) (3 4) (5 6))

16:21 noidi: thanks!

16:23 Chouser: danlarkin: I'm still laughing.

16:24 danlarkin: MUNCTIONAL

16:25 noidi: Do you want gratuitous amounts of volume changes? LOUD (quiet) LOUD (quiet)

16:26 kinda ruined it for me, but thumbs up for the idea :)

16:27 replaca: danlarkin: fabulous! :-)

16:34 lisppaste8: noidi pasted "helloworld" at http://paste.lisp.org/display/76919

16:35 noidi: i'm really beginning to like clojure

16:35 i couldn't imagine writing a doctest clone as a "hello world" project in any other language :)

16:36 and after two evenings of work it seems coming along quite nicely

16:36 +to be

16:47 rzezeski: kotarak, what we really need is a joint compiler

16:48 kotarak: rzezeski: what we need is a simple way to extract dependency information and a capable build system. Eg. like cook.

16:49 rzezeski: I'm not sure what cook is, but I think it would be awesome if someone could come up with a generic joint compiler for all languages that live on the JVM, allowing us to easily mix java/clojure/groovy/scala/jruby/etc

16:50 maacl: When I try to launch slime with swank-clojure-jar-path set to the compojure clojure.jar I get java.lang.ExceptionInInitializerError (NO_SOURCE_FILE:0) - the REPL seems to work if I abort - any ideas why ?

16:51 kotarak: rzezeski: you see: java, clojure, groovy, scala, ... Why not a small (easy to debug) dependency extraction tool (eg. like OCaml ocamldep) and a build system which is capable of coping with such dynamic information. Make is notoriously bad at that, but eg. cook (a make replacement) does this quite well. (Although ocamldep as well as cook aren't perfect, either...)

16:53 rzezeski: do you have a link for cook?

16:54 Chouser: someone mentioned a builder for mixed clojure/java programs

16:54 ^^ Buildr

16:54 rzezeski: Chouser, I know someone wrote a java/clojure/groovy joint compiler for Buildr

16:55 kotarak: "gems" probably means Ruby...

16:57 pjstadig: Buildr is a Ruby based Java build tool

16:57 i think there is already a proliferation of build tools

16:57 rake, make, ant, maven, buildr, lancet

16:57 what we need is a non-proliferation agreement

16:57 rzezeski: yea, the problem is these joint-compilers are all one-offs, and they must take into account the "parent" compilers that came before them. So for every different combination you need a new joint compiler, or you need to come up with some weird/fragile build order

16:58 walters: heh

16:58 pjstadig: these are weapons of mass construction

16:59 noidi: hehe

16:59 walters: well, part of it is "don't do that" too - e.g. keep the Java to the lower layers of the system, the dynamic languages for the faster moving parts on top

16:59 so bottom doesn't depend on top

17:00 Chouser: conversely, stop writing Java and just use Clojure.

17:00 rzezeski: walters, to an extent, but on larger projects it can be harder keep the different languages from mixing. Circular dependencies are a fact of life, and a single compiler handles them just fine, it's when you cross language boundaries that things get weird

17:00 Chouser, if only :)

17:01 kotarak: Chouser: tell this our working student.... I tried to infect him with Clojure bacillus but he still has his defenses up....

17:01 Chouser: hmph

17:03 rzezeski: Eg, I'm working on a Grails/Clojure plugin so that I can utilize Clojure power from my Grails projects. However, since there is no joint compilation the dependency can only go one way, my Grails code can know about the AOT-ed classes, but not the other way around. It would be nice if that restriction wasn't there.

17:05 Chouser: no AOT for grails?

17:07 rzezeski: Chouser, not sure if you're joking or you are asking if there is a way to generate stubs in Grails?

17:08 Chouser: If grails can produce class files, then a sufficiently powerful build tool could allow you to write clojure code that used them, right?

17:09 rzezeski: yes, I agree, if you build tool is smart enough, it could search the dependencies and switch back and forth between the compilers to get the right order

17:09 if thats what you mean

17:13 Chouser: i guess that's what I mean. :-) Haven't given it much thought.

17:13 walters: rzezeski: depends what you want to do, but have you e.g. experimented with using the Clojure data structures and STM from groovy?

17:15 rzezeski: haha, yea I'm not explaining myself very well either, I've just recently started working on this and so my knowledge of the problem is still shallow. I still have to play with AOT more and see what sticks, but even one-way I still think it's nice to allow Grails users to utilize some Clojure-fu in their projects

17:17 Walters, no, I have not tried using the Clojure data structures directly from Groovy. Although I read an article of someone doing it in Ruby (I think) and having success. My main reason for my plugin is to actually write Clojure functions that can be called in my Grails projects

17:19 kotarak: Why are people so obsessed with speed?

17:19 Raynes: Groovy is so not groovy.

17:19 rzezeski: lol

17:19 Raynes: kotarak: Because we liek fast things.

17:19 Vroom Vroom.

17:19 rzezeski: Raynes, it's better than tradition J2EE, and I'm happy that I'm working in Groovy in a predominately .Net shop

17:20 traditional*

17:20 it could be much worse

17:20 Raynes: Clojure would be much better though.

17:20 Oh the agony.

17:21 rzezeski: Yes, it would be nice, that's why I'm writing this plugin!

17:21 It's a foot in the door

17:21 Raynes: What plugin?

17:21 O.O

17:21 rzezeski: clojure plugin for grails

17:21 Raynes: Oh neat.

17:23 rzezeski: I can't believe this place has 160 ppl in it, it was hovering around 90ish in November

17:24 Raynes: rzezeski: The growth of Clojure has been amazing since I started coming here.

17:24 shoover: we're all sitting here waiting for clabango

17:24 rzezeski: Raynes, when was that?

17:24 Raynes: If you Google Clojure you can notice that /everyone/ is trying it, and almost everyone is liking it. The channel gets 10 new people on a monthly basis.

17:24 It was around 3 months ago.

17:24 kotarak: rzezeski: lurkers in #clojure * 10 = members of the google group

17:24 Raynes: 115 people were in here regularly.

17:25 danlarkin: ha, speaking of... I need someone to help me test... who volunteers?

17:25 Raynes: CLABANGO!

17:25 p_l: 20:56 -!- Irssi: New peak in #clojure@freenode : 160 20:57 -!- Irssi: New peak in #clojure@freenode : 161 .... 21:44 -!- Irssi: New peak in #clojure@freenode : 16

17:25 pjstadig: ~surprise

17:25 clojurebot: CLABANGO!

17:25 cmvkk_: i'd guess both this channel and the group represent a small portion of users...i lurk on the google group but am not a member, for instance.

17:26 rzezeski: kotarak, what's that...like 1500?

17:26 pjstadig: i keep telling people that Clojure is the next big thing

17:26 * shoover raises an eyebrow towards danlarkin

17:26 pjstadig: booyah!

17:26 ~booyah!

17:26 clojurebot: CLABANGO!

17:27 kotarak: rzezeski: 1602 or something

17:27 pjstadig: hehe

17:27 shoover: clojurebot: clabango?

17:27 clojurebot: Excuse me?

17:27 pjstadig: i better stop

17:27 shoover: clojurebot: clabango is the greatest web framework yet to be written

17:27 clojurebot: Ack. Ack.

17:27 pjstadig: or soon anything you say to clojurebot will result in a CLABANGO!

17:27 i setup a site BTW

17:28 shoover: pjstadig: wha?! I just checked... parked

17:28 pjstadig: i'm waiting for 1and1 to update the NS servers

17:28 it takes forever

17:28 shoover: ok

17:28 pjstadig: i submitted the change 8 hours ago

17:28 cmvkk_: heh

17:28 pjstadig: might show up by tomorrow

17:28 cmvkk_: or in a few weeks, whatever...

17:29 jhawk28: I used to have 1and1 - yes they are slow

17:29 Dreamhost is much faster

17:29 rzezeski: kotarak, are you Brandmeyer ?

17:30 * kotarak hides, "Boss! Was discovered by rzezeski! Have to leave!"

17:30 rzezeski: lol

17:31 first off, thx much for VimClojure man, it was really nice not to have to go back to emacs just for some good Clojure support

17:31 pjstadig: what's wrong with emacs?!

17:31 j/k

17:32 rzezeski: Nothing

17:32 but I want a text editor, not an OS ;)

17:32 nah, I prefer Vim keybidings, IMO they are superior, and no I don't care about Emacs Viper mode

17:32 kotarak: rzezeski: did you try the new one?

17:33 rzezeski: kotarak, I was just about to get to that, I have a question

17:33 kotarak: sure

17:33 rzezeski: At the top of my vimrc I 'let' my maplocalleader to ","

17:34 but when I try to invoke StartRepl or any of the commands, it's as if it didn't care that I set LocalLeader

17:35 eg, when I hit ,sr , it seems to ignore the comma, and then test 'sr' like it normally would

17:35 kotarak: rzezeski: hmmm.. do you edit a clojure file? (I have also , and it works.)

17:35 rzezeski: yea, I open up core.clj

17:36 and I have the nailgun server, not like that should affect the key binding

17:36 kotarak: rzezeski: does \ work?

17:36 rzezeski: I saw you comment about Plugs (which I don't really understand), but I figured as long as I set LocalLeader I should just be able to use the default key bindings

17:36 not \ does not work either

17:37 kotarak: rzezeski: and you are in normal mode?

17:37 rzezeski: as in, not in insert mode?

17:37 or visual mode

17:37 kotarak: yeah

17:37 yeah

17:37 rzezeski: yes

17:38 kotarak: hrmph...

17:38 rzezeski: And I have syntax on a the filetype declaration

17:38 kotarak: syntax works?

17:38 rzezeski: yes

17:38 kotarak: more hrmph...

17:39 rzezeski: If it makes any diff I pulled from your version control

17:39 I like bleeding edge

17:39 kotarak: is identical to the release at the moment.

17:39 rzezeski: maybe I forgot to copy something?

17:40 kotarak: autoload, indent, syntax, ftplugin, ftdetect, doc...

17:40 rzezeski: oh, also, I'm using vim in a shell, not in gui mode if that makes a diff

17:40 kotarak: Hmm... It should not for the Repl, also it might for the highlighting of the ParenRainbow.

17:41 what does nmap ,sr say?

17:41 rzezeski: yea, I did a 'cp -r' on autoload, doc, ftdetect, ftplugin, and syntax

17:42 "no mapping found"

17:43 kotarak: argh. Did you put "let clj_want_gorilla = 1" in your .vimrc?

17:43 rzezeski: if I do "call vimclojure#Repl.New()" I get a Repl window but it's kinda messed up

17:44 "let g:clj_wants_gorilla = 1" ...straight from my vimrc

17:44 oh wait

17:44 kotarak: w/o s

17:44 rzezeski: I see a typo

17:44 tada

17:44 kotarak: ^^^^ I figure it works?

17:45 rzezeski: yep

17:45 kotarak: \o/ :)

17:45 rzezeski: FYI, you have a typo in clojure.txt ;)

17:45 cause I straight copied it

17:45 kotarak: Doh. /o\

17:46 rzezeski: thx for the help, and you're welcome for the bug report ;)

17:50 kotarak: rzezeski: thanks for the report. Now there is also a bleeding-edge branch. ;)

17:50 rzezeski: haha

17:50 i'm glad to see you eliminated the Ruby dep

17:50 Also appears you added some more key bindings too

17:51 looking forward to checking it out

17:51 kotarak: Me too. It was annoying and unstable.

17:51 rzezeski: try <C-X><C-O> (this time in insert mode) :)

17:51 rzezeski: ok

17:52 kotarak: eg. as in r-s<C-X><C-O>

17:52 rzezeski: oh snap, that's hot!

17:52 kotarak: If you got the preview window you can close it with ,p

17:53 rzezeski: very nice

17:53 kotarak: :)

17:53 rzezeski: thx for the hard work

17:53 much appreciated

17:53 durka42: kotarak: yesterday cooldude127 and i were complaining that the repl window resizes every time you evaluate an expression. i discovered that :set noequalalways makes it not do that. maybe something to put in the docs

17:53 kotarak: Huh? It does.

17:55 rzezeski: kotarak, you know what would be REALLY killer, if we could get some kind of "live templating" action going on in VimClojure. So you could do omni complete, find your selection, then when you hit enter it creates the shell and puts you in the first editable slot, and then you keep hitting tab to move to the next slot until you fill out the skeleton

17:55 kotarak: You mean for the arguments.

17:55 rzezeski: I think they have some basic support for this stuff in Vim, but I haven't had time to try it

17:55 kotarak: They have? o.O

17:56 rzezeski: there is?

17:56 kotarak: durka42: Ah. Ok. I understand the equalalways thing.

17:56 rzezeski: have you ever seen screencast of people using TextMate?

17:57 kotarak: No.

17:57 rzezeski: Oh ok, I'll have to find one and send you the link, it's easier to see it then it is to explain it

17:57 kotarak: durka42: I have to open a temporary file for the Clojure interaction. That's why the window gets resized. Will put a not in the docs.

17:57 note

17:57 durka42: ah, i see

18:00 kotarak: durka42: or maybe I can disable the option and re-enable it afterwards..... Have to have a look...

18:03 tashafa: quick question...

18:03 how do i get every other element into a seq

18:04 kotarak: take-nth maybe

18:04 hiredman: ,(map second (partition 2 (range 10)))

18:04 clojurebot: (1 3 5 7 9)

18:04 tashafa: hiredman you are the best

18:04 kotarak: ,(take-nth 2 (range 2))

18:04 clojurebot: (0)

18:04 kotarak: ,(take-nth 2 (range 10))

18:04 clojurebot: (0 2 4 6 8)

18:04 hiredman: ooo

18:05 kotarak is better

18:05 tashafa: i take that back hiredman

18:05 hiredman: ~kotarak is better

18:05 clojurebot: c'est bon!

18:05 kotarak: huh?

18:05 tashafa: kotarak is the man

18:05 jk hiredman

18:05 * kotarak bows.

18:06 tashafa: you've helped me way too many times

18:06 hiredman: but I have no vimclojure love

18:06 I may just not have any vim love

18:06 kotarak: no?

18:07 tashafa: ,(doc take-nth)

18:07 clojurebot: "([n coll]); Returns a lazy seq of every nth item in coll."

18:07 tashafa: god i should know that

18:07 hiredman: I am not sure how this "localleader" thing works, and none of the key combinations I try with \ (the default localleader??) work

18:07 tashafa: i need to hack clojure everyday

18:08 kotarak: hiredman: Have you set "let clj_want_gorilla = 1" in your .vimrc? There was a typo in the docs.

18:08 hiredman: ah

18:08 so no g:

18:08 kotarak: the g: should not matter.

18:09 As long as it's not in a function.

18:09 hiredman: ah

18:09 so the docs said wants

18:09 kotarak: yes.

18:09 Sorry.

18:09 hiredman: *shrug*

18:09 rzezeski: localleader is a way to handle key bidning clashes between global and plugins

18:09 hiredman: it happens

18:10 rzezeski: you can set it like so 'let maplocalleader = ","'

18:10 hiredman: ok

18:10 wonderful

18:10 now I get errors

18:10 rzezeski: w/o the surronding single quotes that I shouldn't have added in

18:10 hiredman: this is progress

18:11 all kinds of errors

18:11 rzezeski: lol

18:12 Drakeson: how should I "pipe" an InputStream into a file ?

18:12 hiredman: hah

18:12 groovy

18:12 I had forget that I stopped the nailgun server last night

18:12 with it running it works

18:13 Drakeson: you open an OutputStream on the file, and loop around both the InputStream and the OutputStream reading from the InputStream and writing to the OutputStream

18:14 kotarak: Drakeson: apache.commons has some copy function.

18:15 hiredman: yeah

18:15 commons.io is the way to go

18:17 rzezeski: kotarak, this is kind of what I was talking about when I said "live templating" http://drnicwilliams.com/wp-content/uploads/2008/06/textmate-snippets-running-ruby.mov Mainly, the ability to build a skeleton of text and use the tab key to navigate through the the parts you want to edit. It helps avoid typing syntax and I think helps keep from constant switching between insert and normal mode.

18:20 Drakeson: OK, do you see a pitfall in (spit "filename" (slurp* stream)) ?

18:22 rzezeski: kotarak, it may not be as useful in Clojure since there isn't really much rigid syntax, but things like auto matching/deleting parenthesis, brackets, braces would be a good start.

18:22 jhawk28: be careful about using commons.io with files that need to be locked

18:23 kotarak: rzezeski: you might want to look into autoclose.vim

18:23 rzezeski: will do

18:30 autoclose led me to surrond.vim, that looks pretty nice

18:30 have you tried either?

18:32 Lau_of_DK: Good evening gents

18:33 kotarak: rzezeski: I tried autoclose and got always confused with the parens. So I gave up in the end.

18:35 rzezeski: I see, well I'll give surround.vim a try

18:35 kotarak: Haven't looked at that.... Maybe I will, too

18:36 Lau_of_DK: Checked out paredit for emacs?

18:36 rzezeski: thx for vimclojure, it has been invaluable for me

18:37 I'm outta' here, later guys/gals

18:38 Lau_of_DK: l8r

18:50 lisppaste8: mec pasted "inf-sequence" at http://paste.lisp.org/display/76928

18:51 Mec: my first macro ^^ tell me how badly i screwed it up :D

18:51 Chousuke: why is it a macro? :)

18:52 Mec: because it wants to be

18:52 Chousuke: it's old-style code anyway.

18:52 with lazy-cons

18:53 Mec: im not running off the repo so i dont have lazy-seq

18:53 Chousuke: but I dunno, seems okay to me.

18:54 Mec: you asked why is it a macro, how do you do it as a function

18:55 Chousuke: well, I guess being a macro makes it a bit neater.

18:55 Mec: it keeps trying to evaluate its args as a function

18:59 danlarkin: Lau_of_DK: ready to help me test out clab... err... madison?

18:59 Drakeson: I still don't get it :( what is the clojurey way of piping a stream into a file? is (spit "filename" (slurp* stream)) a good way?

19:00 Chousuke: hm

19:00 probably not

19:00 Lau_of_DK: ~ dan, you know, I was ready to test, when suddenly...

19:00 clojurebot: CLABANGO!

19:00 Lau_of_DK: You got it uploaded somewhere?

19:00 danlarkin: nope, you get to be my betatester

19:00 Chousuke: Drakeson: you should probably use some java classes.

19:01 Lau_of_DK: k - since its almost bedtime here, you can send me a zip, and I'll have a look at it and get back to you over the weekend, sounds good?

19:01 danlarkin: sure

19:03 Mec: i love clojures gensym, it's gotta be the simplest in existance

19:11 Lau_of_DK: Good night America, whereever you are

19:24 Drakeson: Chousuke: I see.

19:24 dreish: Sounds like rhickeys talks this week have been a hit, from watching twitter.

19:26 jhawk28: dreish: are they online?

19:26 dreish: I doubt they'd be up yet, but I think he's going to put them up.

19:26 gnuvince_: I imagine infoq.com are gonna put up the one from qcon eventually

19:26 jhawk28: where did he speak? Im in brain-dead mode

19:26 gnuvince_: QCon and another place in London

19:27 jhawk28: qcon should be up on infoQ soon then

19:29 dreish: I'm a little bummed because I found a bug in the version of Clojure I have installed at work, and I ran home to reproduce it on my more recent compile, but it has already been fixed.

19:29 I wanted the glory of reporting a bug.

19:29 hiredman: clojurebot: latest?

19:29 clojurebot: latest is 1327

19:30 cmvkk_: is there glory in bug reporting?

19:30 dreish: Tons.

19:30 cmvkk_: i've done it a few times for clojure, but they were all for ridiculous use circumstances, nobody else had noticed them yet because they weren't abusing the language

19:31 dreish: This one seemed pretty serious to me: (= '(1 2 3) [1 2 3]) was true, but the hashCode() for the two collections was different.

19:32 hiredman: ,(doc =)

19:32 clojurebot: "([x] [x y] [x y & more]); Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison."

19:32 cmvkk_: oh we were talking about that earlier. is that a bug, and it was fixed?

19:32 hiredman: "and collections in a type-independent manner."

19:32 cmvkk_: aha.

19:32 dreish: With the result that when an array hash was promoted to a tree-based hash, keys would seem to disappear if they were being looked up by their synonyms.

19:33 It was a bug -- the issue wasn't the = function per se, but .equals() and .hashCode() violating the contract for .hashCode().

19:33 hiredman: ah

19:33 I understand

19:33 yes

19:33 dreish: Anyway, now it works. hashCode()s are the same.

19:33 hiredman: man, php is so dirty

19:36 it really makes you appreciate java

19:37 you know, instead of writing a lisp in php so I can just write lisp and have it work where there is php, maybe I should just never ever write php again

19:38 cmvkk_: maybe nobody should.

19:40 gnuvince_: PHP and its weird definition of equality when using ==

19:41 have some clojure-generated zelda music.

20:29 cp2: neat cmvkk_

21:21 Mec: does clojure or java have a utility for converting bases?

21:22 cmvkk_: java definitely does somewhere

21:22 do you mean like numeric bases in string representations of numbers?

21:23 hiredman: ,(Interger/parseInt "10" 2)

21:23 clojurebot: java.lang.Exception: No such namespace: Interger

21:23 hiredman: ,(Integer/parseInt "10" 2)

21:23 clojurebot: 2

21:23 hiredman: ,(Integer/parseInt "10" 4)

21:23 clojurebot: 4

21:23 hiredman: ,(Integer/parseInt "1" 4)

21:23 clojurebot: 1

21:23 hiredman: ,(Integer/parseInt "11" 4)

21:23 clojurebot: 5

21:24 Mec: is there a way to go to the other base?

21:25 specifically i need to go from decimal to binary

21:27 durka42: ,(Integer/toBinaryString 532)

21:27 clojurebot: "1000010100"

21:27 Mec: thanks

21:31 pjstadig: www.clabango.com

21:31 p_l: >_>

21:32 cmvkk_: excellent.

21:32 hiredman: haha

21:32 jhawk28: what is clabango?

21:33 ,(Math/pow 3 4)

21:33 clojurebot: 81.0

21:34 hiredman: clojurebot: do you have a surprise for me?

21:34 clojurebot: CLABANGO!

21:34 cmvkk_: it's a clojure program that turns lead into gold.

21:34 or at least that's what i assume judging by the hype.

21:34 jhawk28: creates your own custom social networking site for people who love clicking ads?

21:35 Mec: which is basically turning the internets into gold instead of lead

21:36 jhawk28: indirect payment, indirect taxes, what is next?

21:36 Mec: hmm what symbol represents the last repl value?

21:37 i sware i saw it on the site and cant find it again

21:37 jhawk28: *1

21:37 ,(*1)

21:37 clojurebot: java.lang.IllegalStateException: Var clojure.core/*1 is unbound.

21:37 jhawk28: *2 is second

21:38 *3 is the third

21:38 Mec: cool thanks

22:03 hiredman: hah

22:03 vimclojure

22:03 all working and good

22:05 new key bindings to learn

22:22 ;)

22:57 durka42: hmm, looking at Nu

22:57 how many languages can i use without leaving the land of the parens? :)

22:59 p_l: durka42: somewhere around infinity

23:01 Mec: anyone ever used scite and know if it's possible to set up a repl with it?

23:03 jcrites: how well does clojure support building a project into a jar for deployment?

23:04 at one point in the past it didn't very well, but i've heard it's gotten a lot better since then

23:07 hiredman: a jar is just a zipfile

23:07 is their something more specific you are looking for?

23:08 there

23:09 Mec: when using arity to add a counter type is it better to use recur?

23:10 hiredman: eh?

23:10 Mec: (defn f ([a] (f a 0)) ([a counter] ...))

23:11 maybe better to use loop.. hmm

23:11 hiredman: recur recurs with in the the method

23:11 Chouser: Mec: early on I teneded to do that, now I'm more likely to use a loop

23:11 hiredman: so recur in the on arity version will recur to the one arity version

23:12 Mec: really?

23:12 Chouser: ya that observation just came to me

23:12 hiredman: Chouser: for what reason?

23:12 Chouser: having the other arity leaks an internal detail to the public api -- someone could call with a counter value and get unexpected results.

23:12 hiredman: I see

23:13 Chouser: maybe not likely, but what's the benefit? *shrug*

23:13 Mec: true enough

23:13 and loop does remove the necessity for arity, so wins all around

23:13 but i find it interesting if recur will not match arity... must test

23:14 wow it does, i'd never have guessed, i'd just have been confused by that error

23:14 Chouser: Mec: what do you mean?

23:15 Mec: ,(defn f ([a] (recur [a 0])) ([a b] b))

23:15 clojurebot: DENIED

23:15 Mec: java.lang.Exception: Unable to resolve symbol: f in this context (NO_SOURCE_FILE:0)

23:15 err wrong one

23:15 java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 2 (NO_SOURCE_FILE:86)

23:16 Chouser: ,(fn f ([a] (recur [a 0])) ([a b] b))

23:16 clojurebot: #<sandbox\$eval__1590\$f__1592 sandbox\$eval__1590\$f__1592@74c144>

23:16 Chouser: ,(fn f ([a] (recur a 0)) ([a b] b))

23:16 clojurebot: java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 2

23:16 Chouser: there it is. :-)

23:16 jcrites: hiredman: I suppose I am specifically looking for classfile generation for all my code, and building it into a jar for deployment

23:17 I mean, with regards to "what I am looking for" I just mean packing my code up for deployment like I do with Java... I don't have to think much about the specifics of how that works when using a relatively high-level build system, so I am not sure what to ask for :)

23:19 hiredman: jcrites: clojure's jar file has a build.xml with an ant task for compiling .clj files

23:21 if you like high level tools, now is he time to write them

23:21 jcrites: heh

23:21 I suppose I don't actually need for it to be precompiled, as long as I have a jar which appears and works like an executable... do you recommend I compile?

23:22 (assuming I don't depend on it like a library, for example)

23:22 a java executable that is

23:22 dreish: ,(Integer/toString 102 26)

23:22 clojurebot: "3o"

23:25 arohner_: jcrites: if you don't compile, you'll need the clojure.jar to run them

23:26 Chouser: you'll need that even if you do compile.

23:26 arohner_: I would recommend you compile. It's not that bad

23:26 oh, right

23:28 Chouser: you might be able to leave out some classes, like Compiler*, when it's compiled... but I'm not sure how well that would go.

23:29 jcrites: oic. deploying clojure.jar with my application is fine, I think

23:29 thanks for the help.. I will try some things out

23:29 arohner_: Chouser: if you leave out Compiler*, can you still eval?

23:29 Chouser: no

23:29 arohner_: so that means no repl too

23:30 hiredman: you can also fold clojure.jar into your jar

23:41 * Raynes folds his Clojure.jar and neatly places it in his sock drawer.

23:42 Raynes: I place all libraries including Clojure.jar in a library folder beside the jar.

23:44 Stu should have hosted his book on his website for free like Real World Haskell does. He then could proceed to flip Brian O' Sullivan off and smoke a huge cigar.

23:46 hiredman: ~/.jars

23:46 clojurebot: excusez-moi

23:46 cooldude227: lol

23:47 so who's using maven with clojure?

23:48 Raynes: cooldude227: You are.

23:52 Guest46760: ,(time (reduce + (map * (range 100) (repeat 1))))

23:52 clojurebot: 4950

23:52 "Elapsed time: 1.019 msecs"

23:52 Guest46760: ,(time (reduce unchecked-add (map unchecked-multiply (range 100) (repeat 1))))

23:52 clojurebot: 4950

23:52 "Elapsed time: 26.5 msecs"

23:52 cooldude227: Raynes: actually, i'm not at the moment

23:53 i just installed it for some java stuff tho

23:53 Guest46760: thought the unchecked stuff was supposed to be faster?

23:53 cooldude227: Guest46760: you would think. that's bizarre

23:55 Chouser: it's the boxing and unboxing that's killing you there, I think.

23:56 cp2: wow, after not writing in java for a while im starting to notice that it is severely lacking compared to clojure :)

23:56 Guest46760: Chouser: yeah. i was wondering if maybe it needs type hinting.

23:56 cooldude227: i don't know if you can fix the boxing problem. clojure doesn't usually do primitives like that

23:56 Chouser: if you want fast math, don't use the seq abstration

23:57 Guest46760: Chouser: what would i use to avoid it?

23:57 cooldude227: you can't have primitive function args, they'll get boxed, cuz IFn has objects as the arguments to invoke

23:57 Chouser: use something that can deal with primitives, like loop/recur and locals.

23:58 Guest46760: Chouser: k. i'll look into it. thx.

23:59 arohner_: Guest46760: you can also use the java array operations

Logging service provided by n01se.net