#clojure log - May 25 2010

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

0:02 durka42: has anyone tried doing I/O to child processes with ProcessBuilder?

0:04 dnolen: vIkSiT: hmm, the seq would be reversed, what's advantage?

0:05 vIkSiT: oh generally, trying to do it using recursion and figuring out how to generate that seequence

0:08 dnolen: ,(loop [n 1234 result '()] (let [q (int (/ n 10)) r (rem n 10)] (if (= r 0) result (recur q (cons r result)))))

0:08 clojurebot: (1 2 3 4)

0:23 remleduff: ,(loop [n 1034 result '()] (let [q (int (/ n 10)) r (rem n 10)] (if (= r 0) result (recur q (cons r result)))))

0:23 clojurebot: (3 4)

0:25 remleduff: ,(loop [n 1034 result '()] (let [q (int (/ n 10)) r (rem n 10)] (if (= n 0) result (recur q (cons r result)))))

0:25 clojurebot: (1 0 3 4)

0:32 dnolen: remleduff: good point.

0:33 ,(loop [n 10345678 result '()] (let [q (int (/ n 10)) r (rem n 10)] (if (= q 0) (cons r result) (recur q (cons r result)))))

0:33 clojurebot: (1 0 3 4 5 6 7 8)

0:33 dnolen: this is 5-6x slower than just converting to string and back.

0:37 remleduff: That seems odd

0:37 dnolen: remleduff: why? Java string operations are probably highly optimized.

0:37 remleduff: It's a super simple loop though

0:38 Vs a ton of string ops

1:00 riddochc: Hm. This one always bugs me. NullPointerException. It means I've done something stupid, I know, but it's not so helpful.

1:28 Lajla: riddochc: http://www.youtube.com/watch?v=jK47iKOb9lQ

1:34 riddochc: Lajla: Surfer dude?

1:35 Lajla: riddochc, silver surfer.

1:36 The greatest comic book series ever except for Spawn, Blame and Kodomo no Jikan.

1:38 riddochc: Lajla: Cool, I guess. I can't say I know much about comic books...

1:38 Lajla: riddochc, it is sophisticated philosophical literature man, a reflexion upon humanity, Galactus is this all-powerful planet eating diety who is neither good nor evil.

1:39 He simply eats planets to survive, as do humans.

1:39 And he talks with a British accent.

1:39 replaca: technomancy: did you see i used @(promise) in the clojure.pprint tests? But I had to comment it out cause there's now way to identify an unfulfilled promise :(

1:39 *now => no

1:39 technomancy: replaca: no, I hadn't seen that

1:40 we are using it in tests for our distributed job system to simulate a task that is permanently blocked, for that exact reason

1:41 replaca: i want a version of ideref with an isAvailable method, so we can implement a general available? call on iderefs

1:41 cemerick: replaca: I've suggested that in the past

1:42 replaca: future, promise, delay can all implement it

1:42 riddochc: Lajla: I don't quite see the association between my NullPointerException and Silver Surfer. Care to clue me in? :)

1:42 replaca: I though I had seen something like it

1:42 cemerick: The objection was that it doesn't necessarily make sense / is useful for vars and atoms

1:43 replaca: cemerick: they just return true (and don't have to implement the new interface)

1:43 assume an IDeref2 that has the extra method

1:44 cemerick: replaca: I agree. There's a bit of semantic difficulty with atoms, but I'm happy to paper over that.

1:44 I don't think an additional interface is warranted, though.

1:44 replaca: then the available call can check and just return true for IDerefs

1:45 don't atoms always have a value?

1:45 cemerick: yeah, it's not a technical problem. Rich had objections.

1:45 Lajla: riddochc, I just wanted to share my childhood nostalgia actually, and lured you into watching that clip making you think it was related to your problem. =(

1:45 cemerick: They always have a value, but not in the same way as futures, delays, and promises. Same for refs.

1:46 The former get one value, and done.

1:47 replaca: yeah, what i'm talking about is "will i block?" any guarantees about *which* of a set of vals you'll get is completely off the table

1:47 cemerick: I understand what you're driving at -- I'm all for it

1:47 replaca: pprint is my big concern, of course

1:47 cemerick: just trying to represent Rich's objection, as I remember it

1:48 replaca: yeah, I should chat with him about it

1:48 so much to do... :)

1:49 right now I should wake this bby up so she'll sleep during the night

1:49 *baby

1:51 cemerick: replaca: OK, my memory is faulty :-) http://clojure-log.n01se.net/date/2009-08-18.html#11:34c

2:05 replaca: cemerick: thanks

2:07 riddochc: Lajla: Aw, that's okay. Nostalgia's good.

2:08 Lajla: riddochc, I used my smooth cunning to lure you by manipulating the situation, yeees.

2:14 riddochc: Lajla: How clever of you. Aside from other conversations here in #clojure, do we know each other? I can't say your nick rings a bell...

2:15 Lajla: riddochc, I am fairly new here deciding wether or not to exchange Scheme for Closure, thus far my most viable option seems 'design a new language that combines them'.

2:15 Also, I am the second best programmer in the world, only second to Microsoft's chief software architect.

2:17 riddochc: Lajla: Is that so? Interesting. ;)

2:19 Lajla: riddochc, yes, they never told you?

2:19 How long have you been dwelling these forrests?

2:21 riddochc: They? Oh, in #clojure, I was on a little last fall, but haven't really been on much before about two months ago or so.

2:22 Lajla: riddochc, ahhh, I just told them two days back that I am second only to the Microsoft CSA.

2:22 Now they worship me and bow in reverence to an emerald statue in my liking every day as the sun rises.

2:24 riddochc: I see. So, I'm curious, you mentioned you're thinking of combining Scheme and Clojure. What would you change about Clojure as it is?

2:27 Lajla: riddochc, well, combining is a strong word, I'm actually more thinking of extending the concept of 'application' in Scheme beyond the lambda abstraction.

2:27 I was actually thinking of taking 'code = data' to the point that data can be applied in many forms.

2:27 Lambda abstractions being one of them, and also I want to have immutability of data for that and.

2:27 that end*

2:28 But say that x is an ordered sequence, like say and array or a list, then (s 1 -1) would be a slice from the second to the last element.

2:28 And (s 1) would be the second.

2:28 That behaviour of closure inspired me.

2:31 riddochc: Huh. Do you think it might get to a point where determining what function the first element of a list serves would make the code too obfuscated?

2:32 I mean, life in Scheme is comparatively simple, compared to even clojure. The first item in a list, if it's code, is either a function, macro, or a special form.

2:33 Er, mostly.

2:33 KirinDave: riddochc: Well, except when it isn't. :)

2:33 riddochc: KirinDave: Yeah, yeah. Details. ;)

2:34 KirinDave: riddochc: I mean, (module ...) is a great example. :)

2:34 Lajla: riddochc, well, no, that's not how scheme works actually.

2:34 riddochc: It's just that... giving special meaning to lots of data structures when put at the beginning of a list and evaluated could get really complicated, really fast.

2:34 Lajla: It first tests if it's syntax at compile time.

2:34 At runtime, it simply evaluates all the members of a form.

2:34 KirinDave: Lajla: But macros can work on forms even from (eval ...)

2:34 Lajla: If the head does not evaluate to a procedure, it results into an error.

2:35 KirinDave, well, inside eval there are different rules.

2:35 It effectively recompiles there again.

2:35 KirinDave: Lajla: I mean, sure, ultimately the evaluator gets something that is exactly that way.

2:35 Lajla: Also note that Scheme only had eval from 5.

2:35 KirinDave: But it's not something the programmer will ever see.

2:35 Or if they do, it's because they're asking for it.

2:35 It's not a level most people work on.

2:36 Lajla: Sure, but this evaluation model is actually simpler, Scheme needs to check if it's a procedure, then needs to check if the types of the arguments match.

2:36 In this case, only the types of the arguments need to be checked for match.

2:36 riddochc: Not all members of a form are evaluated, necessarily. if, for example.

2:37 Lajla: riddochc, that's syntax.

2:37 riddochc, buuut

2:37 this case is different

2:37 because I intend the language to be lazy.

2:37 If is a function in this language.

2:37 riddochc: So lazy you don't need conditions? ;)

2:37 Lajla: riddochc, well, it's a function like any other.

2:38 The only basic forms I have that are fundamentally different are let and letrec, which work lazily too, so those might need some fundamnetally different internal representation.

2:39 riddochc: I've been wondering lately, what's "lazy enough"... I read "Real World Haskell" about a year ago, and it got pretty hard to wrap my head around when it got to monads.

2:39 Lajla: But for instance, contrary to Scheme (letrec ((a b) (b a)) a) would be valid, it would just be an infinite loop trying to resolve the maning of a.

2:39 riddochc, well, is it just much of a continuum, there's just lazy and strict evaluation I guess.

2:42 riddochc: Well, it sounds like an interesting project, anyway. Try your hand at writing a compiler for it.

2:42 Or interpreter, or whatever.

2:43 Have you written much about it? Got a spec, or a blog, or anything like that for it?

2:46 Lajla: riddochc, well, I'm currently sort of making a mock-up implementation in Scheme, interpreter.

2:46 As I said, I'm fairly new here, I'm still sorting out design goals.

2:46 I think that in the end I'll demand vectors to be homogenous and occupy the same amount of storage.

2:47 There members, that is.

2:47 their*

2:47 riddochc: So they'd be more like arrays.

2:47 Lajla: riddochc, yap, C style arrays but bounded.

2:48 But I have some sketches of it written down

2:48 I'm going for a message-passing style, except that messages are nots ymbols, but any type of data.

2:48 In (sequence 0 5) 0 and 5 could be seen as messages.

2:50 Also, I'm making an unusual design choice in that say I have a function of 3 arguments (f x y z) that I call with (f x y), only one argument, the result will be the same as (f x y nil) for variable argument functions, car and cdr on nil are thus defined, and return nil itself.

2:53 riddochc: So, functions will have a known, fixed arity.

2:53 That's a little un-scheme-like, isn't it?

2:54 Lajla: riddochc, well, they don't at all. It's just that (f x nil nil) is the same as (f x)

2:54 Calling a function with the final arguments all nil can be shorthanded by calling it with fewer arguments.

2:54 So you don't need that (define (f x y . rest) hassle inside.

2:55 And can just use (define (f x y z) where z may be variable, you just check (null? z) to see if it's specified.

2:55 riddochc: Okay, sure, I guess.

2:55 Lajla: where z may be optional*

2:56 It just follows out of that car and cdr are defined on nil and just return nil itself.

2:57 riddochc: I wonder if some of the other non-scheme, non-CL, non-Clojure lisps might give you what you're looking for. I don't know, newlisp?

2:58 Lajla: riddochc, hmm, don't know that one, am checking it out now.

2:59 This version is fairly different though due to being lazy and having all valid code be an expression, like define no longer exists.

2:59 riddochc: Aren't there a couple others that are actively developed? Anyone else know?

2:59 Lajla: Also, most bizarely (- 2 1) returns -3, not 1. And (2 - 1) returns 1.

2:59 riddochc, hmm, not sure, all I know is Clojure, Common Lisp and Scheme.

3:00 All other dialects have pretty much been superseeded by Common Lisp I guess, Scheme and Clojure are different from the rest as a conscious design goal, all the others just followed out of Lisp 1.5 and were later unified in Common Lisp.

3:01 riddochc: But there are other new ones. Arc would count, I guess.

3:02 Though I really don't know whether Arc is actually being actively developed. Paul Graham really could stand to read something like http://producingoss.com/ if he really cared...

3:03 Lajla: Hmm, didn't know Arc too, you might be the third greatest programmer second to me and Microsoft's CSA.

3:03 As I read it, Arc made some controversial desisions of whcih I can't say I approve.

3:05 riddochc: I wouldn't call myself a great programmer... in fact, I'm kinda getting away from it, lately.

3:07 Lajla: riddochc, programming?

3:07 Why?

3:07 clojurebot: http://clojure.org/rationale

3:07 Lajla: Ahaha

3:07 riddochc: Heh.

3:08 Yeah, RSI plus major burnout. No more startups for me, thanks.

3:10 Lajla: In my case it's more currently trying to write an interpreter for a dubious self-invented programming languages with so much sunlight outside it gives me a headache and I see spots in front of mine eyen.

3:10 riddochc: I've had a series of several jobs that have really left me feeling like something is very wrong. You know what they say, anyway, about doing the same thing over and over again, and expecting a different result.

3:11 Lajla: riddochc, explain?

3:12 riddochc: A *real* explanation would take too long, and goes waaaay beyond casual conversation. Needless to say, I'm a hobbyist programmer now, going back to school for another masters soon.

3:15 I suppose I need to come up with a short explanation for it sooner or later... let's see...

3:15 spariev: ,(partition 2 (range 10 15))

3:15 clojurebot: ((10 11) (12 13))

3:17 riddochc: spariev: That's definitely strange.

3:17 spariev: hm, I'd like it to yield ((10 11) (12 13) (14 15))

3:17 technomancy: partition is confusing; generally you want partition-all instead

3:18 spariev: technomancy: thanks, it indeed confusing

3:19 technomancy: newlisp has made some remarkably bad design decisions

3:21 riddochc: I'm a bit of a perfectionist. This would seem like a good thing, but it's really, really not. I shouldn't be working in an industry where the number one priority is time-to-market. It's time I accept this fact, and move on.

3:21 Chousuke: ,(partition 2 (range 10 16))

3:21 clojurebot: ((10 11) (12 13) (14 15))

3:21 Chousuke: it's end-exclusive

3:22 riddochc: technomancy: I'm curious, what're its main flaws, in your view? (I know very little about it, except that it exists.)

3:24 spariev: Chousuke: yep, thanks :) slow morning

3:24 technomancy: riddochc: it has a half-baked GC model and prefers dynamic scope to lexical scope by default.

3:25 riddochc: technomancy: Sounds just like emacs. ;)

3:25 Chousuke: I failed to be impressed by the fexprs things

3:25 -s

3:25 technomancy: riddochc: except even the most hardcore Emacs fans will admit that elisp is a very backward dialect

3:26 Chousuke: Isn't there an ongoing effort to replace elisp with guile?

3:26 riddochc: technomancy: true, though I haven't read much advocacy of newlisp one way or another. Sounds like it's not worth reading about.

3:27 technomancy: Chousuke: sort of. I don't think it'll go anywhere

3:27 riddochc: Chousuke: I'd seen some reference about that just the other day, somewhere.

3:27 technomancy: Chousuke: there's a branch to add lexical scope into mainline elisp anyway

3:30 spariev: there is also PicoLisp http://www.software-lab.de/down.html , dynamic scope and interpreter only. claims to be very fast

3:32 riddochc: Dynamic scope again? Weird.

3:32 Then again, I suppose it is a bit easier to implement...

3:35 bartj: Why can I not find "replace-re" function? I get the following error: "Unable to resolve var: replace-re"

3:36 my clojure version - {:interim true, :major 1, :minor 2, :incremental 0, :qualifier "master"}

3:36 technomancy: implementing lexical scope is not rocket science

3:36 all you have to do is read The Little Schemer

3:37 it's a thin book!

3:37 hiredman: I heard lexical scope is slow

3:37 danlarkin: it's all the stack operations it has to do

3:37 riddochc: technomancy: You're right, it's not rocket science, but implementing dynamic scope was the second assignment in an undergraduate computer science class on programming languages, with two prerequisites, for what it's worth.

3:37 hiredman: danlarkin: right, I wonder if they do some sort of peephole optimization these days

3:38 technomancy: danlarkin: well, it's a bit of a memory hog; sure

3:38 danlarkin: clojure's lexical scoping performs the glory hole optimization

3:38 * riddochc snrk.

3:39 spariev: bartj: it looks like replace-re still in clojure.contrib.string

3:40 riddochc: Really, though. Everyone knows lisp is slow. Must be parsing all those parentheses. ;)

3:40 bartj: spariev: but, it seems to be under clojure.contrib - which I have loaded

3:40 vu3rdd: can someone recommend a Free and simple http proxy to monitor the http traffic ?

3:41 I am playing with clj-apache-http and would like to see what is sent over the wire..

3:41 danlarkin: here's a paper referencing the issue I'm talking about with lexical scope stack popping: http://portal.acm.org/citation.cfm?id=996546.996548&coll=GUIDE&dl=ACM&CFID=89537219&CFTOKEN=90578418

3:41 riddochc: vu3rdd: It's not a proxy, but try wireshark.

3:42 vu3rdd: riddochc: thanks. I know about wireshark, but I wanted to know if there is something more simpler, which can just show http traffic

3:42 There is something called charlesproxy, but it is not really Free

3:43 riddochc: vu3rdd: I often just use the Tamper Data plugin for Firefox.

3:43 technomancy: huh huh he said balls

3:43 vu3rdd: riddochc: thanks, I will look at it.

3:44 I want something like firebug which runs on the unix shell.

3:44 spariev: bartj: hm, what exactly do your use/require statements look like ?

3:46 riddochc: vu3rdd: it's not exactly a proxy... but it'd show you pretty much all the same stuff you'd see in some report from a proxy.

3:47 vu3rdd: riddochc: thanks. I just installed it. Will play with it.

3:51 bartj: spariev: I don't have any use statements. I assumed since the jar files were in the classpath, it would pick it up automatically

3:51 spariev: but, I guess I have to put something like (use 'clojure.contrib.string) to make it work?

3:52 spariev: bartj: yep, exactly

3:52 bartj: spariev: it works, thanks

3:55 spariev: it looks like both use and import are the same

3:55 riddochc: bartj: Not exactly...

3:56 Though I'd have to look it up to tell you the difference.

4:01 tomoj: import is for java classes

4:01 use is for clojure namespaces

4:03 riddochc: tomoj: Thanks. I have a somewhat better chance of remembering that, next time I have to know.

4:05 spariev: one friend of mine thinks The Little Schemer is a bit schizophrenic book. But, he's a Haskell fan, so I'm taking hist opinion whit a big grain af salt :)

4:22 bartj: tomoj: thanks...

4:59 _na_ka_na_: hi all, what's the simplest way to get current date time in Clojure

5:03 spariev: ,(java.util.Date.)

5:03 clojurebot: #<Date Tue May 25 02:08:20 PDT 2010>

5:04 eevar2: might be worth looking at joda time (which probably has bindings in contrib)

5:04 danlucraft: +1 to that

5:05 spariev: here's also http://github.com/clj-sys/clj-time - clojure wrapper around jodatime

5:33 _na_ka_na_: thanks i'll take a look @ clj time

6:21 bartj: (find-doc "fmap")

6:21 ,(find-doc "fmap")

6:21 clojurebot: ------------------------- clojure.contrib.monads/m-fmap nil Bind the monadic value m to the function returning (f x) for argument x

6:41 _na_ka_na_: hi, say I have a fn named myFn ... now I have String s "myFn" ... how do I find documentation of myFn using String s ?

6:44 hellooo anyone there? why is it so quite!

6:45 LauJensen: _na_ka_na_: Im not sure its possible. (defn mfn [] nil) defines a symbol containing a function. (symbol "mfn") would give you the correct symbol but with no data attached.

6:48 _na_ka_na_: LauJensen: Thx for the response, why does (doc (symbol "myFn")) .. throw exception. .java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

6:49 spariev: _na_ka_na_ : you may want to use (find-doc "myFn")

6:49 LauJensen: ,source doc

6:49 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

6:49 LauJensen: $source doc

6:50 _na_ka_na_: spariev: no, I know the name of the fn in a string, just trying to lookup meta for exactly that fn

6:51 bartj: is a hash-map a sequence?

6:52 _na_ka_na_: yes it is

6:52 ,(seq {:a 1 :b 2})

6:52 clojurebot: ([:a 1] [:b 2])

6:55 vu3rdd: how do I create a jar without AOT compilation using mvn + clojure-maven-plugin?

6:55 i.e. just the clj files alone

6:55 kasperlanger: _na_ka_na_: (:doc (meta (ns-resolve *ns* (symbol "map"))))

6:56 I'm sure there's an easier way to do this

6:57 _na_ka_na_: kasperlanger: many thanks!

6:57 kasperlanger: You're welcome

6:59 _na_ka_na_: ,(:doc (meta (ns-resolve *ns* (symbol "map"))))

6:59 clojurebot: "Returns a lazy sequence consisting of the result of applying f to the\n set of first items of each coll, followed by applying f to the set\n of second items in each coll, until any one of the colls is\n exhausted. Any remaining items in other colls are ignored. Function\n f should accept number-of-colls arguments."

6:59 _na_ka_na_: ,(doc (ns-resolve *ns* (symbol "map")))

6:59 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

6:59 _na_ka_na_: kasperlanger: any idea why the above is throwing exception

7:00 kasperlanger: doc is macro

7:00 Take a look at how it's implemented

7:01 spariev: (ns-resolve *ns* (symbol "map")) just does not get evaluated

7:02 btw, ns-resolve *ns* could be substituted by resolve

7:02 ,(:doc (meta (resolve (symbol "doc"))))

7:02 clojurebot: "Prints documentation for a var or special form given its name"

7:04 bartj: is there a function to remove keys which have "nil" values in a map?

7:04 tomoj: I don't think so, but it is not very hard to make one

7:05 do you ever have false as a value?

7:05 if not:

7:05 ,(into {} (filter val {:a 3 :b 4 :c nil :d false}))

7:05 clojurebot: {:a 3, :b 4}

7:05 bartj: no always, nil

7:06 tomoj: filter will make it into a seq, so we have to stuff it back into a map with into

7:06 if you are doing other seq operations, only do the into once

7:06 _na_ka_na_: ,(into {} (filter nil? {:a 3 :b 4 :c nil :d false}))

7:06 clojurebot: {}

7:06 tomoj: ,(into {} (remove nil? {:a 3 :b 4 :c nil :d false}))

7:06 clojurebot: {:a 3, :b 4, :c nil, :d false}

7:07 tomoj: you need this if you can have false:

7:07 kasperlanger: I guess (print-doc (resolve (symbol "map"))) would be the best way to do it then

7:07 tomoj: ,(into {} (remove (comp nil? val) {:a 3 :b 4 :c nil :d false}))

7:07 clojurebot: {:a 3, :b 4, :d false}

7:07 kasperlanger: '(print-doc (resolve (symbol "map")))

7:07 ,(print-doc (resolve (symbol "map")))

7:07 clojurebot: ------------------------- clojure.core/map ([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]) Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments.

7:08 _na_ka_na_: yes thats what I was planning 2

7:08 kasperlanger: :)

7:09 _na_ka_na_: better to use ..

7:09 ,(print-doc (resolve (symbol "clojure.core/map")))

7:09 clojurebot: ------------------------- clojure.core/map ([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]) Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments.

7:10 bartj: key, val are functions?

7:10 which take only one argument?

7:10 , (doc val)

7:10 clojurebot: "([e]); Returns the value in the map entry."

7:13 bartj: tomoj: I don't understand how val is used in - "(filter val {:a 3 :b 4})"

7:13 because val is supposed to return the value of the map

7:13 and (val {:a 3 :b 4}) does not work!

7:14 _na_ka_na_: bartj: val returns value of *a map entry*

7:14 ,(map val {:a 1 :b 2})

7:14 clojurebot: (1 2)

7:14 tomoj: bartj: correct

7:14 bartj: do you know about seqs yet?

7:14 _na_ka_na_: (seq a-map) gives a list of map entries ...

7:14 tomoj: yeah, a seq of map entries

7:15 filter, map, and functions like them call seq on the collection

7:15 so each time val is called by filter, it is called with a map entry

7:17 bartj: , (doc val) takes only one argument!

7:17 clojurebot: "([e]); Returns the value in the map entry."

7:17 _na_ka_na_: yes that argument is a map entry

7:17 tomoj: ,(seq {:a 1 :b 2})

7:17 clojurebot: ([:a 1] [:b 2])

7:17 tomoj: ,(class (first (seq {:a 1 :b 2})))

7:17 clojurebot: clojure.lang.MapEntry

7:18 tomoj: filter calls the predicate on elements of the coll's seq, and returns a seq

7:18 bartj: my main doubt is this: (into {} (filter val {:a 1})) works but not (val {:a 1})

7:18 tomoj: yes, because filter does not call val on {:a 1}

7:18 it calls val on elements of the map's seq

7:18 ,(first (seq {:a 1 :b 2}))

7:18 clojurebot: [:a 1]

7:18 tomoj: ,(val (first (seq {:a 1 :b 2})))

7:18 clojurebot: 1

7:19 tomoj: filter converts the map into a seq of map entries before processing it

7:19 it then returns a seq of map entries (only the ones for which the predicate returned true)

7:19 this is why we have to squash it back into a map with (into {} ...)

7:19 otherwise...:

7:19 _na_ka_na_: ,(val (clojure.lang.MapEntry. :a 100))

7:19 clojurebot: 100

7:19 tomoj: ,(filter val {:a 1 :b 2 :c nil :d false))

7:19 clojurebot: Unmatched delimiter: )

7:20 tomoj: err

7:20 ,(filter val {:a 1 :b 2 :c nil :d false})

7:20 clojurebot: ([:a 1] [:b 2])

7:20 _na_ka_na_: also

7:20 ,(key (clojure.lang.MapEntry. :a 100))

7:20 clojurebot: :a

7:21 bartj: tomoj: got it!

7:21 tomoj: I wonder if it would be good to make protocol versions of filter, map, etc

7:21 which return the original type and work really quickly

7:23 _na_ka_na_: tomoj: didn't quite get what you mean, map filter etc. work with sequences currently

7:24 cemerick: yeesh, there are people complaining about no 1.2 release yet :-/

7:26 tomoj: _na_ka_na_: yes, I'm wondering if I want something that _doesn't_ work with sequences

7:27 bartj: tomoj: is there a way to write a "for loop" over a hash-map then?

7:27 tomoj: sure

7:27 for operates on the seq of the coll as well

7:27 so each time around, the binding will be to a map entry

7:27 which you can destructure like a seq, so:

7:28 ,(for [[k v] {:a 1 :b 2}] [k (inc v)])

7:28 clojurebot: ([:a 2] [:b 3])

7:28 tomoj: ,(into {} (for [[k v] {:a 1 :b 2}] [k (inc v)]))

7:28 clojurebot: {:a 2, :b 3}

7:28 tomoj: see, here also, it might be cool if there were a version of for which could bind over maps, would return a map, and would use transients

7:29 using it would mean it wouldn't work as part of a chain which had other seqable types in it

7:29 but they could just have the same names in a different namespace, or slightly modified names, so switching would be easy

7:30 _na_ka_na_: for example you mean, for-map .. which takes map as input and avoids calling seq?

7:31 tomoj: yeah

7:31 _na_ka_na_: might be a good idea, but any other benefits apart from performance?

7:31 tomoj: except there's no need to tag the function names with types

7:31 because of protocols

7:31 _na_ka_na_: currently they work to a uniform abstraction..

7:32 hmm .. so u mean at runtime it will call apt. map depending on the protocol?

7:33 tomoj: yeah

7:33 but it's fast

7:33 no, performance is the main benefit

7:34 but it also might be nice sometimes to avoid stuff like (into {} ...)

7:34 the repackaging you have to do when you just want the same type back goes away

7:34 _na_ka_na_: Hmm .. sounds a good idea to my naive self .. post on g groups?

7:35 tomoj: I think I will try working on it a bit

7:37 bartj: tomoj: for the earlier question of removing nil values from a map, I came up with this...

7:37 ,(defn remove-nil [map] (for [[k v] map] (if-not (nil? v) [k v])))

7:37 clojurebot: DENIED

7:38 bartj: ,(defn remove-nil [m] (for [[k v] m] (if-not (nil? v) [k v])))

7:38 clojurebot: DENIED

7:38 bartj: , (into {} (filter (complement nil?) (remove-nil {:a 1})))

7:38 clojurebot: java.lang.Exception: Unable to resolve symbol: remove-nil in this context

7:39 cemerick: bartj: you can't define new fns in clojurebot's sandbox

7:40 tomoj: bartj: great success

7:40 it seems a bit overcomplicated, though

7:40 ,(into {} (filter (comp nil? val) {:a 3 :b nil :c false}))

7:40 clojurebot: {:b nil}

7:40 tomoj: oops

7:40 ,(into {} (remove (comp nil? val) {:a 3 :b nil :c false}))

7:40 clojurebot: {:a 3, :c false}

7:41 bartj: tomoj: yes

7:43 tomoj: the other day my boss did (dorun (map (fn [_] ...) (range 0 10))) instead of (dotimes [_ 10] ...)

7:43 I mean, you will get better at using clojure's expressivity if you keep using it

7:44 bartj: tomoj: that is a beauty

8:12 can anyone point to a great reference to "code styling guidelines" for clojure

8:12 something like what Linus Torvalds has written for the the Linux Kernel (in C)

8:13 Link: http://www.linuxfromscratch.org/alfs/view/hacker/part2/hacker/coding-style.html

8:19 anyone?

8:22 dnolen: bartj: clojure mostly follows lisp conventions. One difference is the tendency to not mark constants since everything is immutable anyway.

8:24 bartj: dnolen: I find the above link by Linus the authoritative source on coding conventions, is there any such created by McCarthy or *the* reference?

8:24 cemerick: dnolen: I continue to believe that marking vars that should not be rebound with plus signs is good practice.

8:25 bartj: this is the closest there is to a style guide: http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards

8:27 hoeck: bartj: http://norvig.com/luv-slides.ps

8:28 bartj: cemerick: my major beef is with indentation

8:29 cemereick: and the above link does not seem to have any comments on that

8:29 cemerick: and by that I mean, where to place the paranthesis

8:30 spariev: bartj: http://mumble.net/~campbell/scheme/style.txt

8:31 cemerick: bartj: I was just about to paste spariev's link :-)

8:32 I prefer 2-space indents, but that's me.

8:32 bartj: hoeck: that link is a beauty :)

