#clojure log - Jun 11 2010

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

0:24 dnolen: anyone have example of type-hinting deftype methods?

0:31 mmarczyk: (deftype Foo [x] Object (^boolean equals [self ^Object other] true))

0:31 (.equals (Foo. 5) true) => true

0:32 technomancy: who wants a generic hook function extension system?

0:32 anybody? http://p.hagelb.org/hooke-readme.html

0:34 mmarczyk: I definitely want a hook extension system named after Robert Hooke

0:35 dnolen: marczyk: hm, I keep running into issues where it doesn't it complains about the method if I've defined a protocol

0:35 technomancy: sold! to the guy with the orange nick (in my client) http://p.hagelb.org/hooke.clj.html

0:36 mmarczyk: no idea what colour nick I've got in your client, but thanks :-)

0:37 I think I'll have a use for that in a little while too, so that's pretty cool :-)

0:37 technomancy: oh?

0:37 cemerick: mmarczyk: sent in your CA yet? :-)

0:38 mmarczyk: cemerick: heh, thanks for asking :-)

0:39 cemerick: will do today, it's printed and just waiting for me to go to the post office

0:39 cemerick: mmarczyk: good, I'll only have to pester you once more ;-)

0:39 mmarczyk: cemerick: right :-)))

0:39 incidentally, any thoughts on whether I should include non-ascii chars or skipt them?

0:39 rava: anyone know of a decent looking gui kit i can use for clojure?

0:40 mmarczyk: I've decided to skip, but if it's a problem, could make another version...

0:40 rava: swing is so very difficult to make look decent

0:40 cemerick: rava: SWT is really the only other option

0:40 mmarczyk: non-ascii for what?

0:40 mmarczyk: technomancy: if you're asking what sort of use for R. Hooke I had in mind, I'm not very clear on how the thing I can see using it work will work yet, so hard to summarise

0:41 technomancy: I'll be sure to let you know when/if I do use it though :-)

0:41 cemerick: there's one non-ascii letter in my first name and a couple in the mailing address

0:41 the address is not a problem, it's perfectly normal to skip those

0:41 cemerick: mmarczyk: oh, leave them in, make it proper

0:41 tomoj: so the metadata on the function has a ::hooks key which holds a list of hook fns?

0:41 cemerick: legal document, after all

0:42 mmarczyk: right, though on the other hand, I've produced a number of legal documents in pure-ascii form

0:42 I believe my bank cards are pure-ascii too, Google wanted pure ascii for GSoC...

0:42 wouldn't want to make processing overly complex (and therefore I'm making it overly complex for me right now :-P)

0:43 technomancy: tomoj: yeah

0:43 limits it to 1.2+ unfortunately

0:43 cemerick: Rich is doing the only processing, so *shrug*

0:43 technomancy: but hey, it's only 23 lines.

0:43 mmarczyk: yeah, I guess I can always send another one if it matters somehow

0:44 tomoj: hmm.. the bicycle and the tricycle. I approve.

0:44 rava: saw these in a best in class blog: http://code.google.com/p/macwidgets/

0:45 dnolen: hmm so the the type hints have to be on the protocol?

0:45 cemerick: rava: those are swing AFAIK :-)

0:46 plus some OS X-specific client properties

0:46 rava: cemerick: yes, but the prettyness work done for me :D

0:46 cemerick: right

0:46 well, I was assuming you were aiming for cross-platform :-)

0:46 technomancy: would renaming add-hook to add-hooke be too cute?

0:47 cemerick: heh

0:47 technomancy: probably

0:47 cemerick: technomancy: reminds me of wall-hack-*

0:47 rava: cemerick: those do render across platforms

0:47 cemerick: rava: oh, sure, but....stick out like a sore thumb elsewhere, no?

0:48 I mean iTunes on Windows is there, but sorta awful.

0:48 rava: cemerick: meh, i don't care about looking like a native app

0:48 cemerick: fair 'nuff then

0:49 rava: windows native = fugly anyway

0:56 ysph: did lazy-xml/emit and emit-element move into clojure.xml in 1.2?

1:01 tomoj: clojure.xml has emit and emit-element in 1.2, at least

1:08 ysph: it has before, but there were some issues that weren't present in lazy-xml/emit and emit-element, so i wonder if they were consolidated

1:09 tomoj: looks like not

1:09 last changes to emit and emit-element in clojure.xml were in 2008

1:10 technomancy: the function that's like remove but takes an element instead of a pred is in contrib rather than core, right?

1:12 mmarczyk: in case anybody wants to play with a Turing machine, http://github.com/michalmarczyk/turing-machines

1:56 technomancy: http://github.com/technomancy/robert-hooke

2:03 Lajla: $(apply append (map #(append %1 " ") (list "I" "worship" "his" "shadow"))

2:03 sexpbot: java.lang.Exception: EOF while reading

2:04 Lajla: $(apply append (map #(append %1 " ") (list "I" "worship" "his" "shadow")))

2:04 sexpbot: java.lang.Exception: Unable to resolve symbol: append in this context

2:13 jrp: Im looking around at getting started with clojure and os x. Is there a prefered way to get it working with vim? Ive found a few vim scripts, and Im wondering what people prefer.

2:16 imran_sr: jrp: I use syntax highlighting, indenting and rainbow parens from vimclojure (but not the nailgun repl), and I use my own vimscript to send whatever I like to a repl (current line, current expression, function, entire buffer, (doc <this word), whatever). And I keep vim and the repl side by side in a vert split gnu screen

2:16 whew, thats it :)

2:17 tomoj: Lajla: maybe you're looking for clojure.contrib.str-utils/str-join ?

2:17 jrp: hm, ok. ill give that a shot. I tried slimv but it was a bit problematic

2:17 Lajla: $(apply join (map #(join %1 " ") (list "I" "worship" "his" "shadow")))

2:17 sexpbot: java.lang.Exception: Unable to resolve symbol: join in this context

2:17 Lajla: I give up

2:17 tomoj, you do it

2:17 Outperform me

2:17 Be the third best programmer after me and Bill.

2:18 tomoj: somebody already did it

2:18 and it's in contrib :)

2:19 hoeck: ,(apply str (interpose " " ["I" "worship" "his" "shadow"]))

2:19 clojurebot: "I worship his shadow"

2:19 imran_sr: jrp: I found the idea (for vimscript to repl communication) here : http://technotales.wordpress.com/2007/10/03/like-slime-for-vim/

2:19 jrp: there you'll find a simple slime.vim

2:20 jrp: I rewrote my own version, for additional functionality (plus it now works with latest gnu-screen from git)

2:20 jrp: but if you don't use gnu-screen, it won't really help you :(

2:25 Lajla: tomoj, you worship my shadow eh?

2:25 tomoj, also, your function does a different thing

2:25 Mine ends on a space, yours doesn't.

2:26 jrp: imran_sr: I do use a bit of screen, perhaps I should use more

2:26 tomoj: Lajla: my function?

2:26 imran_sr: jrp: best thing since sliced bread :)

2:26 Lajla: erhh, hoecks.

2:26 I misread.

2:26 tomoj, will you ever be able to forgive me for my errings?

2:27 tomoj: like this, then?

2:27 ,(#(apply str (interleave %2 (repeat %1))) " " ["I" "worship" "his" "shadow"])

2:27 clojurebot: "I worship his shadow "

2:28 hiredman: ,(doc interpose)

2:28 clojurebot: "([sep coll]); Returns a lazy seq of the elements of coll separated by sep"

2:30 hoeck: Lajla: not ending in whitespace was intended :)

2:30 Lajla: hoeck, my shadow ends with blackspace.

2:30 * Lajla hugs hoeck.

2:31 hoeck: ,(apply str (interleave ["I" "worship" "his" "shadow"] (repeat " ")))

2:31 clojurebot: "I worship his shadow "

2:31 hoeck: interleave, interpose, I love them! :P

2:31 Lajla: I want to map over it.

2:32 I worship His Divine Map.

2:51 LauJensen: Good morning all

2:52 vIkSiT: hey LauJensen

2:55 hmm, in Clojure - how do you handle the class paradigm, with a bunch of local variables that are bound to it?

2:56 tomoj: bound to what?

2:56 a class?

2:56 vIkSiT: yes

2:56 tomoj: I certainly don't understand you

2:57 vIkSiT: well, so lets assume I have a stack class

2:57 tomoj: ,(let [x java.lang.String] x)

2:57 clojurebot: java.lang.String

2:57 tomoj: x is bound to String

2:57 KirinDave: vIkSiT: If you have something where it makes sense to tightly encapsulate the behavior that way

2:57 vIkSiT: this contains say, 3 variables - a, b, and c. and 3 methods: push, pop and peek.

2:57 KirinDave: vIkSiT: Then these days you'd use deftype and a stack protocol (along with other collection interfaces)

2:57 vIkSiT: hmm

2:57 KirinDave: vIkSiT: But clojure prefers you don't clutter the world with superfluous ontologies

2:58 tomoj: :D

2:58 KirinDave: Clojure is verb oriented.

2:58 vIkSiT: KirinDave, yes I understand how to use protocols, multimethods and deftypes

2:58 the question is - how does Clojure allow me to use verbs to define the same relationships?

2:59 LauJensen: protocols, namespaces, hash-maps can all be used in some way to bundle behavior

2:59 KirinDave: vIkSiT: (pop stack), (push stack item), (count stack). And a namespace. Do you need more?

2:59 vIkSiT: LauJensen, hmm, you mean using a hash map to store variable info. hmm

3:00 could use that

3:00 KirinDave: vIkSiT: It may seem a little loosely bound if you're not used to it, but consider the monad library for a good example of how an opaque namespace can give the illusion of a unified interface if you don't know the details.

3:00 LauJensen: vIkSiT: When Clojure first came out, people basically substituted objects with hash-maps, which was why Rich had to rush to implement it, otherwise people wouldnt try Clojure :)

3:00 KirinDave: You said 'monad', now I have to ban you from the community

3:00 KirinDave: LauJensen: Why?

3:01 LauJensen: They're that terrible :)

3:01 vIkSiT: KirinDave, thanks, let me check it out

3:01 LauJensen, heh I can imagine

3:01 KirinDave: Monads are fantastically useful in a few limited situations. Those situations are rare.

3:01 LauJensen: KirinDave: And they all exist in Haskell

3:01 tomoj: in clojure, you mean?

3:01 vIkSiT: KirinDave, any pointers to code here? http://bitbucket.org/kotarak/monad

3:01 tomoj: rare in clojure, you mean?, I mean

3:01 KirinDave: vIkSiT: Just read the docs to the contrib monad library

3:01 tomoj: No, rare in life. You can use them to solve other things

3:01 But you shouldn't.

3:02 Raynes: LauJensen: You're a Haskell hater?

3:02 :<

3:02 LauJensen: Raynes: Im a Haskell lover :)

3:02 vIkSiT: hmmm. I see. So substitute a namespace for a class scope

3:02 KirinDave: LauJensen: I'm confused.

3:02 mmarczyk: morning

3:03 Raynes: I'm confused.

3:03 KirinDave: LauJensen: btw thanks for open sourcing your blog.

3:03 LauJensen: I just dislike monads - Primarily because they are a way of hiding state, not handling it. Which is why Clojure is already more popular because it provides a uniform solution to the state problem. And secondly, the name is just so uuuugly.

3:03 KirinDave: You're welcome

3:03 KirinDave: LauJensen: They're great for implementing some specific things though. As a component for a parser for example.

3:03 mmarczyk: I need to have the KirinDave / LauJensen two lines on monads and Haskell on a t-shirt

3:03 KirinDave: And the maybe monad is pretty much universally useful.

3:03 Even in my ruby days I pretended I had it with ||= chaining.

3:04 LauJensen: hehe

3:04 brehaut: KirinDave: so is the list monad, though we call it for ;)

3:04 mmarczyk: ah, but monads are not only for dealing with state

3:04 KirinDave: LauJensen: I bought http://fayr.am

3:04 LauJensen: Which is my last name

3:04 LauJensen: I figure that's a good place to host a blog.

3:04 mmarczyk: I prefer to think of them as a means of adding complex behaviour to function composition

3:04 LauJensen: Yea why wouldnt it be?

3:05 KirinDave: Too bad my middle name isn't http://

3:05 LauJensen: mmarczyk: I think per definition, Scala is a means of adding complex behavior to function composition :)

3:05 KirinDave: Yea that would have been sweet

3:05 KirinDave: ha

3:05 LauJensen: KirinDave: My only regret, is that my blog is married to nginx

3:05 KirinDave: Man I cannot wait for prim to go into main.

3:05 LauJensen: I might make a teepeedee2 branch :)