8:33 Lajla: bartj, are you Dutch?

8:33 bartj: for eg: I wrote a definition which looks like this:

8:33 (def z (zipmap (keys a) (map (fn [x] (when (get a x) (get labels (get a x)))) (keys a))))

8:33 I have no clue where and when the paranthesis should start in a new line - sigh

8:33 Lajla: no

8:35 spariev: thanks for the link. Just asking, are there any differences between scheme and clojure coding conventions - since, that link seems to be for scheme

8:37 spariev: bartj: you are welcome. I don't think there are many differences, thay both are lisps after all

8:37 s/thay/they

8:38 btw, this link is mentioned in leiningen README

8:41 cemerick: There's a variety of syntactic differences, which spill over to style.

8:42 rhickey: http://groups.google.com/group/clojure/msg/16cc11e863625358

8:42 spariev: I'm not very knowledgeable about scheme, I should add :)

8:44 SynrG: rhickey: super. nice site, btw

8:45 rhickey: SynrG: thanks

8:47 chouser: rhickey: congrats!

8:47 rhickey: chouser: thanks!

8:48 Lajla: ,+

8:48 clojurebot: #<core$_PLUS___3868 clojure.core$_PLUS___3868@1b149e1>

8:48 Lajla: Cool

8:51 bartj: can anyone confirm that it is not possible to view documentation for a symbol in vimclojure

8:52 *using vimclojure

8:53 chouser: that seems unlikely. maybe \lw

8:54 cemerick: rhickey: congrats :-)

8:54 rhickey: cemerick: thanks

8:55 bartj: rhickey: perhaps, you would like to add a newsletter so that users can get info on discounts, training programs, schedules, etc.

8:56 rhickey: bartj: good idea

8:58 cemerick: rhickey: on a third reading, your role seems a little murky -- are you going to be working on Relevance projects, etc?

8:59 rhickey: cemerick: I will not be coding on Relevance projects, but I will be working with the team. And they will be working with me (on Clojure)

9:07 chouser: I'm a little surprised by the 20% time. Several companies these days spend that much time on various open-source projects without claiming it as some kind of core concern.

9:09 rhickey: chouser: what aspect is surprising?

9:09 chouser: it seems small

9:10 Of course I can't say it ought to be different or that it's somehow wrong, I just would have expected it to be a bigger slice of the company's time.

9:11 cemerick: Maybe 20% of the non-rhickey team members? *shrug*

9:12 rhickey: chouser: A commitment to dedicate 20% of developer time to specific projects seems like a large investment to me.

9:12 cemerick: right, that number does not apply to me

9:12 chouser: oh, that's interesting. I assumed it did.

9:13 as in, maybe 100% of Rich's time, but none of the other 4 devs.

9:13 cemerick: Yeah, that's part of the murkiness I was talking about before.

9:13 * rhickey rereads

9:13 chouser: or it's friday, everybody close tickets for a day.

9:13 cemerick: rhickey: the impression I got was that you are Guido to Relevance's Zope, or something.

9:14 rhickey: cemerick: not sure I get the analogy

9:14 chouser: yes, basically David, Stuart, Aaron et al will spend Fridays on Clojure itself

9:15 cemerick: rhickey: I might have the history wrong, but IIRC, gvr joined zope, which sponsored him working on python core "a lot", but he was part of the day-to-day at the company.

9:16 chouser: hmph. did I not have a patch that pointed out which line began an unclosed paren?

9:19 rhickey: cemerick: It is a joint venture, and I am not an employee of Relevance

9:25 esj: rhickey: an exciting development, nice !

9:26 rhickey: esj: thanks

9:27 s450r1: Clojure/core seems like an excellent development to me. Seems like it means at least 4 extra people get to spend one day a week working directly on Clojure. Hope everything works out!

9:30 rhickey: s450r1: yes, thanks!

9:33 * chouser compares and contrasts visual style of clojure.com with lispworks.com

9:33 cemerick: ha

9:34 I do wish lispworks would jump over, though.

9:35 chouser: jump over?

9:35 * chouser imagines lisp-shaped candlesticks

9:36 cemerick: chouser: I want a clojure plugin for eclipse from them, or somesuch.

9:36 chouser: oh I see

9:36 cemerick: Can't imagine the CL space is a growth business.

9:36 * cemerick waves $500 in the direction of lispworks, wherever they are.

9:36 rhickey: cemerick: I thought you wanted them to open-source it

9:37 cemerick: rhickey: I think it might be wise of them to do so, but no, that's not a key criterion for me (as long as the kit works)

9:37 The actual, current lispworks env has little value to me though. Can't imagine it'd ever get open sourced.

9:38 * rhickey pays for LispWorks every year, largely now to see them continue to exist

9:38 cemerick: rhickey: you should send them a note, prodding them to get into the clojure tooling biz :-)

9:39 cgrand: rhickey: congrats for clojure/core

9:39 rhickey: cgrand: thanks!

9:40 cemerick: rhickey: BTW, I wasn't trying to bring you down at all before -- just mirroring how I read the ann. Free message consulting, FWIW. ;-)

9:40 rsynnott: cemerick: lisp companies ALWAYS have crap-looking sites. It's traditional :)

9:40 cemerick: one nice thing that Lispworks has is an acceptable cross-platform GUI thing

9:40 oh, and a tree-shaker

9:40 rhickey: cemerick: that kind of feedback is very important right now, keep it coming. To the extent the message is confusing we need to fix it

9:40 cemerick: rsynnott: um, yeah...acceptable :-)

9:40 rsynnott: distributing a desktop app with lispworks seems far more practical than, say, with sbcl

9:41 cemerick: there's no such thing as a good one :)

9:41 cemerick: rsynnott: swing is pretty darn good for what it gets you IMO