3:06 mmarczyk: LauJensen: it certainly appears so from the syntax :-)

3:06 brehaut: LauJensen: whats the problem with nginx?

3:07 KirinDave: brehaut: It's a sort of pain of the ass for a small installation.

3:07 jrp: imran_sr: are you still around? Im trying to get slime.vim working, and wondering what sort of modifications I need to make

3:07 LauJensen: brehaut: No problem, its fantastic. I just didnt want the blog to be married to it. And I think teepeedee2 has 2 advantages: 1) serves 6500 customers per second, 2) written in Lisp

3:07 brehaut: KirinDave: oh really? i was looking at using it when ive rebuilt my site

3:07 KirinDave: Hmm.

3:08 LauJensen: KirinDave: ?!

3:08 A pain?

3:08 Its quite the opposite

3:08 KirinDave: LauJensen: Not in my experience.

3:08 LauJensen: Apache is like that elefant which everybody tries to bring to every party

3:08 KirinDave: LauJensen: I'm not advocating apache

3:08 LauJensen: (I know I know, only Raynes actually bring elephants to parties)

3:08 KirinDave: Hum, what lens to rent for this architectural shoot?

3:09 LauJensen: Ok - I just find nginx to be very lean and clean, easy to set up and runs completely problem free

3:09 brehaut: ive been tossing up between lighty and nginx

3:09 KirinDave: 24mm tiltshift

3:09 LauJensen: Ive never had to restart or anything

3:09 KirinDave: or 14-24mm?

3:09 LauJensen: http://github.com/vii/teepeedee2

3:14 brehaut: another clojure for web question; how much ram would you expect the JVM to need to operate comfortably for a small (personal scale) site?

3:14 imran_sr: jrp: sorry, was away. If you using the latest gnu-screen (I don't know what version your linux distro has packaged for you, but I build from git sources), then I would suggest that you dump the way the original slime.vim was communicating with screen

3:15 Instead, try this: write text to a file -> read it into a screen register -> dump register to stdin of desired screen window

3:16 I really ought to cleanup my vimscript, and put it online.

3:16 jrp: i dont think I am

3:16 yeah, Im using a version from oct 06

3:16 apparently

3:16 imran_sr: ok, so if you look at slime.vim from that webpage I posted

3:16 jrp: yep, got it installed

3:17 imran_sr: its basically doing this (to send text from vim to screen)

3:17 jrp: do I need to modify the -X stuff part?

3:17 imran_sr: text -> escape awkward chars -> inserting into it a screen stuff command -> run screen stuff

3:17 jrp: yep

3:17 imran_sr: I changed the method of communicating with screen to instead do this: write text to a file -> read it into a screen register -> dump register to stdin of desired screen window

3:17 that works flawlessly

3:18 KirinDave: Hm, I'm trying to decide if http://twelvesouth.com/products/bookbook/ is awesome or tacky.

3:18 imran_sr: jrp: but without cleaning up my own slime.vim, I'm not helping you much :(

3:18 KirinDave: I have a http://www.dodocase.com/ and its totally awesome (and not tacky)

3:19 But the bookbook is a little more ostentatious.

3:21 vIkSiT: hmm, what does a (def +something+ 3) imply?

3:21 a local variable?

3:22 brehaut: vIkSiT: yes http://clojure.org/vars

3:22 KirinDave: vIkSiT: It's a var in the current scope.

3:22 imran_sr: jrp: tell you what. I can send you my slime.vim as it is. You just have to pop it into ~/.vim/plugin/, and try it out.

3:22 LauJensen: imran_sr: That depends on how much the app consumes. If you have an app that at any point holds 350Mb in memory, then you need more than that. If its just for simple interfaces run on a Jetty servlet, then 128mb should be fine. But there's no answer that fits all. So far Best In Class is doing _quite_ well with 256m

3:22 vIkSiT: ah

3:22 thanks

3:22 brehaut: vIkSiT: 'local' variables are normally defined with let forms

3:22 vIkSiT: ah right..

3:23 KirinDave: vIkSiT: Let me confuse you even more: vars are mutable by assignment. :)

3:23 vIkSiT: this would be in the current ns, I believe

3:23 bartj: er, is it possible to use back-references for regular expressions in Clojure ala Perl, etc?

3:23 imran_sr: oh well

3:24 brehaut: bartj: its anything you can do with a normal java regexp

3:24 vIkSiT: KirinDave, well, they're thread-local right?

3:24 KirinDave: vIkSiT: yes.

3:24 vIkSiT: Well, generally they are.

3:25 brehaut: bartj: http://www.regular-expressions.info/java.html

3:26 jrp: imran_sr: there we go, im very sorry. Could you paste whatever you said from when you were explaining how slime.vim work until now?

3:27 vIkSiT: LauJensen, re your statement about using maps to store variable information

3:27 can such maps/structs be made part of a protocol?

3:28 LauJensen: vIkSiT: Yea I suppose they can be wrapped, though Im not sure if there's any idiomatic support for doing it yet

3:28 vIkSiT: hmm..

3:29 would you have pointers on something that does this?

3:29 or actually - here's what I'm trying to do

3:29 imperatively, I'd have a class called Tuple, that would have a map as a local variable, and a few supporting methods that act on it

3:30 so each tuple would carry its instance of the map

3:30 brehaut: vIkSiT: instead of having a class or type contain the map, just pass the map around

3:31 vIkSiT: brehaut, hmm, as in?

3:31 brehaut: say i have a blog post with a title, a description and a timestamp

3:31 instaed of defining a type

3:31 tomoj: what do Tuples do that vectors don't?

3:32 vIkSiT: tomoj, this is a database tuple btw. not a pair class..

3:32 LauJensen: vIkSiT: To me it sounds like the description of a standard protocol

3:32 tomoj: oh, I see

3:32 so a Tuple is a mapping from field names to values?

3:32 brehaut: id just create a new hash map say {:title "frobtz" :description "foo bar baz" :timestamp "2010.06.10"}

3:32 tomoj: yeah.. :)

3:33 vIkSiT: tomoj, yeap..

3:33 * vIkSiT is implementing a toy rdbms in cloure

3:33 vIkSiT: .. or trying to anyway.

3:33 brehaut: vIkSiT: a basic toy rdbms would have tables that are sets of vectors

3:34 LauJensen: (defrecord tuple [x y z]) (defprotocol Ptuple (add []) (remove [])) instantiate it with the maps data, and thats it ?

3:34 vIkSiT: brehaut, well almost. a tuple looks like : [(field1, type) , (field2, type).. ]

3:34 brehaut: vIkSiT: then a set of maps ;)

3:34 vIkSiT: LauJensen, aah yes.

3:35 hmm I think a vector of maps, yeap :)

3:35 brehaut: vIkSiT: typically a relational DB doesnt allow duplicate records in the table ;) but sure

3:36 bartj: brehaut: thanks,

3:36 vIkSiT: brehaut, ah this is the schema representation of the table..

3:36 brehaut: vIkSiT: ah right

3:36 bartj: brehaut: though, I am not able to find the difference between re-find and re-seq

3:36 vIkSiT: the records, yes I agree

3:36 bartj: brehaut: since both return sequence of the matches!

3:37 LauJensen: bartj: one is lazy the other isnt

3:37 tomoj: re-find shouldn't return a sequence..