9:41 chouser: I thought qt-jambi had so much promise. :-(

9:42 cemerick: rhickey: in that case, the positioning of the relevance logo ahead of the clojure logo is a big signal IMO.

9:42 rhickey: cemerick: signal of what?

9:43 cemerick: (that coming from someone with (almost) no skin in the game, and I'm sure Stu & co. want maximum visibility for relevance)

9:43 rhickey: that it is fundamentally a Relevance operation.

9:43 chouser: yeah, that was a big loss

9:44 I'm on the brink of seriously evaluating swt (again). We'll see how that pans out.

9:45 rhickey: which, again, isn't a bad thing, but that's the impression IMO *shrug*

9:45 rhickey: cemerick: from the operations side, that's not incorrect - they are bringing their (quite sophisticated, IMO) agile practice to bear here

9:47 eevar2: meh. swt is never the right answer

9:48 cemerick: rhickey: well, the *operations* distinction is a fine one. People may assume clojure direction, etc. is determined by relevance., or that clojure.org is the "open core" of the more advanced clojure.com.

9:48 eevar: it's just a widget toolkit. I find it hard to get worked up about them.

9:48 rsynnott: Oh, yes; that's far too nice-looking to be allowed to be a commercial lisp site

9:49 rhickey: cemerick: I'm not sure I see that. This practice isn't selling Clojure itself, in any form. It is fundamentally a service company, based on Clojure, that also works to sustain Clojure.

9:50 cemerick: what might help clarify that?

9:51 rsynnott: rhickey: perhaps swap the 'Why Clojure' and 'Why Clojure/core' sections?

9:51 as it is, the one saying that this particular website is is below the fold

9:52 so it does look a bit like clojure.com is the site for clojure itself

9:52 rhickey: rsynnott: good point

9:52 cemerick: rhickey: insofar as one is familiar with "open core" business models, the fact that clojure/core is @ clojure.com, with open source bits @ clojure.org implies that alignment pretty strongly

9:53 rsynnott: (I initially thought it was something along the lines of erlang.se when I saw it

9:53 (erlang.se is a licensed erlang with support and certification)

9:55 cemerick: the .com/.org relationship is pretty well established -- sugarcrm, zenoss, etc.

9:59 rhickey: cemerick: but barring giving up use of clojure.com (which I wouldn't consider), what's actionable? Just the logo order?

10:04 cemerick: rhickey: I'd drop the clojure logo entirely, and put a prominent link to clojure.org *saying* what is being linked to.

10:04 arkahn: It seems pretty clear to me: Why Clojure speaks to the language and Why Clojure/core speaks to the services offered by Relevance. One change I would make is adding a "Learn More About Clojure" underneath Why Clojure and have that point to clojure.org

10:06 cemerick: Beyond that, a declaration of what the organization *is* is warranted. Is this just a PR site for relevance? A separate unit within relevance? A loose collaboration between some relevance folk and some community folk? The about page doesn't clarify these things either.

10:07 * cemerick feels remarkably uncomfortable giving advice like this, even though rhickey asked for it :-|

10:07 arkahn: from a business aspect, I realize you don't want to drive people away from the commercial motivation that is Relevance, but making a stronger distinction between clojure.org and clojure.com (while tying the two together) seems like a good idea

10:07 rhickey: cemerick: It's ok, I'm free to ignore it :)

10:08 cemerick: I do think the lead paragraph here is clear - http://clojure.com/about.html

10:09 cemerick: rhickey: again re: the domains, punching "clojure" into many browsers will now go to clojure.com instead of the actual project (perhaps that intentional). Further, depending on the vicissitudes of google, the .com may end up ranking higher than the .org for a straight "clojure" search.

10:09 rhickey: "specialized technical practice brought to you by..." is mud to me *shrug*

10:09 Dawgmatix: just some feedback - the top center is what the user sees first, i think the front page under communicates what clojure/core does

10:10 Chousuke: I agree that clojure.org should be more clearly linked from the clojure.com page

10:10 perhaps link the first metion of "Clojure" in the intro paragraph to clojure.org?

10:11 that would make it stand out somewhat

10:11 Dawgmatix: having the first para from clojure.com/about.html on the front center on the mainpage would answer a new visitors questions on what clojure/core does instantly

10:11 fogus: rhickey: Cool Venn diagram. :-)

10:12 cemerick: fogus: did you catch that twitter convo yesterday re: macros vs. scala's call-by-name?

10:12 fogus: cemerick: No I missed that one. Did someone say they are equivalent?

10:13 cemerick: fogus: that the latter are a superset, even!

10:13 chouser: someone said macros are a subset

10:13 cemerick: I don't know what call-by-name is in scala, but I was surprised by that.

10:13 chouser: but others jumped on that so I didn't have to. :-)

10:14 fogus: cemerick: Cool! Can't wait until Clojure finally grows up and gets call-by-name :p

10:16 Chousuke: :P

10:16 what languages have call-by-name?

10:16 fogus: So call by name let's you do some of what macros give you, but uses currying, lambdas, and the fact that foo{} is a function call to make looping things. It's fairly nice, but I would never say it is a superset of macros

10:17 cemerick: oh, I found a tutorial I grok now

10:17 Chousuke: link?

10:17 clojurebot: your link is dead

10:17 Chousuke: :P

10:17 cemerick: Chousuke: http://www.naildrivin5.com/scalatour/wiki_pages/CallByName

10:17 That is just nutty.

10:18 I love this: "The syntax => String is different than () => String; the first form indicates that a String is expected, but will be passed by name, not value; the second indicates a function taking no arguments and returning a String is expected. This is somewhat subtle, as you could certainly think of the first case as a no-arg function that returns a String."

10:18 fogus: It's sugar

10:19 cemerick: yeah; it's the kind of sugar that makes ruby unintelligible to me, too

10:21 fogus: Anyone have a link to the superset comment?

10:21 Chousuke: Did someone actually claim that call-by-name offers a superset of the functionality of macros? :/

10:21 cemerick: yes

10:22 fogus: http://twitter.com/eikke/statuses/14649976180

10:23 Chousuke: I'd say it's the other way around

10:23 cemerick: oh yeah

10:23 fogus: Well, I would say they are orthogonal

10:24 Chousuke: there seems to be some overlap.

10:24 tomoj: how could it be a subset?

10:24 cemerick: really? Isn't c.c.logging doing exactly what the tutorial was showing, but with macros.

10:24 And macros are obviously more capable than simple value substitution.

10:24 fogus: I meant orthogonal mechanisms

10:24 cemerick: ah

10:25 Chousuke: Can you think of anything you can do with call-by-name that is not possible (or is significantly more difficult) with macros?

10:25 fogus: The scala cbn is sugar on top of a higher-order curried function

10:26 Chousuke: I suppose you can't do compile-time computations with cbn

10:27 fogus: I can't think of anything that macros can't do, but I'm not fully conversant on the whole set of CBN use cases. :-)

10:31 A Twitter search for call-by-name is fun

10:37 patrkris: does anyone know why Clojure does not use read time stamps in its implementation of MVCC, while database systems do (according to Wikipedia)? Why are databases concerned with read time stamps?

10:41 stuarthalloway: patrkris: clojure cares about relative time

10:42 patrkris: stuarthalloway: can you elaborate?

10:44 chouser: patrkris: reads aren't tracked in clojure's STM, is that what you're referring to?

10:45 patrkris: chouser: yes

10:45 i was just looking at wikipedia's definition of mvcc, and in that definition, reads _are_ tracked

10:46 and I don't quite understand why that is necessary, when multiple versions are available

10:49 rhickey: patrkris: that definition is biased towards databases, where you don't have GC 'tracking' of read references to older data

10:50 patrkris: and where tracking reads is nothing compared to I/O costs

10:50 chouser: a read can cause a retry in clojure if the history isn't deep enough, right? is that true of db mvcc as well?

10:53 patrkris: chouser: seems to be the case in oracle at least

10:53 chouser: I'm having trouble thinking of any way it could be avoided.

10:54 patrkris: rhickey: you're thinking about the I/O cost of potentially reading an older version from disk?

10:54 chouser: Back when I was using SQL DBs a lot, I don't think I had any idea transactions could be retried.

10:55 patrkris: chouser: none of us did - i didn't even use transactions, because I never thought I would have concurrent users :)

10:56 chouser: heh. well, I was using SQL Server and multi-threaded ASP, so we were definitely thinking about transactions. But apparently not as deeply as we thought we were.

10:57 rhickey: patrkris: I'm just saying you're not going to see read tracking even addressed as an issue for disk-based MVCC since other factors dominate

11:10 patrkris: rhickey: my problem is understanding why databases track reads, when it isn't necessary in e.g. Clojure? Do you have any idea? What does it give database systems? I am sure I'm just overlooking something.

11:10 rhickey: patrkris: as I said, no GC in databases

11:11 patrkris: rhickey: ah, and reading a version would create 'garbage' that would need to be be handled somehow?

11:11 rhickey: so how would the db know it could reuse the disk space?

11:13 cemerick: rhickey: replaca brought up the notion of an available? fn (with accompanying addition to the reference interface(s)) last night; we talked about this a while ago (http://clojure-log.n01se.net/date/2009-08-18.html#11:34c) -- would you welcome a ticket?

11:16 rhickey: cemerick: same questions still apply - where does it go in the abstraction hierarchy, what about timeouts etc

11:17 cemerick: rhickey: Sure -- I just figure it'd be better to have a spot for that discussion. I'm lining up my early 1.3 wish-list items :-)

11:19 rhickey: cemerick: how about a design page on the wiki first?

11:19 cemerick: oh, sure

11:19 rhickey: IMightDeref, IBlockingDeref et al

11:20 Fossi: faridcmi: any reason to query me?

11:21 cemerick: rhickey: so you're still opposed to just adding a method to IDeref (say, with overloads for timeouts)?

11:22 rhickey: cemerick: It makes no sense for many reference types

11:24 cemerick: rhickey: always returning true for those cases (atoms and refs, right?) seems reasonable *shrug*

11:25 rhickey: cemerick: could return true for numbers and collections too

11:25 cemerick: you lost me there.

11:27 rhickey: cemerick: taking a boolean op and making it always return x given some y for which it makes no sense

11:27 the mere availability of available? might cause people to wonder

11:28 is a var or ref or atom ever not available?

11:28 do I need to protect against that?

11:29 cemerick: vars can be unbound, but I get your point

11:29 rhickey: cemerick: is there a problem with available? only being available where it makes sense?

11:30 cemerick: Insofar as a majority of impls of an interface usefully carry certain semantics, it seems fine to default the minority. IMO, of course.

11:30 stuarthalloway: seems like you would want available?-available? to check

11:30 rhickey: yikes

11:30 stuarthalloway: sorry, had to be said :-)

11:30 cemerick: heh

11:30 rhickey: :)

11:30 available?-available? should take a timeout also

11:31 ah, polling

11:32 cemerick: rhickey: no problem, no (aside from yet-another-interface). Given my majority/minority comment above, simply adding to IDeref seemed reasonable to me.

11:33 remleduff: Why add it to IDeref interface instead of making an Available protocol?

11:35 cemerick: A good point. Where do things stand w.r.t. using protocols in core ("policy"-wise, perhaps)?

11:35 rhickey: cemerick: new abstractions are perfect candidates for protocols

11:37 KirinDave: rhickey: Is there a good example in the clojure code, or anywhere, that really shows what you envision protocols being best at?

11:37 rhickey: I get the gist, but I'm still not sure that I feel like I understand how they're really intended to be used.

11:37 fogus: KirinDave: have you looked at gvec.clj?

11:38 KirinDave: Nope.

11:38 I will look right now.

11:38 fogus: There is not much guidance WRT protocols there though

11:38 http://github.com/richhickey/clojure/blob/master/src/clj/clojure/gvec.clj

11:38 But it's a start

11:39 cemerick: There's IOFactory in clojure.java.io as well. http://github.com/richhickey/clojure/blob/master/src/clj/clojure/java/io.clj

11:39 rhickey: KirinDave: unfortunately the bulk of Clojure was written before protocols existed, but they'd be great for any of Clojure's abstractions currently implemented as interfaces, such as Seqable. Moving forward, some of these will be moved to protocols

11:41 KirinDave: rhickey: I see.

11:41 fogus: rhickey: Sorry if I missed an official announcement, but will cells make it into 1.2?

11:42 rhickey: fogus: unfortunately not, simply not done yet

11:42 KirinDave: It's funny. I used to be a huge CLOS proponent.

11:42 But I really like the way this protocol code looks.

11:42 fogus: rhickey: OK, thank you. That gives me a reason to push for a 2nd edition one day. ;-)

11:42 KirinDave: Single dispatch is sorta limited, but people make do with it for the bulk of their time programming, I guess. :)

11:44 rhickey: KirinDave: yes, and multimethods are not going away

11:45 KirinDave: but even when multiple dispatch is available, I would guess it is used less than 5% of the time

11:47 KirinDave: rhickey: In Clojure, you mean? :)

11:50 There does seem to be a fair amount of trepidation about the performance of multimethods in clojure. I've yet to find it to be a problem, but I guess I seldom write things where the tight loop is the bottleneck, these days.

11:51 cemerick: They're absolutely fast enough for "app level" stuff -- it's just an additional fn invocation and map lookup.

11:51 KirinDave: How well do they jit down?

11:52 I imagine if the type becomes stable over repeat invocations they'd be amenable to some pretty aggressive tracing optimizations.

11:52 cemerick: as well as it'd be able to optimize any other fn invocation, I presume

11:53 KirinDave: Hum.

11:53 cemerick: KirinDave: oh, but the method that is dispatched to will never get inlined, and the dispatch itself will never get JIT'ed

11:53 KirinDave: I just wonder if the JIT could figure out that if there are type constraints matched earlier on, the map lookup could be skipped.

11:54 I suppose the VM would have to become aware of what's going on directly to figure that out without some more aggressive trace-tree stuff.

11:54 cemerick: the dispatch can't be optimized away given the way it's implemented right now. Multiprotocols might be a different story, but I don't know how far/near they are. Certainly not in 1.2.

11:57 bartj: rhickey: I am sorry to ask this...but has anyone asked you about the "Bus Factor" of Clojure? (http://en.wikipedia.org/wiki/Bus_factor)

11:59 stuarthalloway: bartj: what you would you do about the "bus factor" issue?

11:59 fogus: bartj: I imagine any language < 3 years old has the same bus factor

12:00 esj: set up a group of developers to work with key man so knowledge spreads ? oh wait...

12:01 bartj: stuarthalloway: I am not sure if a question as a reply is appropriate here...

12:01 stuarthalloway: bartj: all right then

12:02 if I were worried about the bus factor, I would (1) learn the tech and make a bunch of contributions myself

12:02 then I would (2) encourage other people to do the same by helping get patches approved

12:02 * replaca arrives late to the discussion of IDeref/available?

12:02 stuarthalloway: and then, just maybe, build a sustainable business around growing (1) and (2) until the bus number factor gets lower

12:03 but my question is a serious one: do you see something that is going undone here?

12:04 * stuarthalloway has considered body armor for Rich :-)

12:05 replaca: rhickey: my idea was pretty much just to have an interface IDeref2 (name TBD) that has an extra bool isAvailable() method. The available? fn is just (if (instance? IDeref2 x) (.isAvailable x) true)

12:06 interested objects could implement that

12:06 bartj: stuarthalloway: er, you mean higher?

12:07 stuarthalloway: bartj: right. Sorry, I think in terms of risk, not the bus number metaphor

12:07 replaca: rhickey: my primary interest here is so pprint doesn't hang crossing promises/futures, though laziness also poses some challenges here

12:07 cemerick: stuarthalloway: the bus factor notion is mostly a canard I think. Outside of what you just talked about, other people often look for something like a PEP as a check that there's some "sanity" around direction, etc. Most people aren't comfortable with hashing things out in irc. :-)

12:08 (note that I'm absolutely not suggesting the establishment of a corollary process)

12:08 stuarthalloway: cemerick: I simply found today an amusing moment for the issue to come up

12:08 and don't we do a lot of hashing out here? :-)

12:08 cemerick: heh

12:08 yeah, we do, but this ain't where the morts hang out, generally

12:09 stuarthalloway: ironically, there will probably be *more* questions about "bus factors" and such for a while.

12:09 The chasm is *really* wide, depending on which one you're talking about. :-)

12:11 mefesto: I'm using c.c.http.agent in a script which seems to never terminate. I'm guessing some background thread is keeping it alive even though there's no more work to be done. Is a (System/exit) the way to go or is there another way?

12:11 stuarthalloway: cemerick: I wasn't on IRC earlier today, but we have made a bunch of website changes to clarify questions you and chouser brought up

12:11 cemerick: mefesto: Yeah, that's due to the agents using non-daemon threadpools

12:12 A (System/exit 0) is fine; invoking (clojure.lang.Agent/shutdown) should have the same effect at the end of a script.

12:12 (where shutdown tears down those threadpools)

12:13 mefesto: cemerick: ok, thanks :)

12:13 bartj: I didn't mean to offend anyone asking inane questions, about bus factors...

12:13 stuarthalloway: bartj: no offense given

12:13 remleduff: Or (shutdown-agents) which does the same thing

12:13 bartj: I just read this - http://www.3ofcoins.net/2009/01/30/common-lisp-clojure-and-seriousness/ and it threw me off track - since I am pretty much *starting* learning clojure

12:14 cemerick: bartj: The term is a *little* silly, but the impulse is very natural for most :-)

12:14 bartj: cemerick: morts = mortals ?

12:14 cemerick: remleduff: ah, I didn't know about that -- been using the interop form for way too long...

12:15 stuarthalloway: bartj: clojure is abstraction-oriented, not merely implementation-defined

12:15 bartj: the article you reference is a gut reaction, lumping Clojure where it does not belong

12:16 cemerick: bartj: no, "Mort" is a term (perhaps slightly disparaging) used to refer to developers that don't really know a lot about CS, etc.

12:16 alpheus: Is it reasonable to create-ns a sandbox for experimenting and then remove-ns when you're done?

12:16 cemerick: bartj: originally talked about here: http://www.nikhilk.net/Personas.aspx

12:17 stuarthalloway: bartj: consider lack of stability

12:17 cemerick: Mort == the fellow who puts HTML on his resumé as his primary programming language, etc., Elvis is a relatively decent developer, might put out some libraries here and there, Einsteins are people who write their own languages, etc.

12:17 anyway...

12:17 stuarthalloway: some languages *change* fast. Clojure is *growing* fast

12:17 the difference being that there is very little deprecation or breaking change in Clojuer

12:18 in that respect it is more like Java than the so-called "toy languages"

12:20 cemerick: stuarthalloway: The changes are good. I suspect you'll still get questions along those lines, esp. from those coming into clojure totally green (I keep coming back to the domain names -- they're quite powerful branding devices). Anyway, as I said to rhickey, this is supremely not my business anyway. :-|

12:21 AWizzArd: Some changes though are a bit more breakish than others. For example, I noticed that duck-streams was renamed to clojure.contrib.io and now was renamed again.

12:21 cemerick: conrib is *not* the stdlib :-)

12:22 stuarthalloway: AWizzard: not renamed again. Both should be present, in order not to break people

12:22 AWizzArd: I am trying to prevent gratuitous breakage to contrib, if you see such, let me know

12:23 cemerick: your opinion and feedback are *most* welcome

12:23 remleduff: Is the current form of last-var-wins final? It seems like it will make it tough for library writers to support both 1.1 and 1.2 now

12:23 stuarthalloway: remleduff: example?

12:23 cemerick: stuarthalloway: well, don't go saying that. rhickey did, and look where that got him. ;-)

12:23 remleduff: Sorry, just speculating

12:24 stuarthalloway: remleduff: not trying to put you on the spot! Hoping not to break people, and also to make it super easy to just go to 1.2

12:24 remleduff: But what if you used flatten from contrib before? What should you do now?

12:25 replaca: stuarthalloway: I was about to go through contrib putting deprecated tags on stuff (pprint, duck-streams, etc.). Should I go ahead and do that?

12:25 stuarthalloway: remleduff: if you want to still support 1.1, you can still use flatten, and it will work with a warning on 1.2

12:25 replaca: that would be great!

12:25 fogus: cemerick: It seems that macros are also a subset of C macros. :-) http://twitter.com/eikke/status/14703031487

12:26 replaca: stuarthalloway: k. It's probably still a couple of days out. Swimming in the autodoc mire.

12:26 cemerick: fogus: I *knew* it! Screw you guys, I'm gonna sling some C.

12:26 fogus: cemerick: According to TIOBE you should be able to find a lot of work

12:27 cemerick: fogus: I got a job before you even msg'd me back. C *and* Tiobe FTW!!1!

12:27 remleduff: stuarthalloway: Actually, better example. What if your library defines a name that is now taken by core? At one point with last-var-wins, your version would win, now I think core's will win?

12:27 cemerick: eh, long day already :-P

12:28 stuarthalloway: no, your version still wins

12:28 with a warning

12:28 remleduff: Oh, I misunderstood the last commit then, sorry

12:28 THought it made last-var-wins only work for core

12:28 cemerick: remleduff: refers to core always defer to what you have in your ns.

12:28 stuarthalloway: somebody probably made a crappy commit comment :-)

12:33 remleduff: Is anyone around who could give me permission to post on clojure-dev?

12:43 Question about protocols: Is the following a reasonable expectation, or is Impl expecting too much for its methods to survive this? http://gist.github.com/410416

12:44 In current master, it throws a "method not found" exception

12:50 If you don't want to look at the gist, it's defining a protocol, extending it to a type, removing the functions from the protocol, then adding them back to the protocol.

12:51 After that sequence, the protocol is no longer extended to the type

12:51 Which is fine, but less convenient for somet things

12:52 Guess I'm all alone, talking to myself. ;)

12:59 OK, so even redefining a Protocol to have only exactly the same or only new methods still loses all extenders

13:00 So I guess defprotocol really implies a completely clean slate for the protocol

13:03 Hmm, that's not completely true either

13:05 dnolen: remleduff: I'm not a protocol expert but in general you can't do overly "dynamic" things with them. That's not their purpose anyway. If you want a ridiculous amount of flexibility/dynamism use multimethods.

13:05 remleduff: OK, so redefining a protocol with no changes, preserves extenders. Adding or removing methods to the protocol, makes a clean slate

13:05 hoeck: remleduff: thats a bug

13:06 no, sorry, that was another one, where reevaluating a deftype does nothing

13:08 remleduff: Another question, is it intentional that it's fine to only partially implement a protocol?

13:09 stuarthalloway: remleduff: yes!

13:11 remleduff: OK, but satisfies? checks that it completely implements the protocol

13:18 Actually, not sure I understand what satisfies? is testing

13:19 I really like source being imported into the repl by default :)

13:22 So extenders? returns the list of classes that extend a protocol with "extend", "extend-type" or "extend-protocol", it doesn't give you classes that define a protocol inline? ... Is there any way to get the full list of all classes that are implementing the protocol?

13:24 Also, there's the same split between satisfies? and extends? Both of which kind of lie -- if your users don't fully implement the protocol, you can potentially get an AbstractMethodException for any invocation of a protocol method.

13:25 stuarthalloway: you can't get all implementers of a Java interface either

13:25 and they can also lie

13:26 both of which are things Java does right, IMO

13:26 this feels a little academic, what are you trying to do?

13:27 remleduff: I was creating a test case for an issue, but I'm trying to understand if it's actually an issue or just a problem with my understanding of the intent

13:30 I'm don't like having the low-level satisfies? and extends? predicates without any abstract satisfies-or-extends? predicate. Why should an implementer care how the Protocol was extended? And that same dislike falls through to the "extenders" function I guess.

13:31 s/I'm/I/

13:31 stuarthalloway: frankly I don't use these fns

13:32 maybe we have done too much, rather than not enough

13:32 remleduff: I can definitely see that argument

13:35 I don't think extenders is implementable in a way I would consider useful (at least without doing some sort of classpath search), because it only catches half of the classes that implement the protocol

13:37 * stuarthalloway thinking about i1

13:37 stuarthalloway: it

13:38 remleduff: Another question: Is there any way to ask, given a function and some arguments, what function is going to be called? I'd like to get the var so I can call print-doc or source on it. I had the same question with multimethods as well, sometimes it can get a little hairy figuring out what is being called.

13:40 slyphon: does compojure's daddy hang out in here?

13:45 LauJensen: slyphon: no, but he's very active on the group

13:45 slyphon: ah

13:46 LauJensen: compojure group that is

13:46 * slyphon nods

13:46 slyphon: i'm trying to do something slightly wacky, i can't use the jetty-server-setup conveniences, unfortunately

13:48 LauJensen: What are you trying to do ?

13:48 slyphon: well, i have a jetty server that I constructed myself that's supporting an XMLRPC servlet

13:49 (constructed programmatically, that is)

13:49 so now i need to add on a small REST service

13:49 i guess i could spawn another Jetty on a different port

13:49 but that seems kind of...ew

13:50 LauJensen: slyphon: maybe this helps? http://groups.google.com/group/compojure/browse_thread/thread/f718748a32331375/798b33a018ea9141?lnk=gst&q=rest#798b33a018ea9141

13:51 slyphon: LauJensen: hrm

13:51 LauJensen: i'll have to study this

13:52 LauJensen: but thanks :

13:52 :)

13:52 LauJensen: np

14:12 cemerick: fogus: you forgot the inflammatory, baiting headline: "The problem with perl is parsing."

14:12 beat me by mere seconds, you did! :-P

14:12 fogus: cemerick: There's still time for me to edit. :-)

14:13 cemerick: That's where the money is!

14:13 :-)

14:14 fogus: Actually I should have Simply said "Perl sucks. JVM Clojure Scala Erlang Arc Paul Graham"

14:14 cemerick: yup, then resubmit 3 weeks later with a different link and shuffle the keywords

14:15 KirinDave: Hackernews has really been pissing me off lately.

14:15 A lot of unreasonable people who are scala proponents seem to have fox'd my six.

14:15 LauJensen: fogus: what the headline on HN?

14:15 KirinDave: http://news.ycombinator.com/item?id=1375199 (this keeps happening)

14:16 cemerick: KirinDave: then you must not watch the twitters. The macros/call-by-name thing keeps getting better.

14:16 LauJensen: oh, found it

14:16 KirinDave: cemerick: Please reference me. I love torturing myself.

14:17 cemerick: KirinDave: you can just keep refreshing this, or @eikke's feed http://search.twitter.com/search?q=clojure+call-by-name

14:18 KirinDave: Haha

14:18 Very first one.

14:18 Whattttttt?

14:20 cemerick: hrm, that's four down-with-scala conversations here in as many days.

14:20 or, maybe more generously, "Golly, those scala folk are funny sometimes."

14:21 LauJensen: cemerick: you mean, people are knocking scala?

14:21 KirinDave: cemerick: i actually rather like scala.

14:21 cemerick: Not as much as clojure, but it's a fairly good iteration on Java.

14:21 cemerick: LauJensen: it gets knocked with some regularity, yeah.

14:21 fogus: KirinDave: I love this http://news.ycombinator.com/item?id=1375166

14:21 LauJensen: ah ok

14:21 cemerick: KirinDave: which is to say...... ;-)

14:21 ~scala?

14:21 ,scala

14:21 clojurebot: java.lang.Exception: Unable to resolve symbol: scala in this context

14:22 cemerick: hrm, used to have some funny sayings

14:22 LauJensen: scala would actually win more than a few comparisons against Clojure even still

14:22 KirinDave: Sure.

14:23 cemerick: Every now and then I get the urge to give it another whirl. I do really like static typing, but then it screws me.

14:23 LauJensen: cemerick: eh? Static typing is a pure money maker

14:25 cemerick: LauJensen: lots of consulting hours? ;-)

14:25 LauJensen: exactly

14:25 Its the fastest way to turn a 500 hour project into a 550 hour project

14:25 cemerick: well see, I don't do consulting :-)

14:25 LauJensen: oh

14:25 Yes then its bad, because it adds no real value to the product

14:26 cemerick: I wouldn't say that at all, but there are absolutely downsides to be aware of.

14:26 fogus: "Scala is just a misguided attempt to dumb-down Haskell to the level of the peasantry" -- Fake Tony Morris

14:27 LauJensen: Cruel :)

14:28 cemerick: I think it's remarkable that MS is where a top-notch, widely-supported, statically-typed FP lang came from.

14:28 KirinDave: cemerick: It's the only thing that keeps me warm at night

14:28 cemerick: C# is a pretty grisly scene.

14:28 cemerick: Not only is it an ugly language with lots of fiddly legacy syntax

14:28 cemerick: KirinDave: oh, you're in MS-land, aren't you?

14:28 KirinDave: Yes

14:28 I am an employee for now.

14:29 Vest in peace.

14:29 cemerick: right, powerset

14:29 replaca: KirinDave: do you know that you work downstairs from me?

14:29 KirinDave: But C# also has bad class design

14:29 ordnungswidrig: When I read about darcs and the sophisticated use of static typing, higher rank types, phantom types and all those stuff the compiler… Then I come to the conclusion to stay with dynamic typing and throwing a bunch of unit tests on it

14:29 KirinDave: replaca: Please tell me you're with ustream.

14:29 replaca: no 3vr, why?

14:29 KirinDave: replaca: Or are you from that other company, 3vr

14:29 Ah

14:29 cemerick: hearing about what Miller's going through with ClojureCLR makes me a little scared

14:30 replaca: pissed @ guardian :-)

14:30 ?

14:30 KirinDave: replaca: I want to give a friendly shit-talking to the ustream people for having 40 employees and 2 floors

14:30 replaca: ahh!

14:30 KirinDave: cemerick: The CLR is not the raddest virtual machine around.

14:30 replaca: planning for growth!

14:30 KirinDave: replaca: Yeah yeah yeah

14:30 cemerick: KirinDave: I don't know anything about its internals, and it sounds like I don't want to.

14:31 replaca: we should take a coffee break and chat clojure-y stuff one of these days

14:31 cemerick: ikvm has shielded me from it, lo these many years

14:31 KirinDave: cemerick: Like all things, MS takes great ideas and bones them

14:31 ordnungswidrig: KirinDave: *g*

14:31 KirinDave: replaca: Sure. I think Ive met another guy from up there too who was doing 3vr stuff.

14:31 chouser: I think what Miller's doing is fantastic.

14:31 KirinDave: chouser: No one is saying otherwise, i think.

14:31 replaca: yup, there are a whole bunch of us.

14:32 chouser: I want Clojure everywhere, and that means having a variety of hosts pushing concerns up into Clojure

14:32 replaca: not much clojure though

14:32 KirinDave: chouser: It's just what he's doing is the equivalent of wading into gunfire a la robocop.

14:32 cemerick: chouser: god's work, it is. I jsut don't envy him.

14:32 chouser: cemerick: I'm with you there.