3:38 LauJensen: $(re-find #"[1-9]" "abc 1 2 3 def 2")

3:38 tomoj: ,((juxt re-find re-seq) #"foo" "foobarfoo")

3:38 sexpbot: => "1"

3:38 clojurebot: ["foo" ("foo" "foo")]

3:38 LauJensen: $(re-seq #"[1-9]" "abc 1 2 3 def 2")

3:38 sexpbot: => ("1" "2" "3" "2")

3:38 LauJensen: tomoj: clever demo

3:44 bartj: LauJensen: thanks

3:44 while trying to find the "domain-name" of a URL, I came up with this:

3:45 , (nth (re-find #"(https?://)?(www\.)?([^/]+)(.*?)" "http://www.spr-ufo.ru/hanti-mansiysk-g/irtish-servis-zao.html") 3)

3:45 clojurebot: "spr-ufo.ru"

3:45 tomoj: seems seq is 2x faster in prim

3:46 bartj: not sure, if re-seq (or anything better) would be preferable

3:46 LauJensen: clojurebot: regex?

3:46 clojurebot: Sometimes people have a problem, and decide to solve it with regular expressions. Now they have two problems.

3:46 vu3rdd: :-)

3:47 tomoj: ,(.getHost (java.net.URL. "http://www.spr-ufo.ru/hanti-mansiysk-g/irtish-servis-zao.html"))

3:47 clojurebot: "www.spr-ufo.ru"

3:47 tomoj: part of the way there

3:48 getting only the domain name would require a tld list, wouldn't it?

3:49 err

3:49 I mean the second-level domains like co.uk cause trouble

3:53 LauJensen: Odd that java.net.URL doesnt support that

3:54 brehaut: is there a function like concat that joins to vectors?

3:55 LauJensen: conj you mean ?

3:55 brehaut: i dont think so?

3:55 tomoj: that would be O(n), you OK with that?

3:55 LauJensen: you dont?

3:56 $(-> (.split "http://www.spr-ufo.ru/hanti-mansiysk-g/irtish-servis-zao.html" "\\.") (nth 1))

3:56 sexpbot: => "spr-ufo"

3:56 brehaut: LauJensen: if i conj a vector onto a vector, the result will be the first vec with the second as the last elem

3:56 LauJensen: oh, you want a flat sequence ?

3:56 brehaut: yeah

3:57 LauJensen: $(into [1 2 3] [4 5 6])

3:57 sexpbot: => [1 2 3 4 5 6]

3:57 brehaut: cheers

3:57 tomoj: does that use InternalReduce now?

3:58 oh, it will use a transient I guess

4:01 AND InternalReduce

4:02 HerrBlume: $(concat [1 2 3] [4 5 6])

4:02 sexpbot: => (1 2 3 4 5 6)

4:03 Raynes: concat returns a lazyseq.

4:03 HerrBlume: ah ok

4:03 Raynes: That particular application of into returns a vector.

4:03 bartj: LauJensen: that doesn't get the '.ru' extension, no?

4:03 Raynes: Returns whatever it's first argument is.

4:03 HerrBlume: $(into (list 1 2 3) (list 4 5 6))

4:03 sexpbot: => (6 5 4 1 2 3)

4:06 bartj: , (.getHost (java.net.URL. "http://news.bbc.co.uk/2/hi/business/10290933.stm"))

4:06 clojurebot: "news.bbc.co.uk"

4:07 bartj: tomoj: apparently the second-level domains, don't cause any trouble?

4:07 tomoj: but you've still got the subdomain there

4:07 bartj: tomj: I don't understand?

4:07 LauJensen: bartj: No its a bit of a hack, it just splits the string on periods and picks out the 2nd match. It only gets the second match, and will break if the www. isnt there

4:07 tomoj: I thought you wanted only "bbc.co.uk"

4:09 bartj: tomoj: no, that's ok - the complete domain would do

4:09 tomoj: you still get the "www" though

4:10 if you don't mind that, then yeah, no problem

4:12 wonder why protocol fns don't get :file and :line metadata

4:14 LauJensen: hmm, sure they dont?

4:15 tomoj: well, my clojure.core.protocols/internal-reduce didn't, anyway

4:15 I'm not sure swank-clojure could deal with it even if they did, but it would be at least one step closer M-. on protocol fns

4:15 s.closer.closer to.

4:46 Borkdude: Why doesn't (find-first even? (repeat (rand-int 10))) terminate?

4:47 tomoj: ,(take 5 (repeat (rand-int 10)))

4:47 clojurebot: (3 3 3 3 3)

4:47 tomoj: ,(take 5 (repeatedly #(rand-int 10)))

4:47 clojurebot: (3 5 2 2 6)

4:49 Raynes: ,(rseq [1 2 3])

4:49 clojurebot: (3 2 1)

4:49 tomoj: why not just (* (rand-int 5) 2), though?

4:50 Borkdude: tomoj, that's also possible, but I was just wondering

4:51 why it doesn't terminate

4:51 tomoj: still wondering?

4:51 Raynes: $(take 10 (repeat (rand-int 10)))

4:51 sexpbot: => (0 0 0 0 0 0 0 0 0 0)

4:51 Raynes: It doesn't terminate because you aren't calling the function over and over again, you're repeating it's first result over and over again.

4:51 tomoj: it will sometimes terminate :)

4:52 Raynes: Use his repeatedly example, Borkdude.

4:52 LauJensen: or the force... both can sway the results

4:53 tomoj: repeat is a function, so (rand-int 10) is first evaluated, then the result is passed to repeat

4:53 Borkdude: hmm, ok, yes

4:53 of course

4:55 * Raynes is updating sexpbot's deps.

6:20 vu3rdd: Is it okay to assume that #^ is deprecated for >= 1.2 and ^ is the new meta (and hence type-hint) reader syntax?

6:27 Chousuke: yes

6:52 octe: i'm trying to have a reference to a function in a map and call it dynamically, but i can't seem to get it work. this is what i have: http://paste.lisp.org/display/111346

6:59 raek: octe: remove the quote before file-data-collector

7:00 octe: raek, that seems to evaluate the value of the key in the map when defining the *data-collectors* map

7:00 raek: *data-collectors* contains a map with entry, which key is "file" and value _the symbol_ file-data-collector

7:00 octe: uh.. or maybe not

7:01 raek: yes, you would want to evaluate file-data-collector to get the function that it represents

7:01 so that the value of the map entry is the function itself

7:01 MrHus: octe: (def *data-collectors* {"file" file-data-collector}) without the quote works for me

7:02 raek: ,(let [foo {:my-fn (fn [x] (* x x))}] ((:my-fn foo) 5))

7:02 clojurebot: 25

7:03 raek: also, it's common to use keywords as keys for maps

7:04 two keywords with the same name are guaranteed to be the same instance

7:05 so even though the keyword :my-fn may occur 1000 times in the code, all uses referes to the same object

7:06 octe: raek, can i make a string into a keyword?

7:06 raek: yes

7:06 octe: because i will be looking it up by string..

7:07 raek: just use (keyword "the-string")

7:07 beware of strings with spaces in, though

7:07 octe: ah

7:07 raek, i found why i didn't think it was evaulating at lookup-time

7:07 raek: they will not print correctly: (keyword "foo bar") => :foo bar

7:08 octe: if i recreate (re-bind? re-evauluate?) the file-data-collector fn i need to also re-avulate the (def *data-collectors*

7:08 to update the reference i guess

7:08 raek: ah, yes

7:08 you can then write #'file-data-collector instead of file-data-collector

7:09 this stores the var that the was bound to the function rather than the function itself

7:09 octe: ah, thanks. what does that actually do? (fn [] 'file-data-collector)

7:09 raek: fn is lambda

7:09 octe: i thought # was a reader-macro of some sort for fn

7:09 raek: yes, when followed by a paren :)

7:10 #'foo => (var foo)

7:10 pronounced "var quote"

7:10 when a var is used as the function in a function application, it firsts looks up the value of the var and uses that instead

7:11 so vars containing functions can be used as functions

7:11 octe: ah, ok

7:11 raek: ,#'inc

7:11 clojurebot: #'clojure.core/inc

7:11 raek: ,(inc 1)

7:11 clojurebot: 2

7:11 octe: these special things are nice, but hard to google for :)

7:11 raek: ,(#'inc 1)

7:11 clojurebot: 2

7:12 raek: var-quote is often used when you want to store redefinable functions in data structures, like in your case

7:12 you only need to do this in data, though

7:13 in code, the vars are always used

7:16 octe: thanks, raek

7:22 tomoj: I guess that's why invoking a var invokes the function it's bound to?

7:23 raek: probably a convenience feature

7:23 ior3k: hey everyone

7:23 raek: so one doesn't have to use deref

7:23 Chousuke: I don't think there's much else that a var could reasonably do when invoked

7:24 ior3k: I'm a freelancer, and I'd like to start using clojure on my work

7:24 tomoj: good point

7:24 ior3k: but I'm not exactly sure how to convince my clients about that

7:24 anyone has thoughts on this?

7:24 rsynnott: ior3k: what do you currently use in your work?

7:24 ior3k: ruby, mostly

7:25 but I have experience with several languages

7:25 tomoj: too bad you didn't say 'java'

7:25 Chousuke: ior3k: you could try telling them you're just using java library ;P

7:25 rsynnott: tomoj: yeah, that's what I was thinking

7:25 ior3k: that's not the same though

7:25 one thing is a java lib

7:25 the other is a completely different language

7:25 if for some reason, someone else needs to look at the code

7:26 rsynnott: though if you used jruby, and then say, "ooh, look, I can do X thing a hundred times faster, but only if I write it in this scary devil-language"

7:26 (write that section in)

7:26 tomoj: if random other people are going to have to look at the code, clojure sounds like a bad idea to me

7:26 ior3k: well, I guess jruby is one step in the right direction, that's for sure

7:26 rsynnott: ior3k: in general, using exotic languages for things where the client gets the source is often difficult

7:26 ior3k: yeah, you never really know when that's going to happen,

7:27 rsynnott: (if you just give them the binary, you can use whatever you feel like, of course)

7:27 ior3k: I guess I could always ask them if they have a language preference

7:27 but most do

7:28 Raynes: It's too bad that most of them don't know the difference between Clojure and COBOL.

7:28 ior3k: hehe, they shouldn't have to

7:28 Raynes: "I herd Java is pop u lur."

7:28 ior3k: but using an unknown language is quite a risk for them

7:28 if I get hit by a bus

7:28 they will have trouble finding someone else to maintain the app

7:29 Raynes: ior3k: Get an Iron Man suit, and give them your personal I'll-never-die guarantee.

7:29 ;)

7:29 ior3k: hahaha

7:29 * rsynnott was one of three erlang people in a company heavily dependent on an erlang app at one point

7:29 ior3k: I wish

7:29 rsynnott: two of us left more or less at once :S

7:29 ior3k: yeah, that's really not a position I want to put my clients in

7:30 even though I'd love to be able to use clojure

7:30 I just love lisp :)

7:30 Raynes: One day.

7:31 rsynnott: there does seem to be a general trend towards non-Java languages on JVM

7:31 ior3k: yeah

7:31 rsynnott: (and non C# languages on .NET, for that matter, though that platform's slightly more of a niche)

7:31 Raynes: ior3k: Just think: somewhere, in an alternate universe, you're rocking Clojure all over your clients because Java died in the late 90s.

7:31 ior3k: hehe

7:31 well, it's true that clojure still allows you to use several java libs

7:31 rsynnott: Raynes: it would hardly be clojure, if not for the JVM, surely?

7:32 ior3k: and therefore be more productive

7:32 Raynes: rsynnott: I said "java died".

7:32 Implying other languages took it's place.

7:32 rsynnott: I doubt that exactly the same design decisions would have been taken if the JVM wasn't the target

7:32 ah

7:32 I thought you meant just java died in general

7:32 Raynes: Maybe Rich is older in this universe, or decided to create Clojure earlier in his life.

7:32 rsynnott: (which would presumably mean Sun would never have bothered with proper JIT)

7:33 ior3k: to be honest, I'm not really fond of using java libs in clojure

7:33 Raynes: I don't really have to do that much anymore.

7:33 ior3k: using a non functional black box in a functional language

7:33 feels weird

7:34 so you think it's getting to a point where there is enough native/wrapped stuff?

7:34 Raynes: ^^^

7:35 Raynes: ior3k: Either that, or I just don't do enough specific stuff to have to use Java libs.

7:35 Besides the standard libs, of course.

7:36 ior3k: oh well

7:36 thank you everyone for your thoughts

7:50 rsynnott: it is nice having access to them, though :)

7:50 with the possible exception of Objective C/C, Clojure/Java interaction is about the nicest interaction between two languages I'v used

7:53 Licenser: why is it that I have the feeling that the lisp comunities hobby is to rant on over every lisp but what they find the best?

7:54 tomoj: seems like there's plenty of ranting about the lisp they like as well :)

7:54 Chousuke: rsynnott: I wouldn't count ObjectiveC as "integrated" with C. it IS C, with a bit of syntax for classes and message passing

7:54 Licenser: it is sad, I mean why can't they all work together?

7:55 tomoj: because CL is divinely inspired and we are heretics

7:55 rsynnott: Licenser: in fairness, CL and Clojure are _extremely_ different languages

7:56 (CL isn't functional, for instance)

7:56 Chousuke: some CL people are probably a bit peeved that Clojure has generated so much hype

7:57 (most probably aren't though)

7:57 * rsynnott has both CL and Clojure projects :)

7:58 Chousuke: It would be awesome if CL were used as widely as Java is, but I think that's not possible any more :/

7:59 CL has found its niche and seems to have got stuck in it :P

8:00 lpetit: Hi, any maven guru here ?

8:01 Licenser: rsynnott: I'd just hope that people would sit together and make the best out of things

8:01 Chousuke: Licenser: the problem is that people have differing views on what is best

8:02 rsynnott: Licenser: the two languages are useful for different things

8:02 tomoj: problem?

8:02 clojurebot: People have a problem and think "Hey! I'll use a regular expression!". Now they have two problems....

8:02 rsynnott: there's some crossover, of course

8:02 Chousuke: What works best in practice is competition. But it needs to be the friendly kind.

8:02 lpetit: tomoj: There's this cool war:inplace goal. Works great, but ....

8:04 tomoj: I'm working on a webapp. I'm with Eclipse. So I used eclipse:eclipse goal, which sets my project as dependent of other dependency projects in the workspace. That's cool, but ...

8:04 Licenser: Chousuke: but there is little friendly about the competition I think

8:04 Chousuke: I suppose :/

8:05 tomoj: lpetit: wait, I didn't mean to suggest I'm a maven guru, sorry

8:05 rsynnott: Licenser: I've never seen any particular hostility on either side, and there's some overlap in terms of people

8:05 Chousuke: though I think most of the actual active people are ignoring Clojure and just doing stuff :P

8:05 lpetit: tomoj: war:inplace does not know about the eclipse:eclipse configuration, and keeps copying the snapshots of my workspace dependencies in the WEB-INF/lib/ directory. If I forget to remove them manually, when launching my webapp, it's not the code from the other projects that gets used, but the one in WEB-INF/lib

8:05 rsynnott: CL people are often rather cruel about Arc, but that's because it's crap, not because of some vicious competition

8:05 lpetit: tomoj: too late. Know you must answer ! :-)

8:05 tomoj: I do use maven, but none of that stuff :(

8:06 Chousuke: rsynnott: Does anyone still take Arc seriously?

8:06 lpetit: tomoj: maybe you know how to add behaviour after the invocation of some other goal ?

8:06 tomoj: nope

8:06 lpetit: :-(

8:07 rsynnott: Chousuke: did anyone ever?

8:07 Chousuke: rsynnott: maybe

8:07 rsynnott: but it's the only widespead instance I can think of of CL people attacking another language

8:07 _fogus_: rsynnott: I suppose some Lispers view Arc as less than good, but I never saw the hostility as stemming from that point

8:11 I'm no expert, but I always saw the gripe against Arc coming from the fact that pg hyped Lisp, got it to the brink of relevance again, and then abandoned it for Arc.

8:11 Raynes: Licenser: I've had good experiences with the one CLer that I know. I've discussed Clojure with him, he learned stuff from it, and has a pleasant view of it. Although he's persistent in not actually using Clojure, he likes it and is just happy that Lisp of any sort is gaining popularity.

8:12 * rsynnott is unconvinced that there's really that much hostility

8:12 Raynes: There was that loper-os guy, but other than that, I haven't seen much.

8:13 tomoj: where does all this unfriendly stuff happen? in the blogosphere?

8:13 _fogus_: I don't know enough about Arc itself, but many of the complaints against it seem to suggest that its a thin layer over Lisp/Scheme

8:13 Raynes: The comments on that loper dude's post were pretty shockingly hostile as well. Most of them didn't appear to have ever seen much of Clojure, and just wanted to join in with the Clojure hate-fest.

8:13 _fogus_: As for Clojure, there will always be LoperOS guys no matter what, so why worry about it?

8:13 rsynnott: Raynes: which post is this?

8:14 Licenser: well this axis of eval guy was beyond hostile and yes the loperOS guy wasn't nice either

8:14 rsynnott: ah, found it

8:14 _fogus_: I doubt Rich loses much sleep over it

8:14 Raynes: rsynnott: That one. :p

8:14 rsynnott: I don't think either person is actually particularly big in the CL community, though

8:14 tomoj: oh, "Clojure is the False Lisp, which Reeketh of the Cube Farm." hehe

8:15 cemerick: _fogus_: I think people would have been very happy with arc if it had delivered something notable technically. Renaming standard fns was a helluva letdown after all of that (very good) yammering.

8:16 Just* renaming, that is

8:16 * cemerick isn't being very generous :-|

8:16 lpetit: cemerick: you for sure are a maven expert, aren't you ?

8:16 cemerick: heh

8:16 lpetit: perhaps in here.... :-)

8:17 one-eyed man and all that

8:17 _fogus_: cemerick: I wish I knew enough about Arc's capabilities. But what you say seems to be a common theme.

8:17 cemerick: ;-)

8:17 lpetit: cemerick: I have this goal which does almost what I want, but not totally. I want an ant-task (via antRunner, I've just discovered how to use it) to be run just after the goal is run.

8:19 lpetit: to be precise: mvn war:inplace copies 3 files in WEB-INF/lib/ that I don't want. So I want to delete them. Easy enough. But I want to have them deleted by configuring my pom.xml so that when writing mvn war:inplace, my deletion task will also be called

8:19 * cemerick taking a call, one sec :-)

8:21 lpetit: :)

8:25 cemerick: lpetit: surely you'd want to use excludes instead of cleaning up the results afterwards?

8:25 rhickey: any feedback on prim branch?

8:26 lpetit: cemerick: I've tried to configure the war:inplace plugin, but without much result. which exclude configuration are you thinking about ?

8:28 chouser: rhickey: I'm porting our codebase now. Should have results to report yet this morning.

8:28 rhickey: chouser: was the codebase on master?

8:29 It shouldn't require any changes if so

8:29 chouser: an older master. we were using deftype pre-defrecord

8:29 rhickey: chouser: ah, and are many of our types going to become records?

8:30 your types

8:30 chouser: yes. all, I think.

8:35 oh, whoops. Not all. custom equiv

8:41 rhickey: chouser: for numeric equiv or something else?

8:43 chouser: it's an object that represents a byte string as a offset/length into a byte array.

8:43 rhickey: chouser: why would that become a record anyway?

8:44 chouser: I've been assuming things should use defrecord unless there's a reason to prefer deftype

8:45 rhickey: defrecord is for information and deftype is for program constructs

8:49 dnolen: hmm, so is definterface still an AOT kind of thing? and is it the only way to specify primitive args/return ?

8:49 specify primitive args/return for derecord methods I mean.

8:50 s/derecord/defrecord

8:50 rhickey: dnolen: 1)definterface is dynamic, and 2) well, maybe not after static

8:51 chouser: heh

8:51 oh

8:51 maybe not the only way to do primitives. I misunderstood for a moment.

8:51 rhickey: One of the things driving static is the number of times I've had to create a dummy interface just to get helper methods that take/return primitives. Now these can just be fns

8:52 I'm still contemplating the relationship between static and protocols

8:53 dnolen: rhickey: so one issue I've seen with with using statics for helpers method is I need to add a lot of args for the fields of the defrecord so I don't pay for the cost of field lookup time when there's lots of iterations

8:54 in that case I would prefer that the deftype method allow primitive arg/return

8:54 sadly I've been unable to decipher the proper syntax to do this after looking at gvec :P

8:54 rhickey: dnolen: field lookup via '.' ?

8:55 dnolen: rhickey: ah, so that's just as fast just referring to that field when "inside" a defrecord method? I've been sticking with :field access.

8:55 rhickey: one issue with statics for that is the circular def problem.

8:56 dnolen: even :field access is fast for deftypes

8:56 chouser: defrecords?

8:56 rhickey: sorry, defrecords

8:57 dnolen: true, but I get like a 3X speed boost if I avoid it, and have those be parameters to my static methods

8:57 well, perhaps overstating more like 2-2.5X or something.

8:58 rhickey: the problem is: a static can't use the type of the deftype before its used, and if defined after, can't be used by the deftype impl itself. But this could become a decl thing

8:58 deftype before it is defined

8:58 such decls being not much slimmer than definterfaces :(

8:59 AWizzArd: rhickey: is there possibly a way to have something like Protocolls for concrete objects?

9:02 dnolen: rhickey: interesting. I anycase it's still a massive improvement. The code got 1.5X faster from a version that used type-hinting macros. And I love not having to write type hints inside methods.

9:03 rhickey: AWizzArd: I don't know what that means

9:06 AWizzArd: rhickey: Example: in my db system I build indexes for data. There is a (defrecord Index ...). Every Index should be able to report how many elements it holds, a fn to serialize its data, to deserialize it, etc. But: the underlying datastructure that holds the objects inside the many Indexes can differ. In principle each instance of Index should follow a Protocoll, not all Indexes the same.

9:07 rhickey: AWizzArd: still don't get it

9:10 dnolen: rhickey: oh yeah, I thought it was weird that the order of primitive args/return hints differed between definterface and statics (but I guess your saying this is part of the part you're mulling over)

9:10 AWizzArd: Imagine you have the maps M1 = {:a 1, :b 2, :c 3} and M2 = {:x #{1 2 3}, :y #{4}, :z #{5 6}}. And you have a protocoll Cache, which defines get-element-count. For M1 this would be 3, and for M2 this would be 6. We can not simply extend Maps with this protocoll. Both concrete instances need their own implementation of count.

9:12 rhickey: AWizzArd: that's why you have records

9:12 AWizzArd: Yes, I was already thinking about writing a macro which will dynamically emit defrecords

9:12 rhickey: no plans for per-instance protocol impls

9:13 AWizzArd: ok

9:13 rhickey: it adds a step to dispatch that will slow down everyone else

9:13 AWizzArd: yes, that would not make sense

9:14 I just came across this and some days ago chouser had a similar challenge, so I just wanted to ask if this could make sense.

9:20 rhickey: instance methods bring equality/identity, dispatch and GC issues

9:21 AWizzArd: Yes, and there are ways to work around those issues, and I guess they arise not often.

9:21 chouser: I don't see what I'm doing wrong here: (reify clojure.lang.ILookup (valAt [k])) ;=> java.lang.IllegalArgumentException: Can't define method not in interfaces: valAt

9:22 hoeck: this?

9:22 clojurebot: this is not allegro

9:23 chouser: hoeck: gah. thanks.

9:23 hoeck: :)

9:30 candera: Licenser: ping

9:35 raek: now I wanna make another IRC bot.

9:36 irclj looks really neat

9:36 Licenser: candera: pong

9:36 raek: Raynes: you're awesome!

9:37 candera: Licenser: been trying to come up to speed on clj-swing. Having some problem with adding an ActionListener.

9:37 Licenser: you have an example?

9:37 candera: Yep. Pasting into a gist now. One sec.

9:39 http://gist.github.com/434478

9:40 My action listener never seems to fire.

9:40 Keeping in mind that I'm new to swing, and not exactly super-experienced with Clojure.

9:40 Licenser: candera: you need to put the add-action listener behind the [] the stuff in [] are bindings

9:40 candera: Yeah, I tried that, too.

9:41 Licenser: http://gist.github.com/434482

9:41 also you are using EMACS right?

9:41 candera: Yep.

9:42 Licenser: look in the inferior lisp buffer

9:42 since swing is a own thread and the bindings of out and so are sadly different there :(

9:42 candera: Nothing there. I thought of that, too.

9:43 Your code (which I had tried previously) gives me an error. Same error I was seeing: wrong number of args passed to add-action-listener

9:43 Licenser: hmm

9:43 candera: I'm on a recent 1.2 snapshot.

9:44 Licenser: *nods*

9:44 *fires up the reps*

9:45 candera: BTW, I dig clj-swing so far. Very similar to what I had in mind to write.

9:46 Licenser: :)

9:46 glad to hear that

9:46 candera: I have some broader design questions for you at some point, though. :)

9:47 arkh: is clj-swing a separate effort from what Luke VanderHart was working on?

9:47 candera: Also: specifying the :action on the button works. But I want the action to affect one of the other controls.

9:48 Twey: clojure-mode in emacs starts up SBCL in its inferior Lisp buffer ☹

9:53 Licenser: candera: that's cool :) I am always open to discuss clj-swing or take ideas to make it better

9:53 oh sneaky

9:54 candera: ?

9:54 Licenser: I opened the wrong repo :P

9:57 candera: found the problem :)

9:57 candera: Excellent!

9:58 Was it me or you? I'm guessing me. :)

9:58 Licenser: candera: well tecnically both :P

9:58 bad design decision and non existing documentation on my side, not noticing that form was calling the content in a doto on your side

9:59 mind if I keep your code in the examples file?

9:59 candera: Ah. I think I understand. It's that I was adding an action listner to the frame, yes?

10:00 Licenser: no it was adding the frame to the action lsitener call which is kind of wrong it was (add-action-listener frame b1 (...))

10:00 candera: Right. That's what I was trying to say.

10:00 Makes sense.

10:00 How are you going to solve the problem? Anaphora?

10:01 Licenser: I took the stuff out of doto in the form macro, it is ugly and was a design mistake / oversight that it was in there

10:01 and I don't even know what anaphora means :P

10:02 candera: It just means capturing a variable during the macro expansion. E.g. after the bindings in the frame, you could bind the frame itself to the symbol $.

10:02 Incanter does something similar in places.

10:02 Licenser: ah I use :name for that I think

10:02 yap

10:02 candera: How do I refer to the frame in the body of the expansion?

10:02 Licenser: you can use :name in most components to that

10:03 well if you need to (frame ... :name my-frame ... [... binding stuff ...] (.coolFunction my-frame))

10:03 candera: BTW: fine to use my example. It's a translation from "Swing: A beginner's guide"

10:03 OK - the :name thing works for me.

10:03 Licenser: kk then you got push to the new version on clojars and github

10:04 candera: Read error: sentence does not parse. :)