14:32 KirinDave: Cue robocop theme, cue cheap ricochet effects.

14:32 replaca: KirinDave: Zach Tellman (the penumbra guy) used to work here too, but he went off to google

14:32 KirinDave: Huh

14:33 * fogus_ wishes he had people who were interested in Clojure working nearby

14:33 stuarthalloway: fogus should move the local value of nearby south a bit

14:34 replaca: Q: Does anyone have a pointer to the "offcial" keyword arg syntax that Rich added?

14:34 chouser: fogus_: my plan is to tkae people who are working nearby and cause them to become interested in Clojure.

14:34 KirinDave: So I'm supposed to ask around. Who here isn't working on a clojure book but would be interested in the massively painful process of doing so? I'm friends with a friend of a publisher who's trying to get a new book rolling.

14:34 chouser: I keep trying to do this to coda hale, but he keeps denying me on account of the parenthesis. :(

14:35 chouser: KirinDave: I can sympathize with that reaction, sad though it is.

14:35 fogus_: chouser: I always just hoped I wouldn't have to do any work. ;-)

14:35 chouser: I was solidly there before "on lisp", and even after only reluctantly willing to put up with parens to get at good macros.

14:36 cemerick: KirinDave: Some nut on twitter suggested I should write one. I think it was actually chouser in disguise, looking for company. ;-)

14:36 chouser: hehe

14:36 nice try, but I have good company already.

14:36 KirinDave: cemerick: If you're interested, email me and I can connect you with people who want to do one

14:37 chouser: KirinDave: even then, I spiked lisp-like macros for JavaScript

14:37 KirinDave: cemerick: I think the thrust is to do one more friendly to people with no prior lisp experience. Evidently that is a major complaint about existing books.

14:37 fogus_: chouser: I tried that before too! My head still hurts

14:37 cemerick: heh, that'd be hilarious

14:37 KirinDave: chouser: The thing is, most languages have at least as much decoration as clojure.

14:38 cemerick: I've always tried to channel the common java dev, but that's a tall order.

14:39 replaca: no help on keyword args? example? I saw the checkin, but I didn't see any guidance.

14:40 chouser: ,((fn [a & {:keys [b c d]}] [:args a b c d]) 1 :c 3 :d 4)

14:40 clojurebot: [:args 1 nil 3 4]

14:40 KirinDave: C# rage. Smash it all

14:40 Raynes: replaca: (defn wtf [args here & {:keys [onearg twoarg] :or onearg "something" twoarg 3}])

14:40 KirinDave: Properties can be set via reflection with a 3 argument method. Fields can be set via reflection with a 2 argument method.

14:40 Type dispatch if clouds, ahoy

14:41 Hate this job.

14:41 DeusExPikachu: is it possible to define namespace qualified vars?

14:41 chouser: all named vars are namespace qualified

14:41 or rather belong to a namespace

14:42 DeusExPikachu: ,(def foo/bar 'foo)

14:42 clojurebot: DENIED

14:42 KirinDave: ha

14:42 DeusExPikachu: gives me exception

14:42 chouser: DeusExPikachu: you can't with 'def'. What are you trying to do?

14:42 you don't want to enter the namespace first with 'ns' or 'in-ns'?

14:43 arohner: DeusExPikachu: there's with-ns in contrib somewhere

14:43 replaca: Raynes: thanks!

14:43 arohner: it's something like (with-ns 'foo (def bar ...))

14:43 chouser: you can use 'intern', but you usually shouldn't

14:43 DeusExPikachu: chouser, its a macro that defines calls def, but I need it defined in the current ns not the one where the macro is defined in

14:43 replaca: chouser: you too!

14:44 chouser: DeusExPikachu: if your macro expands to (def foo ...), that'll define foo in the ns where it's expanded -- sounds like what you want.

14:44 if you're providing the name in the macro itself, you may be getting "Can't refer to qualified var that doesn't exist"

14:44 DeusExPikachu: actually technically its not a macro that expands into a def, its a macro that expands into an eval form that contains a def

14:45 replaca: (defn wtf [args here & {:keys [onearg twoarg] :or onearg "something" twoarg 3}])

14:45 oops, putty probs! :-)

14:45 chouser: DeusExPikachu: you're calling eval in a macro? that's likely to hurt you later.

14:45 clojurebot: eval is DENIED

14:45 fogus_: cemerick: So this about sums up my thoughts on the matter (from a chat the other day) http://www.codecommit.com/blog/scala/working-with-scalas-xml-support

14:46 DeusExPikachu: not calling eval in macro, eval is in the expansion

14:46 KirinDave: Man, calling eval in a macro is almost always a sign something is wrong.

14:46 chouser: hm. still dangerous. are you sure you need to call eval?

14:46 KirinDave: I mean, a macro is an elaborate way of prepping an eval.

14:46 DeusExPikachu: yes, cause eval starts up a new classloader

14:46 Raynes: clojurebot: Shush.

14:46 clojurebot: excusez-moi

14:46 chouser: ah.

14:47 well, ok. even so, (eval '(def foo ...)) should use the namespace into which that's expanded.

14:47 what problem do you have?

14:47 DeusExPikachu: chouser, ok, I'm having problems accessing foo though

14:48 chouser, as in it doesn't exist after running macro

14:48 cemerick: fogus_: I'll have to catch this more fully later, but wow, scary stuff.

14:50 chouser: DeusExPikachu: (eval `(def foo ...)) should return the var that is defined, which knows it's fully qualified name

14:50 I just tried it here and it seems to work as you want.

14:50 KirinDave: Man, this eikke stuff is awesome.

14:50 cemerick: fogus_: it seems to me that stuff like this should just be deathly poison w.r.t. retaining developers. i.e. scala looks just great until 6 months later you're knee-deep in xml literals and looking around for a life preserver somewhere.

14:51 eh, 90% of folks probably don't bother / mind

14:51 KirinDave: cemerick: I think that's a problem too.

14:51 And I see it happen with scala peeps around me.

14:52 All sighing and looking long faced, "Man programming is hard."

14:52 But I suppose the same could be said of macros.

14:52 chouser: macros are *fun*

14:52 KirinDave: All of it requires discipline. :)

14:52 chouser: but rarely needed

14:52 cemerick: not IME, but mileage varies

14:53 SynrG: the trick is to reduce all complex problems to trivially solvable problems

14:53 cemerick: I had that "programming is hard" feeling at the end there, when scala ~2.7.1 came out? Rough times.

14:53 SynrG: then all programming is easy

14:54 fogus_: In talking to devs I've found that those who ran away initially thought they were learning Java++

14:54 (Scala devs that is)

14:54 cemerick: that *is* its billing AFAICT

14:54 or Java.Next or some other silliness

14:57 fogus_: Yeah you would think so, but then you go and look at code by Tony Morris, Jonas Boner, or Daniel Spiewak and that is quickly dashed away

14:57 chouser: reading that scala xml page makes me think "writing a language is hard"

14:57 The complexities in Clojure's implementation are quite localized.

14:58 PersistentVector is complex, but the API is simple. localized complexity.

14:58 The reader is complex, but it's output is simple.

14:59 cemerick: but those guys know what they're doing very deeply. If the sell is java.next, but the reality is, you need to be Jonas to really sing with it, that should be game over.

14:59 DeusExPikachu: chouser, here is the paste, maybe you might see something I'm not seeing http://paste.lisp.org/display/100473

14:59 chouser: The STM transaction system is complex, but doesn't touch the compiler or the persistent collection implementation, etc.

14:59 cemerick: The question is, do you need to be a cgrand (for example :-)) to sing with clojure?

14:59 fogus_: cemerick: That's my humble view

15:00 DeusExPikachu: also, dj.cli.repl/main is called externally to start the repl

15:00 chouser: The compiler/emitter may be the biggest undividied complexity, and I want to split that into 2 and document the interface.

15:01 fogus_: Oh yeah, the Clojure compiler code makes my head spin

15:01 chouser: too much java

15:01 fogus_: But that is my own fault for looking at it.

15:01 chouser: heh

15:02 fogus_: I think that Scala is really really really complicated in implementation so that the user experience is only really really complicated

15:04 LauJensen: fogus_: isnt that just because you aren't comfortable with it ?

15:04 fogus_: LauJensen: With Scala?

15:04 LauJensen: yea

15:05 * stuarthalloway laughing

15:06 replaca: Raynes: small correction to your example: (defn wtf [args here & {:keys [onearg twoarg] :or (onearg "something" twoarg 3)}])

15:06 fogus_: LauJensen: Maybe that's it.

15:06 LauJensen: :)

15:06 Raynes: replaca: Small correction to your example: (defn wtf [args here & {:keys [onearg twoarg] :or [onearg "something" twoarg 3]}])

15:06 lrn2sqrbracket

15:06 ;)

15:06 replaca: Raynes: parens around "or" pairs

15:06 Raynes: It doesn't have to be parens, I'm fairly certain.

15:07 replaca: yes, or square brackets, doesn't matter. I was going from Rich's destructuring examples

15:07 chouser: maybe LauJensen doesn't realize fogus_ has contributed to Scala.

15:07 LauJensen: chouser: No I had no idea

15:07 replaca: which are old before the tyranny of square brackets was fully established

15:08 LauJensen: fogus_: I didn't mean it in a derrogatory (?) manner, but rather that people who only rate scala as 'really really' complex, usually havent tried it enough to realize its much more complex than that

15:08 chouser: DeusExPikachu: ok, something squirrely is going on there. don't have my finger on it yet.

15:08 DeusExPikachu: chouser, thanks for taking a look

15:09 chouser: DeusExPikachu: for one, you shouldn't quote the namespace name in 'ns'

15:09 fogus_: LauJensen: I see. I guess my background gave me enough chops to rate as only a double-really n00b.

15:09 chouser: but I assume that's an artifact of the paste, or you'd have different errors. :-)

15:10 DeusExPikachu: chouser, oh yeah, hehe, I hand typed that

15:11 there's other fluff I removed for clarity

15:13 chouser: DeusExPikachu: something's swallowing an exception.

15:13 Can't let qualified name: dj.classloader/classloader

15:14 DeusExPikachu: ah, ok I'll work on that

15:15 chouser: don't think you need let there at all

15:16 DeusExPikachu: chouser, actually yeah, I had some defn's earlier cause I was writing some clojures but in the paste yeah Its not needed

15:17 chouser: I remain dubious that this is the best angle

15:17 you can't just create a classloader of the sort you need?

15:17 * chouser admits to very shallow understanding of classloaders

15:18 patrkris: chouser: is clojure.contrib.command-line the defacto choice for command-line parsing?

15:19 DeusExPikachu: chouser, I suppose I could, but I'd prefer to reuse existing clojure tools, also I don't know how to do that ATM

15:19 chouser: patrkris: I think the defacto choice for command-line parsing is to not do it all. :-/

15:19 patrkris: chouser: Hmm... but I need to do it :)

15:20 chouser: patrkris: that's because you're in the only unixy mindset. In javaworld, we are already in a JVM and just make method calls.

15:20 sorry. not helpful.

15:20 DeusExPikachu: chouser, hmm I simplified it but still can't get the-cl to be resolved in the new repl, `(eval `(do (def the-cl 'foo) ~~@body))

15:20 patrkris: :)

15:21 chouser: patrkris: My point is that I think there is no command-line parser that is heavily used. If command-line is sufficient for you needs, have at it.

15:21 patrkris: chouser: Ok, thanks :)

15:22 chouser: helpful documentation also: http://richhickey.github.com/clojure-contrib/command-line-api.html :)

15:22 DeusExPikachu: patrkris, I think jline was mentioned by stuarthalloway

15:22 patrkris: DeusExPikachu: Will check it out. Thanks.

15:23 chouser: bleh. yeah, sorry about that. There's a barely-more-useful example in a comment at the end of the .clj file.

15:31 DeusExPikachu: it's probably still eating your exception.

15:31 DeusExPikachu: chouser, probably, I'm playing with macroexpand right now

15:31 chouser: good

15:32 also try calling (with-new-classloader :done) or something

15:32 DeusExPikachu: oww my eyes... so much clojure.core...

15:32 technomancy: KirinDave: coda's too smart to really let the parens be blocking him; it must just be his excuse for something else.

15:33 DeusExPikachu: is there a pprint version of macroexpand?

15:33 chouser: macroexpand just returns the form -- you can pass that to pprint

15:34 pprint's code printer can do nice things to it too, but I haven't figured out how to call that conveniently

15:34 replaca: DeusExPikachu: yeah, but it's more complex than that. you want to bind code-dispatch

15:36 DeusExPikachu: see the example here: http://richhickey.github.com/clojure/doc/clojure/pprint/PrettyPrinting.html

15:36 under "Dispatch tables and code formatting"

15:37 BTW, I'm thinking I'll probably add a pp-macroexpand for those not using slime (slime already has it built in)

15:37 vu3rdd: technomancy: ping

15:38 DeusExPikachu: replaca, where's *code-dispatch* defined in?

15:39 stuarthalloway: replaca: name it "wtf?" for "what-the-form?" :-)

15:39 cp2: heh

15:40 vu3rdd: technomancy: Sometime back I was trying to build leiningen using ant for packaging up into debian. Facing some problems with it.

15:40 technomancy: vu3rdd: hmm... danlarkin did that for homebrew; I'd imagine you could take a look at his fork and re-use the stuff he did.

15:41 vu3rdd: also ieure did it for macports

15:41 vu3rdd: technomancy: yes, I reused most of ieure's stuff. I also made a maven pom.xml which works quite fine and creates the jar.

15:41 replaca: DeusExPikachu: clojure.pprint (oh, but it doesn't have the *'s anymore, I'll update the doc) => just "code-dispatch"

15:42 vu3rdd: The problem is that, lein deps hangs with the created jar.

15:42 it copied the deps. But seem to be doing something else after that..

15:46 technomancy: I tried AOT compiling not just the core, but all the namespaces. I also used the exact versions of the ant and ant-launcher dependencies (which are slightly older than the current releases)

15:46 but no success.

15:50 technomancy: vu3rdd: I think the hang-after-deps is fixed in the latest lein; it was due to a maven bug, and we rolled back to an earlier maven.

15:52 vu3rdd: technomancy: you mean the maven-ant-tasks jar version?

15:52 technomancy: right

15:53 vu3rdd: ok. Let me try. Thanks for the help

15:53 Looks like I have a new version of maven-ant-tasks

15:55 technomancy: success

15:55 technomancy: great

15:55 vu3rdd: many thanks

15:55 I spent the whole day here trying to figure out what the problem is

15:55 technomancy: urk; sorry about that. =\

15:55 it will be great to have a .deb available.

15:56 vu3rdd: sure, it is definitely on the way to the archive in a week or two

15:56 lancepantz: vu3rdd: i spent about 5 hours trying to figure that one out too last week :)

15:56 technomancy: vu3rdd: we've got some issues with the repl task and ant's stdin support that's blocking a release of lein 1.2 unfortunately

15:57 vu3rdd: getting lein into debian is absolutely essential to pave way for the rest of clojure packages

15:57 lancepantz: oh! I should read irc and lists more carefully.. :-(

15:57 lancepantz: vu3rdd: there's an issue that references it on github

15:57 technomancy: I need to post that problem to the ml to get more eyes on it. did you just grab the latest git version or the 1.1 stable?

15:58 vu3rdd: technomancy: latest git

15:58 I tried several versions today. I also tried 1.1.0. Every time I thought I had done something wrong since I was creating a leiningen jar myself.

15:59 technomancy: vu3rdd: I had to break the repl task in order to get things working consistently on OS X. since that's not an issue with .deb, perhaps you should work from a slightly older version where the repl task was ok.

15:59 Drakeson: how can I generate an interface that has a function that takes an array as an arg?

15:59 vu3rdd: technomancy: Ok. Let me try 1.1.0 again with this change

15:59 technomancy: vu3rdd: can you post to the mailing list about it so I can get back to you about it after work?

15:59 vu3rdd: technomancy: sure

16:00 I will do that right away

16:01 chouser: Drakeson: arrays derive from Object

16:01 DeusExPikachu: chouser, hmm it was a backquoting problem, changed (defmacro [] `(eval `(do stuff...))) to (defmacro [] `(eval (do stuff..)), that was a bit unintuitive cause eval normally requires a quoted form

16:02 chouser: that eval's not doing anything useful

16:03 DeusExPikachu: chouser, not at the moment, but in the actual code, I bind the-cl to the classloader that changes when eval is called, a side effect

16:03 chouser: I mean the stuff inside (do ...) is being evaluated and the results passed to 'eval', which is probably not what you want.

16:04 DeusExPikachu: chouser, oh....

16:05 lambdatronic: Howdy everyone. I'm wrestling with the mighty abyss of classloader hell, and I'm hoping someone can give me some advice.

16:06 vu3rdd: technomancy: just posted a message to the lein ml

16:07 lambdatronic: I have a JPF application which manages a collection of Java "plugins", each of which has its own classloader instance.

16:09 One of these plugins contains clojure-1.0.jar. However, the other plugins also want to make use of clojure without generating a new instance of the runtime, since it's expensive and would prevent the plugins from sharing code.

16:10 In order to make this work, we hacked RT to make its class loader publically available to the plugin code we wrote. Then we have had to switch out the classloaders by hand each time we wanted to read some clojure code from any plugin.

16:10 This is substantially inelegant.

16:12 Now to make the situation worse, I have a second library which was built on top of Clojure 1.2-master-SNAPSHOT, that I want to integrate into one of these plugins, but clearly this isn't going to be readable by the Clojure 1.0 which the system is already using.

16:12 What I'm wondering is this:

16:13 1) How does *use-context-classloader* work in Clojure 1.2 (since it seems to be defaulting to true now rather than false)?

16:14 2) Which class loader does an AOT-compiled application use (i.e. clojure's DynamicClassLoader or the System class loader)?

16:16 Any takers?

16:16 chouser: you're in deep, man.

16:16 lambdatronic: tell it like it is.

16:16 chouser: :-)

16:16 lambdatronic: I didn't design the JPF application. I wrote the Clojure 1.2 library, and the JPF app designer wants to use it. Major integration clusterfuck.

16:17 chouser: I have hardly anything to offer. I seems that AOT-compiled code is loaded by whatever classloader you ask to load it. They're just .classes

16:17 s/is/would be/

16:17 lambdatronic: Yeah, but there's something a little tricky there that's escaping me.

16:18 chouser: have you looked at Clojure's code around *use-context-classloader*

16:18 ?

16:18 lambdatronic: When you AOT-compile a class that has a (:gen-class) form in its ns macro, you get a myns.class, myns_init.class, and myns_loading-somethingorother.class

16:18 chouser: I don't really understand it, but I could help you find it if you haven't already. Maybe it would make sense to you.

16:18 lambdatronic: but the classes that don't use (:gen-class) just get the init and loading versions.

16:19 chouser: yes

16:19 lambdatronic: I've been digging around in it and parts of JPF for most of the day.

16:19 chouser: ok. I don't grok classloaders sufficiently to be of much help.

16:19 lambdatronic: So here's the rub: do the init and loading classes use the DynamicClassLoader or not?

16:19 chouser: haven't had a need to understand them, so my attempts to read don't stick well.

16:20 lambdatronic: Yeah, it's seriously frustrating. I don't grok it well either, and I've tried reading everything I can from googling, looking at the clojure mailing list, etc.

16:20 chouser: I was able to run AOT-compiled clojure code in a java applet sandbox, as long as no reflection was ever used.

16:20 I think that indicates that the DynamicClassLoader isn't used for AOT-compiled clojure.

16:21 lambdatronic: Could you give me some more details?

16:21 right, that's my understaning from what I've read.

16:21 I'm wondering if the non (:gen-class)ed classes that generate init and loading class stubs fall under that rule.

16:21 or if I have to (:gen-class) all of my namespaces.

16:21 I just have no idea how to test it.

16:21 chouser: gen-class doesn't change anything about the other classes for that namespace.

16:22 lambdatronic: right, of course.

16:22 chouser: it just generates an extra class.

16:22 lambdatronic: Yes, I know.

16:22 chouser: so failing to generate that class shouldn't have any effect on how the others are loaded.

16:22 lambdatronic: And that extra class clearly doesn't use the DynamicClassLoader.

16:22 alright, fair enough.

16:23 the funky thing is that apparently clojure uses a new DynamicClassLoader for each eval.

16:23 chouser: yes

16:23 to overcome problems with PermGen overflow

16:23 lambdatronic: and this allows for redefining vars and such, I understand.

16:23 ah.

16:23 interesting.

16:24 chouser: I think redefining vars doesn't need extra classloader instances.

16:24 I'm not sure about redefining record types

16:24 lambdatronic: oh right, damnit that's what I meant. I read that earlier.

16:25 well, there's this *use-context-classloader* global that rich added awhile back which apparently default to nil.

16:25 chouser: I haven't looked deeply at the implementation of the compiler since deftype was added. I'm sure it's not simpler than it was. :-P

16:25 lambdatronic: and when it's bound to true, the thread class loader is used as the parent of the dynamicclassloader rather than the system classloader.

16:25 chouser: hm, ok.

16:25 lambdatronic: only now, in clojure-1.2 it's defaulting to true, which is confusing me.

16:26 and a lot of the code that seems to have tested for this value in the compiler is all commented out.

16:26 so now I'm wondering if the default behavior changed and what the heck does that mean for me

16:27 sorry, I appear to be bitching without any real solution here.

16:27 chouser: yeah, I'm afraid the lack of response means nobody who knows more is paying attention.

16:27 might be worth dropping a note on the google group.

16:27 lambdatronic: guess not.

16:27 true true.

16:28 DeusExPikachu: hmm didn't know eval changes the ns

16:28 lambdatronic: eh?

16:30 well off to set up the sandboxes again...thanks chouser.

16:30 chouser: sure -- sorry I couldn't help.

16:31 lambdatronic: it happens. we'll meet again. we always do.

16:31 chouser: :-)

16:31 lambdatronic: ;-)

16:32 DeusExPikachu: so I changed my code now to (defmacro foo [] `(eval '(do (def ~'the-cl 'foo) ~@body))), I call this macro in another file, (foo (clojure.main/main)), and in the repl, the-cl is in the 'user ns, not the ns where foo is used

16:33 Chousuke: DeusExPikachu: why are you generating an an eval expression?

16:34 DeusExPikachu: Chousuke, (def the-cl 'foo) should really be (def the-cl (clojure.lang.RT/baseLoader)), i'm grabbing the new classloader

16:35 Chousuke: but couldn't you just do (defmacro foo [] `(do (def ~'the-cl 'foo) ~@body)))

16:35 DeusExPikachu: Chousuke, I'd grab the current classloader, instead of the new one that baseLoader is bound to after running eval

16:36 Chousuke: so eval changes the classloader? :/

16:36 I see.

16:36 DeusExPikachu: from my understanding

16:36 that way after the eval exits, so does the classloader

16:37 but I'm having trouble with the nested quotes right now, can't figure out the right combo to get the-cl in the correct ns

16:38 it needs to be in the ns of the caller of the macro

16:43 remleduff_: You're trying to find the classLoader that created the namespace?

16:45 DeusExPikachu: no, trying bind the new classloader that was added in the context of the new eval, the example is check the value of clojure.lang.RT/baseLoader repeatedly in the repl, it changes with each new eval

16:46 i'm starting a new repl, that started in another eval, but I grab the classloader before calling clojure.main/main, so I can add URLs to the new repl session

16:49 remleduff_: But what's the endgame? You're wanting to recreate add-classpath or something?

16:50 DeusExPikachu: remleduff_, basically, but add-classpath is deprecated, and doesn't work in the repl

16:51 also I want to manage the classloaders, keep track of them etc

16:57 remleduff: How about (.getClassLoader (.getClass @(ns-resolve 'namespace 'symbol)))

16:58 DeusExPikachu: ^^

16:59 DeusExPikachu: remleduff, but I want the new classloader made from eval? not the namespace classloader

17:00 so after the eval, the classloader unloads

17:15 ska2342: Hi. Is it old news that there is a name-clash between clojure.repl and clojure.contrib.ns-utils in the current master branches?

17:16 chouser: ah, that must be because last-var-wins only for core, not repl. bleh.

17:17 lpetit: chouser: worth changing the topic for #clojure and including the brand new clojure.com support site ?

17:17 chouser: I'm opless, unfortunately.

17:18 or perhaps fortunately. anyway, opless.

17:18 ska2342: I haven't been following the last var wins discussion closely. However: WARNING: dir already refers to: #'clojure.repl/dir in namespace: user, being replaced by: #'clojure.contrib.ns-utils/dir

17:18 lpetit: chouser: what does opless mean ?

17:19 chouser: without operator privileges. I can't change the topic.

17:19 lpetit: chouse:r oh, sorry then, my IRC client tells me that "chouser" set the topic for #clojure on Thu 15 Apr 2010 ...

17:20 chouser: ^^^

17:20 chouser: yeah, I had op for a few days. heh.

17:20 lpetit: ok :)

17:20 must go to bed, bye

17:22 ska2342: since functions are migrated from ns-utils to clojure.repl, is that contrib library going to be removed in the future?

17:24 chouser: the migrated functions will probably be removed anyway.

17:25 ska2342: I am currently replacing some usage examples in our book that formerly used repl-utils. It would be a waste of time if the lib I replace it with will be removed in 1.2 ;-) Is there any document I can read that tells me what to expect from contrib in the near future?

17:26 chouser: there are tickets in assembla for everything being migrated to clojure from contrib

17:26 which book?

17:27 ska2342: www.clojure-buch.de, AFAIK the first German book on Clojure to be published. I announced it a while back at the group.

17:27 chouser: ah, yes. Just didn't recognize your nick

17:29 ska2342: To be frank, I think that many (most?) assembla tickets are poorly documented. But then, who am I to complain, I'm not contributing myself...

17:29 DeusExPikachu: woot works

17:31 nested backquoting is tricky, especially when you care about which namespace you want >_<

17:51 ninjudd: it looks like you can't have a function with a variable number of arguments in a protocol. is that right?

17:53 remleduff: Think it probably has to have one non-variadic one to dispatch on by class

17:55 Or... maybe you're right

17:55 ninjudd: remleduff: this doesn't seem to work:

17:55 (defprotocol Foo (foo [foo & args]))

17:55 (deftype Baz [] Foo (foo [foo & args] (println :foo args)))

17:56 remleduff: Yeah, sorry. Defining it works, but actually calling it doesn't seem to

17:56 ninjudd: it creates a method that takes 3 args and binds the second to the symbol &

17:57 does anyone know the reason for this limitation?