10:04 Licenser: (dosync (push-to-github *clj-swing-source*) (push-to-clojars "clj-swing.jar"))

10:05 tridd3ll: Does anyone use clojure.contrib.sql against an existing database like Oracle or DB2? All of the examples I see use sql/create-table with just a keyword (like :fruit) for the table name. What I need to do is define tables that already exist (like PRODLIB.KEYS) to query/insert against.

10:05 candera: Meaning I should do that, or you are?

10:05 Licenser: candera: meaning I just did

10:06 candera: Excellent, thanks. FYI I would have seen that as a reasonable reward for you help. ;)

10:06 Licenser: heh

10:06 candera: see helping people to work with clj-swing helps me to make it better, find problems I missed since I know how it works and don't expect stuff

10:06 MrHus: Licencer: The readme on clj-swing does not have the .md extention so formatting is wrong on the page. :P

10:07 candera: Licenser: Thanks again - more feedback as I keep working my way through the book (and ultimately the project I want to build)

10:07 Licenser: I want to make clj-swing as simple and intuitive as possible. I can work on the simple part but the intutive is hard since my intuition is clouded since I know the code :P

10:07 MrHus: thank you I'll fix that

10:09 candera: I already can promise that you'll reach a point where clj-swing won't be enough since, I haven't implemented (wrapped) all kinds of widgets by far

10:11 candera: Licenser: then I'll start breathing down your neck. :) Anyway, I've got to run off to go buy a house! Thanks again!

10:13 raek: where exactly does lein-swank live? leiningen? an own project?

10:16 Licenser: take care candera

10:19 raek: aha, lein-swank is now a part of swank-clojure...

10:27 whohoo! got swank-clojure, slime and clj-1.2.0 working over UTF-8!

10:28 my mind will finally be at peace

10:30 Raynes: raek: I'm awesome? :D

10:30 <3

10:36 raek: now, lets see... how does irclj handle encoding?

10:37 hrm, clojure.contrib.io/reader uses clojure.contrib.io/*default-encoding*, which is UTF-8

10:38 note: in swedish channels, about 50% use latin-1 and 50% UTF-8

10:38 this only works because irc clients are smart and try both decoding from UTF-8 and Latin-1

10:42 hrm, maybe one could make a java CharsetProvider that provides a try-utf8-fallback-to-latin1 Charset

10:48 Raynes: Oi.

10:49 I just noticed a bug in Irclj. Good thing I never used the :on-action handler in sexpbot, because it was broken. :\

10:58 raek: Raynes: how often do you push to clojars?

10:59 Raynes: raek: If I make a fix, or add something (like I'm doing as we speak), I push a new snapshot as soon as I know that sexpbot will run with the new snapshot.

10:59 raek: ah, cool

10:59 Raynes: I'm very liberal with my snapshots.

10:59 ;P

11:01 raek: I'll ping you when I push.

11:05 raek: Just pushed the new snapshot.

11:06 That :on-action bug would have been nasty, had anyone actually used it.

11:06 sexpbot doesn't do anything special for actions, so I never noticed it.

11:07 My test/example bot needs to be more through so that I can catch stuff like that.

11:10 raek: Sorry for Irclj's shoddy documentation. Most of that thing was thrown together in a day and a half, and I've been busy with other stuff lately, so the documentation hasn't really improved.

11:12 raek: well, the example has shown me what I have needed so far... :)

11:14 Downloading: irclj/irclj/0.3.0-SNAPSHOT/irclj-0.3.0-20100502.112537-6.jar from clojars

11:14 Raynes: raek: Yeah, the example bot isn't too bad. There isn't much to Irclj, so the general idea is easy to get across. It's what Irclj is 'specifically' capable of that isn't entirely clear.

11:14 raek: does it take some time before the new one gets through?

11:15 Raynes: Hm?

11:15 raek: I just cleared all my irclj jar files from the project and .m2

11:15 and ran lein deps

11:15 jcromartie: is 1.2 considered "beta" at this point or what?

11:15 raek: looks like it downloaded a version from 2010-05-02

11:16 Raynes: Oh.

11:16 Hrm.

11:16 I'll try that again. Give me a sec.

11:17 [INFO] Uploading project information for irclj 0.3.0-20100502.112537-7

11:18 raek: Apparently, it's right. I guess maven's calendar is broke?

11:18 :\

11:18 raek: hah, ok

11:18 another question: how are private messages to the bot handled?

11:19 is the :channel value instead the nick or something?

11:19 Raynes: They're considered normal messages, and trigger the :on-message handler.

11:19 The :channel value is the nick instead.

11:19 raek: nice, so I can always reply to "channel"

11:19 Raynes: Yep.

11:19 :)

11:20 raek: I'm taking off for a while. If you have any more questions, ping me or shoot me a message on github.

11:22 raek: all right.

11:23 now, where's my cond-re macro?

11:23 this could make my bot's command parsing much simpler: http://gist.github.com/387097

11:26 dnolen_: raek: couldn't you do that with condp and re-matches?

11:27 jcromartie: yeah, looks like condp already fits the bill

11:27 although I have to say condp is one of the trickiest things to grasp in Clojure

11:29 dnolen_: jcromartie: really? so many others things on my list that are harder to grasp :D tho it is diminishing over time ...

11:29 jcromartie: heh

11:29 I just had to use it to really get it

11:29 raek: I wanted a more compact way of including the destruturing

11:30 it takes triples of [re bindings body]

11:30 bindings are bound to the groups of the match

11:30 dnolen_: raek: i see. cool. so you have your solution :)

11:34 cgrand: raek: (defn parse-flag [s] (rest (re-matches #"--([^=]+)(?:=(.*))?" "--abc")))

11:36 err I mean (defn parse-flag [s] (rest (re-matches #"--([^=]+)(?:=(.*))?" s))) ;-)

11:37 dnolen_: can somebody tell me what I'm doing wrong here? I'm trying to create a type-hinted method on defrecord, http://gist.github.com/434649

11:38 Chousuke: dnolen_: bar is a method, not a function

11:38 dnolen_: maybe you meant to define a protocol instead?

11:39 dnolen_: Chousuke: wow, so only protocols generate fns?

11:39 Chousuke: dnolen_: yes.

11:39 definterface generates an interface

11:39 dnolen_: Chousuke: that was the gap in my understanding abou the relation between interfaces and protocols.

11:39 Chousuke: best not think of them as at all related

11:40 a protocol is backed by an interface, but that's just the implementation

11:50 Licenser: coookies!

11:51 Raynes: cakes!

11:52 cemerick: lpetit: should ccw work OK in helios RCs?

11:55 lpetit: cemerick: not tested for a while, but I guess so

11:56 cemerick: did I just loose ? :)

11:56 * cemerick goes forward bravely :-)

11:56 cemerick: lpetit: not at all, we'll see how it goes.

11:57 lpetit: cemerick: ok then. Honestly I'm pretty confident

11:58 cemerick: yeah, it's supposed to be entirely compatible with whatever the current rev is, just thought I'd check

11:58 Licenser: no Raynes cooooookies!

11:59 I want to build something geniouse and crazy

11:59 lpetit: cemerick: that's a good test I haven't done in a while. Looking forward to your feedback

12:01 cemerick: lpetit: am I right in thinking that ccw doesn't have remote repl capability?

12:01 lpetit: cemerick: you're right, it's on my todo list

12:02 cemerick: lpetit: if possible, I'd recommend just reusing the existing impls

12:02 lpetit: cemerick: as you guessed (was it you ? I think so) in one of your blog posts, we are using the java console input/output facilities provided by Eclipse

12:02 cemerick: enclojure's repl library has been very solid for us. I don't have any experience with swank, though.

12:02 yeah, I figured

12:03 IMO, all repls should be run over a socket

12:03 I've always had issues with inferior repls

12:04 or, I should say, did the last time I used them :-)

12:06 lpetit: cemerick: sure, I totally agree. One path for everything. Even if the REPL is from the same JVM, pass through a socket for communicating between the server part and the GUI partr

12:06 cemerick: yup

12:09 lpetit: cemerick: but from what I've seen, I will not take a lot of things from enclojure repl, when I plan to do so. Because the GUI part is in swing, and will resemble nothing under Eclipse

12:10 cemerick: lpetit: the GUI is irrelevant -- the tricky part is the repl client/server library, which is a separate small component :-)

12:10 or, not irrelevant, but easy to recreate ;-)

12:11 lpetit: cemerick: indeed, but for ccw, I just use the "trick" (currently) of starting the application to test with clojure.contrib.repl_ln :-)

12:12 cemerick: I also have a "server" backdoor, of course, to be able to send commands to the launched JVM

12:12 cemerick: carefully written in clojure 1.0 style, so that it works for any clojure a user may want to use

12:18 Licenser: cookies

12:21 rrc7cz-hm: is there some trick for working on a gen-class and not having to restart swank? working within already defined methods is fine of course, but when you're adding methods I don't see another way

12:21 arohner: it would be really nice if you could apply a map to (fn foo [ & { a :a b :b}])

12:21 (apply foo {:a 1 :b 2})

12:30 StartsWithK: in clojure dist, test/clojure/test_clojure/genclass/examples.clj there is ExampleAnnotationClass using new reader syntax to attach metadata to class

12:31 how can that be used lets say to add: @Perm("can-read") @Perm("can-write")

12:35 also, are there any examples on how to use enums and other annotations inside the annotation value part

12:43 chouser: weird. I've got what appears to be a deadlock involving agent await that only shows up after upgrading clojure.

12:43 I don't really believe that's it, but that's how it looks at the moment.

13:20 dnolen_: hmm does ^:static work for def as well?

13:25 duncanm: dum de dum

13:31 Bootvis: what's the difference between defn- and defn?

13:31 Raynes: Bootvis: defn- makes the definition private.

13:31 Bootvis: thanks

13:45 chouser: rhickey: we using binding to replace various core functions with our own for unit tests

13:45 as long as core functions have been vars this has worked just fine. direct linking started to change this, but we had a workaround. statics are killing.

13:46 rhickey: chouser: with your hack for direct linked things?

13:46 chouser: we'll have to find another way to solve our problem before we can use the prim branch

13:46 rhickey: what's an example of something you replace and why?

13:47 chouser: what is easy. I'll work on why for you.

13:48 what: pmap, send-off, await

13:48 technomancy: we rebind test-var so we can mark some tests as integration tests in their metadata

13:48 that way we can skip the tests that require network access when doing our regular test runs and run them with less frequency.

13:49 very nice capability to have.

13:49 might be worth formalizing in clojure.test in the future though.

13:50 chouser: oh, I bet all these are to support mocking of our own network functions.

13:50 rhickey: if your hack was based on modifying the metadata before compiling a use, you can just lop of :static true

13:51 lop off

13:51 chouser: the test calls real code that may call network functions inside pmap or send-off

13:52 technomancy: chouser: we have a with-alter-var-root macro for that. it's super-ick, but it works across threads.

13:52 chouser: we want to mock out those network functions with binding, but that fails if the real code does a real send-off, so we have to mock that out as well.

13:52 technomancy: obviously verboten for anything but tests

13:52 chouser: technomancy: hm, that might be better

13:53 ok, lopping off :static works fine for now.

13:53 all tests pass. prim is good enough for us. :-)

13:53 rhickey: yay

13:53 chouser: but altering the var root would be much better.

13:54 rhickey: so, this still begs the question of opt-in/out and knobs

13:54 chouser: that were never really answered with direct linking

13:55 rhickey: a big problem is people thinking they should be able to change the decision of other people re: direct links

13:59 cemerick: easily being able to route around "private" vars when necessary seems like a corollary, but carrying over that principle doesn't sound possible

14:00 rhickey: cemerick: @#'

14:01 cemerick: yes, I know about that

14:01 rhickey: cemerick: so, I don't understand re: private vars

14:01 cemerick: I'm just saying that both statics and visibility are examples of authors making decisions that users might want to override

14:02 rhickey: #'

14:03 timcharper: will a future die if it's running, but there are no references to retrieve it's result ?

14:03 IE: does the running thread keep it from being garbage collected ?

14:03

14:04 chouser: timcharper: yes, the running thread will keep going

14:05 ,(let [x (future (Thread/sleep 2000) (println "stayin' alive"))] 0)

14:05 clojurebot: 0

14:05 chouser: heh. well, it works at a real repl.

14:06 I imagine "sayin' alive" is printed on some clojurebot console somewhere.

14:09 leif-p: Hi. All the examples in clojure.walk have to do with transformation. Does anyone have any example code where they walk through a form collecting values? I can do it by mutating an atom, but I hope there is a more functional, clojure-y way.

14:19 aria42: Is there a *special* variable that's set when a form is being evaluated as part of compilation?

14:40 yacin: can you do the multiple possible argument destructuring that you can do in defns in defmethods?

14:40 like

14:40 (defn mymax ([x] x) ([x y] ...))?

14:41 i guess having different arglists in defmethod is what i want

14:41 or should i just make my dispatch function take this into account?

14:44 chouser: your dispatch function will have to handle different arity counts either way

14:45 yacin: yeah, i just realized that

14:46 jasonamster: ny good tutorials or walkthroughs for a rubyist to learn clojure? Not just syntax but doing projects and creating apps

14:46 technomancy: clojurebot: peepcode?

14:46 clojurebot: peepcode is a commercial screencast series; see the Clojure one at http://peepcode.com/products/functional-programming-with-clojure by technomancy

14:47 jasonamster: technomancy: isn't peepcode out of date?

14:47 technomancy: jasonamster: it doesn't cover the latest features of clojure, but the stuff it covers is still relevant.

14:47 I wrote a blog post that covers the few things that are a bit out of date: http://technomancy.us/136

14:48 jasonamster: technomancy: okay great... I actually think I purchased that peepcode a while back anyway... Now if I can only find it.

14:48 technomancy: heh; cool

14:49 clojure is really good about not breaking backwards compatibility within the language itself (modulo external libraries)

14:51 jasonamster: just found it... yep i remember watching this... I must have been drunk, b/c it's a blurry memory

14:54 technomancy: heh

15:25 timcharper: chouser, heheh. Thanks.

15:25 chouser: :-)

15:26 timcharper: the bot is still probably singing "oh, oh, oh, oh, sayin' alive"

15:26 chouser: I know I am.

15:26 timcharper: infecting song, isn't it?

15:26 lol

15:27 in seriousness though... is there anyway to hook into the garbage collector with clojure? Or is this naughty? I'd like to have a thread that stops when an object is freed.

15:27 chouser: timcharper: fill-queue does that, I think, but it's messy, fragile, etc.

15:27 technomancy: clojurebot: 𝅘𝅥𝅮 "This was a triumph. I'm making a note here: huge success." 𝅘𝅥𝅯

15:27 clojurebot: make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive

15:27 chouser: technomancy: :-)

15:28 for the good of all of us, except the ones that are dead.

15:30 timcharper: see 'alive?' and (throw ... "abandoned")

15:30 timcharper: looking...

15:30 yeah

15:32 so, you create an object that is not referenced by the fill fn (but is by the drain fn)

15:32 so if the drain fn gets gc'd, then so does the fill fn ?

15:33 hmmm... let me see if I get this actually...

15:34 chouser: close. if the drain instance is gc'ed, next time fill loops it'll notice and kill the thread so the thread no longer keeps refs to the blocking queue, etc.

15:34 timcharper: ah... the drain fn is the lazy sequence :)

15:34 that is pretty neat

15:34 why is that fragile ?

15:34 (I want to create a process that subscribes to a queue and pulls off mongodb records from it, running mass-insert on it everytime)

15:35 chouser: it's a lot of consequence hanging on GC's specific behavior

15:35 you might consider more specifically-scoped behavior, something closer to with-open

15:35 timcharper: I considered that first

15:35 chouser: oh, good.

15:35 that's the correct order. :-)

15:35 timcharper: but I've already got two with-open-ish statements on this piece of code

15:36 and adding another... it just nests deeper and deeper

15:36 I would like to flatten them

15:36 (maybe I should write a macro for it...)

15:36 to flatten the nesting

15:36 chouser: well, if the nesting points are correct, I'd -- yeah, combine them somehow rather than going to some other mechanism

15:37 timcharper: it's a with-open to read a csv, with-open to write a csv, and then a with-mongo-db-mass-inserter-thingy

15:37 chouser: the GC-based behavior probably should only be considered if you can't know by any other mechanism when it should be cleaned up

15:37 timcharper: which in the case of fill-queue... would suck to have to remember to close it

15:37 (which is why GC exists)

15:37 chouser: timcharper: maybe a protocol so you can (with-my-open [reader ... writer ... mongo ...] ...)

15:38 and extend the protocol to all of them. only one level of nesting then, but without losing any specificity.

15:38 timcharper: what about a thread-through approach for nested macros ?

15:39 chouser: sure, if that works

15:39 timcharper: kinda like thread through... but obviously without the threading

15:39 (as in threading a value through it)

15:39 heh, ok. Thank you counselor chouser :)

15:39 chouser: :-)

15:52 arkh: does a repl (await) an agent (send-off) ? When I send-off an agent at the repl with an infinite loop, the repl doesn't return with another prompt

15:53 e.g. (send-off (agent nil) #(do (prn "hi") (Thread/sleep 1000) (recur))

15:54 chouser: you're just missing a close paren

15:54 but even with that fixed, the agent will immediately fail because the action fn must take at least one argument

15:55 arkh: gee I do good work ... thank you though

15:57 (send-off (agent nil) (fn [_] (do (prn "hi") (Thread/sleep 1000) (recur nil))))

15:57 chouser: np

15:57 there you go. :-)

15:57 arkh: chouser: thanks! ; )

16:49 aria42: Is anyone using the maven plugin (1.3.2) and having trouble getting it to respect the compile and copy configuration elements?

17:14 duncanm: kinda quiet today....

17:16 dnolen_: duncanm: the pre 1.2 hush ...

17:19 serp_: sup

17:21 dnolen_: rhickey: so what was the rationale behind putting the return arg type hint where it is now? is that because ^:static true would look weird? wouldn't it be better to just have fns that are tagged in the normal way with ^long or ^double to have implicit static?

17:22 erg I mean ^:static hint foo

17:22 ^:static ^hint foo

17:34 serp_: is it ever a problem in practice that transactions become too big and performance dies because the transaction becomes interupted by external modifications and keeps restarting?

17:39 dnolen_: serp_: that's a possibility, but as long as you give your design some thought you can make that very unlikely. the trick in clojure it seems is to pick the right level of granularity.

17:40 serp_: if you need to serialize access use an atom, if you to coordinate two or more things use refs. That's what I've culled anyway. People who know better than I can probably say more.

17:43 hiredman: just like locks you can also change granularity, a map in a ref vs. each value in a map being a ref

17:44 the difference is operations on refs compose

17:50 serp_: I have to read more stuff to understand your answers, but thanks :)

17:55 rhickey: dnolen_: if you have multiple arities they might have different returns

17:57 arohner: if you have a fn with signature [ & {a :a b :b}], and you want to apply a map, is there a faster/cleaner way than (apply foo (interleave (keys map) (vals map)))?

17:57 dnolen_: rhickey: oh yeah. thx.

17:59 serp_: transactions seem scary/involved but it's actually pretty easy to set some up, use a couple Thread/sleep and you can get a intuitive sense of what kinds of things can happen.

18:07 rmarianski: arohner: maybe you can (flatten (seq map))

18:07 dunno if that's cleaner though

18:07 arohner: rmarianski: using flatten makes a little more sense to me. thanks

18:08 rmarianski: sure, np

18:20 mebaran151: is it possible to completely AOT compile a Clojure app that uses defprotocol and friends?

18:21 I was wondering if I AOT'ed a Clojure 1.2 app if I couldn't avoid nasty probles on android (running just the final jar once through dx)

18:44 arohner: mebaran151: I'm pretty sure the answer is yes, you can AOT defprotocol

18:45 mebaran151: I don't know if that's solves all the issues of running on andriod.

18:46 lancepantz: i think it would completely break servlets if you couldn't

18:54 hamza: guys, I have symbol for a function and I need to call that particular function something like the following (let [s 'println] (s "Hello...")) but it does not work..

18:55 Twey: hamza: Don't call a symbol, just call the function

18:56 (let [s println] (s "Hello"))

18:56 dakrone: ,(let [s (var println)] (s "hello"))

18:56 clojurebot: hello

18:56 Twey: ,(let [f (+ % 1)] (f 3))

18:56 clojurebot: java.lang.Exception: Unable to resolve symbol: % in this context

18:56 Twey: ,(let [f #(+ % 1)] (f 3))

18:56 clojurebot: 4

18:56 Twey: dakrone: What's the ‘var’ for?

18:57 ,(let [s println] (s "Hello"))

18:57 clojurebot: Hello

18:57 dakrone: that works too, don't even need the var

18:57 Chousuke: hamza: you can resolve a symbol to a var by using resolve

18:58 hamza: but in my case symbols are user defined, i pass them around as symbols then i need to call them.

18:58 ,(doc var)

18:58 clojurebot: Gabh mo leithscéal?

18:58 Twey: Haha

18:58 Chousuke: var is not for runtime stuf

18:58 f

18:58 Twey: http://clojure.org/special_forms#var

18:58 Chousuke: ,((resolve 'println) "foo")

18:58 clojurebot: foo

18:58 hamza: ,(let [s 'println] ((resolve s) "Hello..."))

18:58 clojurebot: Hello...

18:58 Twey: Ah, ‘resolve’, that's the one

18:59 ,(let [f 3] (eval 'f))

18:59 clojurebot: DENIED

18:59 hamza: cool thanks..

18:59 Chousuke: resolve can return nil though, so beware

18:59 Lajla: ,(let [gay 3] (let [twey gay] (+ twey gay)))

18:59 clojurebot: 6

18:59 Twey: Denied?! :-D

18:59 Chousuke: it'll also return a Class instance for class names.

18:59 Twey: Hm, not allowed eh.

18:59 Chousuke: Twey: eval is not allowed

19:00 Twey: It's an error anyway. Guess eval doesn't work like that.

19:00 Lajla: Chousuke, kerro twey:lle että mun suomenkieli on parempi kuin sen.

19:00 timcharper: chouser: for fun and giggles, here's a macro that encapsulates the WeakReference pattern used by fill-queue

19:00 Twey: >.>

19:00 Lajla: kerro että olen paras.

19:00 hamza: Chousuke: function will be defined before calling it, is it safe to assume it wont return nil in this case?

19:00 Chousuke: Lajla: You're being weird :P

19:00 Lajla: Chousuke, I guess, it's a curse.

19:00 Twey: How long have you known Lajla? :þ

19:00 timcharper: http://gist.github.com/435165

19:01 Lajla: Twey, do not remind it.

19:01 You're a cruel man.

19:01 Reminding people that I exist.

19:01 Twey: 'tis true

19:01 Lajla: You should hate yourself, I happen to have some of that spare for you.

19:01 Twey: Sometimes I sit here and just look at you, so you can't escape.

19:01 Lajla: Sometimes I wank and think about my sister.

19:01 Twey: I knew that already.

19:01 Lajla: I say it a lot.

19:02 More reason to hate myself.

19:02 And more reason for you to do so too, your thoughts have been beviled with incest.

19:02 Chousuke: seriously now, keep that outside this channel, please.

19:03 timcharper: chouser: maybe you don't want to wrap it because it can be abused

19:03 :)

19:05 Lajla: not funny

19:05 "Yields an object and a fn to tell if if the object has been GC'd yet

19:05

19:05 The following will quit when the return value is no longer referenced and GC is run

19:05

19:05 (with-monitor [monitor alive?]

19:06 (let [alive-fn (fn [] (loop []

19:06 (println \"alive...\")

19:06 (java.lang.Thread/sleep 1000)

19:06 (when (alive?) (recur))))]

19:06 (future (alive-fn))

19:06 monitor))"

19:06 [[tracer-binding alive?-fn-binding] & body]

19:06 `(let [~tracer-binding (Object.)

19:06 weak-ref# (java.lang.ref.WeakReference. ~tracer-binding)

19:06 ~alive?-fn-binding (fn [] (not (nil? (.get weak-ref#))))]

19:06 ~@body))

19:06 ummm... wow. Go ERC random yank.

19:10 RosaSchaf: hi, I was searching for something and came across neman.cells in the list of libraries on clojure.org. I have actually no idea but it seems to be interesting. However, the latest change was made over an year ago and I wonder if the idea is still up to date and if it is, if there is another, more active implementation or if neman.cells will work fine? (I actually just want to know if it is worth to have a closer look at it)

20:05 quotemstr: Why does Clojure put the docstring *before* the arguments?

20:06 Twey: Because the bodies of a function are arglist/expression pairs?

20:06 quotemstr: Bod... ies?

20:07 Twey: You can overload a function on number of arguments

20:07 quotemstr: In the same defn?

20:07 Twey: (defn foo [x y] (foo) [x y z] (bar))

20:07 Yes

20:07 quotemstr: Ah.

20:09 technomancy: quotemstr: the only thing that helps there is font-lock; Emacs will highlight it with comment-face if it's in the right place.

20:12 quotemstr: So where in the Emacs implementation in Clojure? Every Lisp dialect seems to get its own Emacs. :-)

20:13 Chousuke: Twey: not quite like that though.

20:14 technomancy: quotemstr: actually once Emacs gets threads and Clojure gets a little closer to self-hosting, Emacs may become a feasible compilation target.

20:14 Chousuke: if you want to overload by arity, you need more parens :)

20:14 Twey: Really? Damn.

20:14 Chousuke: eg. (defn foo ([a] a) ([a b] b))

20:14 Twey: Thanks. I'm new. ☺

20:24 Lajla: Twey, if I prove that my language is better than clojure and make a better compiler, will you then join the dark side?

20:25 zakwilson: How does one prove that a language is "better"?

20:37 hamza: are there any examples that show how can i use protocols to override functions such as conj to work on custom data structures?

20:38 I am looking over protocols and types but no examples

20:38 technomancy: hamza: conj hasn't been ported to use protocols yet

20:39 hamza: technomancy: thanks, is there alist somewhere that shows which functions are ported?

20:45 technomancy: I don't know of such a list.

21:28 Lajla: zakwilson, well, by me saying it is, and then using the argument to authority.

21:29 tomoj: well, you can have a deftype implement IPersistentCollection for custom conj behavior, right?

21:31 Lajla: tomoj, are you addressing me?

21:32 tomoj: nope

21:32 Lajla: tomoj, why not?

21:32 Don't youy like to put me in the centre of attention?

21:36 quotemstr: Do {}-structures default to ordered or unordered maps?

21:36 Eww -- comma are just ignored?

21:36 commas, even.

21:36 What about in backquote?

21:36 Lajla: quotemstr, commata, and yes.

21:36 You use ~

21:37 quotemstr: Ah.

21:37 Lajla: `(a ~b c)

21:37 Same key too

21:37 On most keyboards

21:37 quotemstr: I can live with that.

21:37 Lajla: quotemstr, if you can, then so can I.

21:38 If you believe, then so do I.

21:38 quotemstr, also, they call the syntax-quote.

21:38 We call it the unquote.

21:38 Pluriformity eh?

21:38 And we all respect each other

21:38 And don't go argue about it.

21:38 We realize we all mean the same thing, but say it differently.

21:38 We don't blow ourselves up because of it.

21:38 We're all friends.

21:39 quotemstr: I get the feeling there have been massive flamewars on this very topic.

21:39 Lajla: ,(let [a 3 b 4] `(~(+ a b) c))

21:39 clojurebot: (7 sandbox/c)

21:39 Lajla: quotemstr, I haven't seen them.

21:40 Lisp is unlike the gaza strip.

21:40 here we realize, Scheme, CL or Clojure, we all came from the same roots.

21:40 We believe the same things in essense, minor differences.

21:40 We should be brethren, not war.

21:40 We're all entitled to the promised land.

21:41 quotemstr: My ancestors called it quasiquote and I'll DIE and MARTYR MYSELF before you call it syntax-quote you filthy heathen!

21:41 Err, I mean, right.

21:41 Lajla: quotemstr, that's another thing.

21:41 quasiquote is `

21:41 quote is '

21:42 and unquote is , in Scheme, in CL it's called backquote, Cloj has ~, and calls it syntax-quote.

21:42 quotemstr, be open to the warmth we offer you.

21:42 raek: no, it is ` which is called syntax-quote

21:42 ~ is simply called unquote

21:42 clojurebot: Titim gan éirí ort.

21:42 raek: and ~@ unquote-splicing

21:43 Lajla: Whether you cover up your women and beat them to death for being raped, whether you sell indulgences in the name of God to enrich yourself, whether you nuke homeless people who got in a land before you you think is your promised land, we all have our failures, doesn't mean we can't get be friends.

21:43 raek, I respect your vision

21:43 after all, doesn't matter how we call it, it's the same.

21:44 * Lajla hugs raek and is openminded towards its differences, and does not call it a blasphemer.

21:45 raek: I just wanted to avoid confusion about clojure's names, not pick on other lisps' conventions...

21:45 Lajla: raek, I respect that.

21:45 raek: anyway, http://clojure.org/reader says "Syntax-quote (`, note, the "backquote" character), Unquote (~) and Unquote-splicing (~@)"

21:46 that was what I wanted to relay

21:46 Lajla: To inform is the key to peaceful co-existence between different creeds.

21:46 Welcome that which is different, do not be afraid of it.

21:50 lancepantz: Lajla: to a point

21:50 "all that is necessary for the triumph of evils is that the good men do nothing"

21:51 not that i'm saying we should take out the scheme fans

21:52 * quotemstr defines an 'unless' macro.

21:54 quotemstr: So def *always* affects the root binding, where set! affects either the root or the current dynamic binding?

21:54 raek: set! can only affect a thread-local (i.e. dynamic) binding

21:55 quotemstr: So set! on an unbound variable is an error?

21:55 raek: yes

21:55 quotemstr: Hrm.

21:55 Lajla: Not sure if this is the idea of clojure, but in Scheme, the idea is that set! changes a memory address.

21:55 And define actually binds a variable.

21:56 Ehh, hanges the contents of a memory address.

21:56 raek: clojure is a bit different from scheme

21:56 Lajla: lancepantz, it has a reason though, good leaders are reluctant to lead.

21:57 raek: only root bindings can change

21:57 quotemstr: raek: Then what does set! do?

21:57 raek: locals introduced by let and function parameters are actually not variables at all, but local names for immutable values

21:58 Lajla: raek, that's the same thing in Scheme though.

21:58 raek: you can mutate vars if you have a thread-local binding for it

21:58 Lajla: set! does not mutate.

21:58 It binds a symbol to another value.

21:58 raek: it mutates the var object

21:59 clojure variables are objects

21:59 living in a namespace

21:59 Lajla: If that was so, then let would mutate it too.

21:59 It changes the environment in a way.

21:59 raek: let makes a new environment

22:00 (if one uses scheme terminology)

22:00 Lajla: That is true

22:00 set! changes it, but it doesn't mutate any data per se.

22:00 raek: yes

22:01 anyway, in order to be able to change a variable with set!, it must first have a thread-local value

22:01 Lajla: As in (define x #(1 2 3)) (define y x) (set! x #(2 3 4)) y will then still have #(1 2 3)

22:01 raek: this is done by (binding)

22:01 a warning: in clojure, def should normally only be used at the top level

22:02 it does not add a new binding in the "closest" frame, but in the global environment

22:02 (the current namespace)

22:02 JonSmith: right

22:02 def is global

22:03 raek: these things doesn't work much like in scheme

22:03 quotemstr: Can Clojure's reader eval by itself like CL's can?

22:03 JonSmith: raek: is more like common lisp in that way

22:05 raek: IIRC, there is a #= reader macro that evaluates

22:06 (def x 1) (set! x 2) => "Can't change/establish root binding of: x with set"

22:06 JonSmith: you have to do binding first

22:06 raek: (def x 1) (binding [x 2] (set! x 3) x) => 3

22:06 JonSmith: set is thread local

22:07 raek: yes, I just thought I'd show quotemstr an example

22:07 quotemstr: Thanks.

22:07 JonSmith: oh ok

22:07 i think i came in partway through, my bad

22:07 quotemstr: Can refs point to refs?

22:08 raek: set! can be used when interfacing with some java libraries

22:08 yes, refs can point to anything and nesting is allowed

22:08 you can make cycles this way too

22:08 just make sure not to try to print the ref

22:09 (if you have cycles)

22:09 also, in the example with binding, after binding has been evaluated, x has the value 1

22:10 and all other threads saw the value 1 during all the time

22:11 quotemstr: Ah, I like the shortcut literal syntax.

22:11 shortcut lambda syntax, that is.

22:19 Hrm, I'd prefer map to do the Python-esque thing and return an iterator object instead of being automagically lazy.

22:27 tomoj: huh?

22:28 iterators aren't lazy?

22:28 quotemstr: Sure they are.

22:29 But in Python, printing an iterator doesn't automatically try to iterate through all items in the sequence.

22:29 iter((1,2,3)) => <tupleiterator object at 0x10048c7d0>

22:32 KirinDave: quotemstr: “automagically lazy?”

22:32 quotemstr: KirinDave: What I mean is that map seems to return a magic object instead of the mapped sequence.

22:33 Binding this magic object to a var doesn't evaluate the sequence, but then trying to get at the value of the var evaluates the sequence.

22:33 Trying to print this magic object similarly evaluates the sequence.

22:33 KirinDave: quotemstr: "Getting" doesn't actually.

22:33 quotemstr: You're playing on the repl?

22:33 quotemstr: KirinDave: No, just looking at some documentation for now. :-)

22:34 KirinDave: quotemstr: It doesn't return any sort of magical object, it returns a lazy seq. Which is like a cons cell but the cdr is delayed computation that it knows to force.

22:34 quotemstr: Is it possible to print the delayed sequence object itself without resolving the sequence?

22:35 KirinDave: There are ways to make a unique identifier, but otherwise the print function forces it.

22:36 quotemstr: What does a unique identifier have to do with it? Let's consider lists.

22:36 You have regular lists and lazy lists, right?

22:36 KirinDave: quotemstr: yes.

22:36 quotemstr: A var can be set to either kind of list.

22:36 KirinDave: Yes.

22:36 quotemstr: (Among other data types.)

22:37 tomoj: so is the quibble just about the printed representation of a lazy seq?

22:37 quotemstr: KirinDave: But list and printing functions on that var will do the same thing regardless of whether it's a lazy or real list, right?

22:37 KirinDave: quotemstr: What it does depends entirely upon the object.

22:38 quotemstr: Basically, I'm just used to the model of a lazy-list and a list being two very different data types, with an explicit call being required to transform the lazy list to a real list.

22:38 KirinDave: quotemstr: Well then, welcome to the future.

22:38 Seq is a super-abstraction over all these types.

22:38 quotemstr: I'm not sure it's the future. :-)

22:38 Is it possible to distinguish between a variable bound to a list and a variable bound to a lazy-list?

22:38 KirinDave: Yes.

22:39 quotemstr: Ah, okay. Thanks.

22:39 KirinDave: quotemstr: I suggest you fire up the repl and answer these questions yourself.

22:39 quotemstr: When it finishes building, I will. :-P

22:39 KirinDave: Building?

22:41 quotemstr: The macport had a bunch of dependencies. It's done now.

22:42 tomoj: there's a macport for clojure?

22:42 :(

22:42 quotemstr: tomoj: Why not?

22:42 KirinDave: Wow, macports.

22:42 Haven't heard that name in awhile.

22:42 tomoj: why?

22:42 clojurebot: why not?

22:42 KirinDave: why ask why?

22:42 tomoj: it looks like it's 1.0.0 anyway?

22:42 KirinDave: Dang come on clojurebot work with me here.

22:42 quotemstr: tomoj: It provides a unified way of managing software installation. The less I stick in /usr/local/stow, the easier it is to manage.

22:42 tomoj: 1.1

22:42 tomoj: ah, not so bad

22:43 KirinDave: quotemstr: So why does this bother you?

22:43 tomoj: oh, the wrappers it installs look kinda useful

22:43 quotemstr: but, you don't need to stick anything in /usr/local for a standard clojure install

22:43 it's all project-local

22:44 quotemstr: KirinDave: I'd worry about evaluating happening when it wasn't expected.

22:44 tomoj: evaluation will happen exactly when it needs to

22:44 KirinDave: In general that's not an issue.

22:45 tomoj: bets on how long it will take quotemstr to realize that lazy seqs are beautiful? :)

22:45 quotemstr: tomoj: Sure, but then I need to add crap to $PATH and stick the clojure directory somewhere. I just wanted a repl, dammit. :)

22:45 tomoj: no, you don't need to add anything to $PATH or stick any clojure directory anywhere

22:45 but yeah, you'd have to set up a project

22:45 and those wrappers do look useful

22:46 too bad they're tied down to a system-wide version of clojure

22:46 * quotemstr wonders whether these wrappers make clojure executable with a hashbang.

22:46 tomoj: would be cool for a repl/clj command to look in ~/.m2 and allow you to pick the clojure version

22:47 yep, they should

22:48 quotemstr: Hrm. Nifty.

22:48 tomoj: quotemstr: can you map over both an iterator and a list (or whatever the equivalent is in python)?

22:49 I mean, mapping over an iterator would force evaluation, right?

22:49 er, no, I guess not

22:49 just get another iterator back, I bet?

22:50 quotemstr: no, map always evaluates immediately. There's a separate function to construct an iterator from an iterator and a mapping function.

22:50 Then again, lazy sequences were bolted onto Python, so I'm not sure that approach is better.

22:50 tomoj: that doesn't seem.. inconvenient to you?

22:50 heh, yeah

22:50 quotemstr: It seems less surprising, but that's because I'm used to Python and not Clojure. :)

22:51 tomoj: the seq abstraction is pretty fundamental here

22:51 KirinDave: quotemstr: Hopefully we can break you of that love.

22:51 quotemstr: Well, it's nice to be able to talk about a Lisp without being asked whether I can find the way back to my nursing home on my own.

22:51 :-)

22:52 tomoj: I mean, we can do things like this:

22:52 ,(->> (map #(* % %) (range 10)) (filter even?))

22:52 clojurebot: (0 4 16 36 64)

22:52 quotemstr: On the other hand, I have a horrible temptation to restructure my project's lisp to resemble Clojure instead of CL. :-)

22:53 KirinDave: tomoj: Funny thing happened in here the other day. Someone asked "What is the equivalent of ruby's detect?"

22:53 tomoj: if the interfaces for lazy seqs and concrete sequential data structures were different, it seems like beautiful stuff like that would be uglier

22:53 KirinDave: tomoj: Which is a funny question. Suggests to me people have a hard time with laziness.

22:53 tomoj: (by "interface" I don't mean java interface, but the functions you can apply to these things..)

22:53 clojurebot:

22:54 KirinDave: clojurebot: it is a lie

22:54 clojurebot: You don't have to tell me twice.

22:54 tomoj: KirinDave: I don't understand?

22:54 KirinDave: tomoj: Well how do you find the first item in a list that (conforms? x) returns true to?

22:55 tomoj: clojure.contrib.seq-utils/find-first ?

22:55 (first (filter ....)) I guess is what you're getting at?

22:56 KirinDave: tomoj: Yeah.

22:56 tomoj: so the rubyist thinks the whole seq would have to be processed by filter, I guess

22:57 KirinDave: Well I don't think he thought that directly.

22:57 It's more like, there is an inherent bias against that kind of thinking because people have a gut measure of cost for things like (filter ...)

22:57 tomoj: yeah

22:58 I think I still sometimes felt a gut reaction against things similar to (first (filter ..))

22:58 s.felt.feel.

23:10 quotemstr: Why is (let [foo 5] #'foo) an error?

23:10 Vars only exist for dynamically-bound symbols?

23:11 tomoj: vars only exist when you create them

23:11 e.g. with def

23:13 quotemstr: Which corresponds to the invisible "value cell" in Common Lisp.

23:13 tomoj: local variables don't vary

23:13 quotemstr: I forgot that detail. :)

23:45 Why are send and send-off separate functions?

23:49 technomancy: quotemstr: sometimes you want a bounded thread pool, and sometimes you want unbounded

23:50 depending on whether the work you're sending is IO-bound or CPU-bound.

23:50 send-off is for IO-bound

23:50 quotemstr: technomancy: That's what the documentation says, but it'd be nice if the documented explained the difference in thread-pool model instead of just saying "A is for X and B is for Y".

23:51 Or better yet, Clojure could directly expose the thread pool to user code. :) (Maybe it does?)

23:51 technomancy: it does, but I don't know if it's documented

23:52 ,clojure.lang.Agent/pooledExecutor

23:52 clojurebot: #<ThreadPoolExecutor java.util.concurrent.ThreadPoolExecutor@613e0>

Logging service provided by n01se.net