18:01 who is an expert on protocols?

18:03 cemerick: have you encountered this?

18:03 bmason: is transaction from clojure.contrib.sql broken in the 1.2 snapshot?

18:03 remleduff: I see a couple of google hits for "protocols varargs" including Rich Hickey saying that "it's not yet supported" but not sure if that means it will be supported. Seems like they're trying to wrap up quick enough that they might not want to change it before 1.2

18:05 ninjudd: remleduff: aha. good to know

18:05 remleduff: thanks

18:12 remleduff: Just speculating... Invoking a protocol function is currently basically just calling a method in an interface, I'm not certain how you'd do varargs efficiently, you have to know the arity of the target so you'd have to store it somewhere so you can look it up without reflection. Protocols are supposed to be host-fast...

18:15 ninjudd: remleduff: that make sense. perhaps protocols could transform a varargs call into a fixed args call where the last argument is a List

18:19 DeusExPikachu: may have found a bug, made a writeup on the ml http://groups.google.com/group/clojure/browse_thread/thread/28cf5de185252896

18:33 remleduff: Is "source" going to move to core?

18:37 DeusExPikachu: How about: (defn foo [& body] `(do (intern *ns* 'the-cl 1234) ~@body))

18:37 DeusExPikachu: sorry remleduff, what are you referring to?

18:38 remleduff: The intern in place of that nasty double-unquote

18:38 DeusExPikachu: ah, good tip

18:43 rsh: when coding in clojure, I often find myself creating functions or macros that create hash tables that I end up storing at the top level in a namespace. Then I have a list of functions that act upon each of these objects. At a very high level, does this seem like idiomatic clojure?

18:57 replaca: is there a way (in Clojure or Java) to do a min on Comparables rather than numbers?

18:58 DeusExPikachu: rsh, seems fine to me

18:59 arohner: replaca: you'd probably have to write your own function

19:01 replaca: arohner: that was the conclusion I just came to

19:01 arohner: replaca: should be pretty easy though. Check out (source min) and (doc compare)

19:01 replaca: but then I decided I didn't need it after all

19:01 thanks!

19:11 technomancy: ,(do (or (do not :there (is (not (try))))))

19:11 clojurebot: java.lang.Exception: Unable to resolve symbol: is in this context

19:11 technomancy: ,(use 'clojure.test)

19:11 clojurebot: nil

19:11 technomancy: ,(do (or (do not :there (is (not (try))))))

19:11 clojurebot: DENIED

19:11 technomancy: ...!

19:11 clojurebot: why do you hate Yoda?

19:11 clojurebot: It's greek to me.

19:14 riddochc: That sounds like the right answer to me.

19:15 technomancy: good point

19:15 riddochc: :)

19:16 That yoda quote always gets used at the most inappropriate times, I think. Meh.

19:22 replaca: technomancy: the keyword syntax lets you cheat a lot there

19:24 technomancy: but you only have to cheat once for that quotation. I think that's significant.

19:27 riddochc: Allowing for reading it left-to-right instead of inside-out, anyway.

19:29 remleduff: I'm kind of amazed no one has used "there" for something

19:30 Licenser: ,(def there def)

19:30 clojurebot: DENIED

19:30 Licenser: ,(there x 5)

19:30 clojurebot: java.lang.Exception: Unable to resolve symbol: there in this context

19:30 Licenser: by the way, night people!

19:59 replaca: technomancy|away: I'll grant you that :-)

20:28 maxhodak: what's the right thing to do when you have a list of items and you want to pick one out? calling filter all the time (which ostensibly does an O(n) search) seems hugely wasteful

20:29 remleduff: Put it in a map and then use get?

20:29 But I don't think that's enough detail ;)

20:29 maxhodak: remleduff: no i can do that, that makes sense

20:30 but my conflict is that lists are much easier to handle as structures (you can just map instead of needing to map/reduce/etc to run through it, and many methods expect colls rather than maps)

20:30 but maps are keyed

20:34 riddochc: maxhodak: It might not be wasteful if your list is short, anyway. Using a map may be faster, but it also just might not matter. Have you measured?

20:35 maxhodak: I'd say it really depends on what you're using that list for. Unless it's actually slow, and you know it's spending a lot of time in filter, I wouldn't worry about it.

20:40 remleduff: If you've got a sorted-set are you supposed to use Collections.binarySearch or is there a clojure function somewhere I'm missing?

21:18 stuarthalloway: chouser: you around?

21:19 ...or anybody else who uses c.c.shell(-out)?

21:21 chouser: yeah, hi.

21:22 stuarthalloway: I am promoting c.c.shell to core

21:22 chouser: cool

21:22 stuarthalloway: and the only thing I wonder about is the weird :return-map stuff

21:23 or more particularly, the returning of out+err mashed together when one doesn't use return-map

21:23 chouser: it struck me as the most common use case.

21:24 things run at the command line dump stdout and stderr together in the terminal

21:24 stuarthalloway: together, but not combined

21:25 chouser: ?

21:25 stuarthalloway: if I wrote to stderr first I would see that first

21:25 in production code I think I would always use :return-map

21:26 I think scripting languages tend to give you back stdout

21:26 and then set variables to let you inquire about stderr and the return code if you want

21:26 that doesn't feel very clojurish though

21:27 chouser: I use the sh function rather rarely. I wonder what options most people use.

21:27 stuarthalloway: was looking around to see that very thing

21:27 pallet uses it once, with :return-map

21:28 c.c.javadoc uses it once, ignoring the return value

21:28 chouser: sh is not a complete wrapper of exec

21:29 stuarthalloway: understood

21:29 my concern is to have the API promise as little as possible

21:29 chouser: the idea was to make the most common uses easy.

21:29 ok

21:29 stuarthalloway: in particular, promise only things we are sure we like

21:30 chouser: hm.

21:30 stuarthalloway: so I am thinking making the current :return-map the default, and only approach

21:30 technomancy: sounds good to me

21:30 stuarthalloway: any first time user getting back a map with :exit, :our, and :err in it would know exactly what they had

21:30 chouser: my only concern with that is it would make the simple case of, say (sh "ls") more complicated

21:31 stuarthalloway: right

21:31 (:out (sh "ls"))

21:31 chouser: right

21:31 stuarthalloway: technomancy: do you use c.c.shell now?

21:32 chouser: if only we had return value polymorphism. ;-)

21:32 technomancy: stuarthalloway: we bounce back and forth

21:32 stuarthalloway: we've been bitten by a JVM bug where exec temporarily needs twice the memory of the parent process, and our heap is always huge

21:32 so we've been wary of it

21:33 stuarthalloway: to be clear: the reason to add this is (originally) to support javadoc

21:33 for the repl

21:33 chouser: oh, I didn't realize javadoc used it

21:33 hiredman: the return map is useful

21:33 technomancy: stuarthalloway: just to launch a browser?

21:33 stuarthalloway: and from there, it's just "what the hell, sh is useful on its own, might as well make it public"

21:33 hiredman: because if my shell process does not exit with 0 I want to know

21:34 remleduff: Why does it return new readers and writers rather than take readers and writers as parameters with defaults?

21:34 hiredman: and I want to throw an exception and log it

21:34 chouser: I'm not going to make much of a fuss either way.

21:34 technomancy: with clojure-http-client we have two nses: a low-level version that returns a map and a higher-level one that translates non-success error codes into exceptions thrown.

21:34 that has worked out pretty well IMO

21:35 hiredman: the return map is not to bad if you destructure it

21:35 technomancy: try/catch around a shell-out seems to better communicate what's going on though

21:35 hiredman: (let [{:keys [exit in out]} (sh ...)] (when-not (zero? exit) (throw ...)))

21:35 technomancy: but it doesn't address stdout/stderr at all

21:36 stuarthalloway: remleduff: designed for repl usage, not as a general purpose api

21:36 hiredman: I do usually get the out as a string

21:36 stuarthalloway: if we could lose the need for sh in javadoc, then I could promote javadoc and leave shell for another day

21:37 it's already a special case branch for the mac

21:37 technomancy: I assume there's no JDK-provided way of launching a browser? man... the things you have to go through to support people who don't use Emacs. =)

21:38 stuarthalloway: technomancy: that is what the code in javadoc suggests

21:39 chouser: I don't see sh in javadoc.

21:39 hiredman: btw, what is the deal with shell and shell-out?

21:40 technomancy: hiredman: it's like duck-streams vs io IIUC

21:40 hiredman: *out of band reply*

21:42 remleduff: There's actually a java 6 way of eating the browser

21:42 hugod: We use shell in pallet, and I modelled clj-ssh after shell as well. I would be quite happy to see the map returned by default.

21:42 remleduff: eating?

21:42 Man I'm out of it

21:44 stuarthalloway: hugod: cool

21:44 remleduff: sadly requiring java 6 not an option

21:44 chouser: javadoc calls browse-url

21:45 browse-url uses sh to avoid repl-utils turning the process into a gui app

21:45 chouser: ah, ok, I see it now.

21:46 remleduff: javadoc.browse is actually trying to use the java 6 way of doing it, if it's supported

21:46 stuarthalloway: which is weird, because it seems that *open-url-script* should be tried first, before open-url-in-browser

21:46 remleduff: that way still seems to make the app into a GUI app

21:47 chouser: stuarthalloway: btw, congrats on clojure/core

21:48 stuarthalloway: thanks! you should abandon your worldly possessions and join us :-)

21:48 chouser: heh. ah, so tempting!

21:48 remleduff: Isn't *open-url-script* mac os specific?

21:51 technomancy: what, you're clojure monastics now?

21:52 stuarthalloway: remleduff: yes, but by using it first, one avoids the app transforming into a GUI app

21:52 at least in the test I just ran

21:53 chouser: remleduff: I think it's just providing a default for mac

21:53 stuarthalloway: if someone else on a mac wants to test this theory: start a repl, use javadoc browse as is

21:54 then change the order tried by browse-url to use the script first. behavior seems better

21:54 remleduff: I read it as trying in turn: 1) Java 6 desktop api 2) If on macosx, shelling out (*open-url-script* isn't defined for any other platform) 3) Using swing gui

21:55 technomancy: 4) use swank. =)

21:56 tetron: question, is there a way to enforce that a particular function call be 'pure' and not have any dirty java interop?

21:56 remleduff: stuarthalloway: What does "turns the app into a gui app" mean? Here, the java 6 method seems preferable, just opens it in a tab in my browser. How can I see if I'm a gui app now?

21:56 stuarthalloway: remleduff: in my case, the app suddenly shows up in the alt-tab circle

21:57 with the generic coffee mug icon

21:57 remleduff: Oh, doesn't happen on my windows 7 at least

21:57 chouser: that sounds like open-url-in-swing

21:57 remleduff: I think that means you're getting the swing app

21:57 stuarthalloway: nope.

21:57 trying the functions one at a time

21:57 remleduff: Interesting

21:58 stuarthalloway: tetron: not easily. and interop isn't dirty :-)

21:59 tetron: stuarthalloway: I haven't dug very deep into clojure, but something I have wanted from a programming language is a way to guarantee that particular code paths is free from side effects

21:59 *are free

22:00 stuarthalloway: tetron: that is a hard thing to do, and clojure doesn't want the complexity required

22:00 haskell does it

22:01 tetron: this is probably simplistic, but it seems like one could "taint" functions based on whether they are provably pure or not

22:04 remleduff: There's a small amount of support for declaring things as transaction-unsafe by using the io! macro

22:04 stuarthalloway: tetron: marking a taint is easy, "provably pure" is not

22:05 tetron: stuarthalloway: fair enough :-)

22:05 stuarthalloway: start to sketch out how you would do that, and in a few years you'll be back with haskell

22:07 tetron: stuarthalloway: and haskell is used to scare small children who don't eat their vegetables :-)

22:07 (eat your peas or it's coding haskell for you! no mommy, no!!)

22:08 I gotta go, thanks for responding though

22:09 remleduff: stuarthalloway: Do we really want a javadoc function? I'd kind of prefer teaching the doc function how to scrape the docs from the javadoc and formatting them in a clojure-ish way

22:13 stuarthalloway: remleduff: how would that work for jars you don't control?

22:13 you'd end up implementing all of the javadoc fn, then refusing to show it in a browser and scraping it to the clojure format

22:15 remleduff: Yeah, that's more work

22:19 Could you use a hook multimethod (*javadoc-fn*) for handling the url so the user can provide a local one?

22:35 replaca: stuarthalloway: except that (doc ) doesn't actually format stuff :(

22:47 remleduff: Oh, there's no easy way to do scraping with just core

23:00 maxhodak: is it just me for is congomongo/insert! totally broken now?

23:00 no matter *what* i do i get a null ptr exception

23:01 same for update!

23:01 johnmn3: I have a swing gui repl that reads the text from a jtextarea. It feeds the characters of text into a function sends a string of text to the repl when it has read in a whole object. It has counters to track the number of open and closed brackets.

23:01 *function _which_ sends*

23:03 it's actually a few different functions that work together. It's way too complex though, the parsing of the objects. I'd like to abstract that job into something more general. Would it make sense to use protocols for that?

23:13 maxhodak: did you try it with a fresh repl?

23:13 DeusExPikachu: is there talk of getting repl-utils into core?

23:18 chouser: DeusExPikachu: parts of it, yes

23:18 source, javadoc, but not show

23:42 rsh: is there a way to get the name in which a struct was created from?

Logging service provided by n01se.net