#clojure log - May 04 2009

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

0:00 hiredman: ,(let [[a b c] '(1 2 3)] (vec a b c))

0:00 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$vec

0:00 cads: verec, I think it would look more elegant as a let binding.. doing the destructing in the argument vector makes it look more messy, I feel

0:00 hiredman: ,(let [[a b c] '(1 2 3)] (vector a b c))

0:00 clojurebot: [1 2 3]

0:00 barkley: I know pattern matching

0:01 like in F#

0:02 can't really do pattern-matching in the channel

0:02 but i understand

0:02 that's why i always liked predicate-dispatch

0:02 verec_: cads, you can always introduce a "destructuring let" right after the argument, if that's the problem???

0:02 barkley: can we meta functions with predicate-dispatch?

0:03 cads: what is predicate dispatch?

0:04 barkley: cads predicate-dispatch : you decorate a function with x < 10 then you dispatch on that

0:04 verec_: cads, predicate dispatch is a) not in clojure and b) not relevant to your destructuring problem ....

0:05 barkley: probably right

0:05 sorry verec_

0:05 cads: verec, heh, I know

0:05 barkley: predicate dispatch is cool though...actually cllojure already has it

0:05 in a way....

0:06 with it's built-in multi-dispatch on normal funcs

0:06 cads: verec_: I was using destructing let before i moved the destructuring to the argument vector, where it looks messy and doesn't tell us what kind of structure we're working with unless we know the structure's keys

0:06 verec_: I think I'll move back to having a separate let, because that's neater

0:07 verec_: cads, in your ideal world, what would you have wished you had instead?

0:08 barkley: verec_: don't you think multi-dispatch is a more natural dispatch then single dispatch?

0:08 cads: I can't think of anything I'd want to be the general case for functions called on structs

0:08 barkley: verec_: i never got your argument for single tree dispath

0:08 danlei: cads: i don't see the problem ... if you prefer (defun foo [s] (let [bar (:baz s)] ...) to (defun foo [{bar :baz}] ...) just use it ... no?

0:09 verec_: cads, you wrote: "I've been thinking of using something more powerful than structmaps". What exactly were you thinking of?

0:11 barkley: I didn't make any argument in favor of either single or multi-dispatch. Not *me* :D

0:12 cads: well I think I'd like to write instead of (defn grav [{a_m :mass a_p :pos} {b_m :mass b_p :pos}] (* a_m b_m (inverse-square a_p b_p))), perhaps something like (defmapfn grav [a b] (* a_m b_m (inverse-square a_p b_p))), where inside the body of the function we have special mappings for things like a_m or b_p, where x_y means (:y x)

0:13 danlei: cads: sounds like symbol-macros

0:14 verec_: cads, you'd want something that does the "destructuring let" for you invisibly? Is that what you are saying?

0:14 cads: yeah, it's duplication of my effort :D

0:15 I think danlei's right, I should just write this up as a macro to use in special cases

0:15 danlei: cads: well, you could, for example write a macro which binds implicitly, if you like that kind of thing

0:15 cads: because there are a lot of cases where I would want to bind things manually

0:16 danlei: cads: but, without symbol macros, it would be the values of (:y x) evaluated, if you really want (:y x), you'd need symbol macros.

0:16 cads: are symbol macros different than what we write with defmacro?

0:17 danlei: cads: in your case, no. in cl, they're there if you for example want an expression bound to a symbol, which yould be a setf'able place ...

0:18 cads: a symbol macro like foo for (:foo x) would be just the same as (:foo x), whereas binding it implicitly in a macro would ... well just bind the value of the form evaluated

0:20 cads: well, my macro will need to take a argument vector, it will have to know which arguments are structmaps.

0:23 then it creates a list of symbols by combining a map's parameter name with its key names, in order to create the bindings for the implicit symbols used in the body

0:25 verec_: cads, how often are you going to use it, since "there are a lot of cases where [you] would want to bind things manually" ?

0:25 danlei: cads: an example of binding implicitly: (defmacro implicitly-bind-foo [[s] & body] `(let [~'x (:x ~s)] ~@body))

0:26 (implicitly-bind-foo [{:x 5}] x) => 5

0:27 cads: danlei that's very spiffy :D

0:28 danlei: cads: many people don't like that kind of thing (it's, more or less) how aif, awhen, etc. are implemented

0:28 cads: but you get the idea

0:30 (should have named it implicitly-bind-x)

0:32 cads: in my macro, we'd have to tell the macro what kind of struct it's dealing with, or give it a list of keys to auto-bind

0:37 eeew, I think I know a way... let (defstruct body :mass :pos), then (defmapfn [:body a :body b] (* a_mass b_mass (op a_pos b_pos))

0:37 err

0:37 that was a premature enter

0:37 that's never happened to me before, I swear!

0:40 (defmapfn foo [:body a :body b] (* a_mass b_mass (op a_pos b_pos))) => (def foo (fn [a b] (let [{:pos a_pos :mass a_mass} a {:pos b_pos :mass b_mass} b] (* a_mass b_mass (op a_pos b_pos)))))

0:41 I dunno, I don't like the underscores

0:44 but, hey, on the wider question, if I come up with something like I like and it modifies the language and adds some feature or changes some syntax, but it feels comfortable and works for me, should I still feel dirty?

0:57 danlei: cads: does that help you? (defmacro implicitly-bind [[keys-to-bind s] & body] `(let [~@(mapcat (fn [key] (vector key (list (keyword (str key)) s))) keys-to-bind)] ~@body)) ... not really tested, and it's late over here

0:58 cads: (implicitly-bind [[x y] {:x 5 :y 10 :z 100}] (vector x y)) => [5 10]

1:08 cads: hello again

1:09 I took a walk and came back and wanted to get back working on my project, not learning macros so

1:10 back in the editor, I was wondering if anyone knows of a syntax highlighting mode for clojure in gnome's Gedit?

1:10 danlei: cads: you've seen what i last posted (implicitly-bind)?

1:10 cads: yeah, that was good

1:11 danlei: cads: you'd just have to make it take several structures, and you're set

1:57 rlb: hiredman: had to kill the process after about 45 minutes -- not sure if it's my code, java, or clojure, but that's far too long for a simple fs traversal.

1:58 (even if it's a decent number of files (~3 million))

2:44 kotarak: ,(nth (iterate rest [1 2 3 4 5 6 6 7 8 9]) 3)

2:44 clojurebot: (4 5 6 6 7 8 9)

2:44 kotarak: ,(nth-rest 3 [1 2 3 4 5 6 7 8 9])

2:44 clojurebot: java.lang.Exception: Unable to resolve symbol: nth-rest in this context

2:44 kotarak: ,(nth-next 3 [1 2 3 4 5 6 7 8 9])

2:44 clojurebot: java.lang.Exception: Unable to resolve symbol: nth-next in this context

2:44 kotarak: hmm..

2:45 ,(nthnext 3 [1 2 3 4 5 6 7 8 9])

2:45 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer

2:45 hoeck: ,nthnext

2:45 clojurebot: #<core$nthnext__4400 clojure.core$nthnext__4400@11e51d0>

2:45 kotarak: ,(nthnext [1 2 3 4 5 6 7 8 9] 3)

2:45 clojurebot: (4 5 6 7 8 9)

2:46 kotarak: Seems to be what unlink1 looked for .....

3:07 danlei: j lisp

3:08 kotarak: o caml?

3:08 danlei: =)

3:36 AWizzArd: Moiners

3:36 kotarak: Moin Moin

3:47 unlink1: Can I solicit style feedback on this implementation http://paste.lisp.org/display/79626 ?

3:47 Usage is like: (println (rpn "1 2 3 + - 2 *"))

3:57 AWizzArd: I find it okay. Only comments are missing, but else the code looks nice.

3:59 comments ==> doc strings

3:59 comments are not needed

4:02 unlink1: I'd ideally like some more concise way to parse either + or 12 identically

4:03 like (get-clojure-object string)

4:03 hoeck: unlink: maybe read-string?

4:03 unlink1: Yeah, but that gives me a symbol for "*", not #<core$_STAR___3341 clojure.core$_STAR___3341@30419d05> or whatever.

4:04 ,((read-string "*") 2 3)

4:04 clojurebot: 3

4:05 hoeck: but you can resolve that symbol, as you do in your code

4:05 unlink1: right, but I'd have to special case symbols.

4:05 hoeck: ,(resolve (read-string "*"))

4:05 clojurebot: #'clojure.core/*

4:06 unlink1: The idea is to treat numbers and operators identically in parsing

4:08 hoeck: and what about:

4:08 ,(read-string (str "(" "1 2 3 + - 2 * 12 +" ")"))

4:08 clojurebot: (1 2 3 + - 2 * 12 +)

4:09 AWizzArd: unlink1: btw, what is that for?

4:10 unlink1: It's an RPN calculator.

4:11 AWizzArd: just for fun?

4:11 unlink1: Hone my clojure & prepare for interviews.

4:13 Cark: hello all

4:13 little question : what's a good java decompiler ?

4:14 or at least on that works on jvm 1.6

4:14 AWizzArd: jad

4:14 http://www.varaneckas.com/jad

4:14 Cark: thanks AWizzArd

4:16 unlink1: Although, checking if something is a symbol and conditionally resolving it is much more concise than parsing integers.

4:19 kotarak: unlink1: btw: you asked yesterday for (nth (iterate rest coll) 3) => (nthnext coll 3)

4:20 unlink1: oh cool. thanks.

4:30 well I guess it's slightly different.

4:30 nthnext will NPE when coll is too small, but nth (iterate rest coll) won't

4:31 kotarak: ,(nthnext [] 3)

4:31 clojurebot: nil

4:31 kotarak: ,(nth (iterate rest []) 3)

4:31 clojurebot: ()

4:31 unlink1: hmmmm

4:31 kotarak: ,(nth (iterate next []) 3)

4:32 clojurebot: nil

4:32 unlink1: er. -> nil instead of ()

4:58 MikeSeth: is there a way to run clojure code in restricted environment? e.g. where java interop & symbol access is not allowed (including e.g. core functions)?

4:59 unlink1: clojurebot might be a good starting point, http://github.com/hiredman/clojurebot/tree/master

4:59 kotarak: I think clojurebot does this.

4:59 AWizzArd: ,(java.io.File.)

4:59 clojurebot: java.lang.IllegalArgumentException: No matching ctor found for class java.io.File

4:59 AWizzArd: ,(java.io.File. "/")

4:59 clojurebot: #<File />

4:59 AWizzArd: hmm, some io is allowed ;)

5:00 kotarak: AWizzArd: File does no IO.

5:00 unlink1: Well, file creation is allowed.

5:00 MikeSeth: and that's implemented without hacking the host clojure environment?

5:00 unlink1: java.io.File creation, that is.

5:00 kotarak: ,(java.io.File. "/nonexistant")

5:00 clojurebot: #<File /nonexistant>

5:00 unlink1: ,(nth (.listFiles (java.io.File. "/")) 0)

5:00 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission / read)

5:00 MikeSeth: TCL is very strong in this respect - you can execute any code in restricted environment where every variable/method access can be intercepted

5:01 unlink1: there you go

5:01 MikeSeth: nice

5:01 thanks for the tip - i'll look in the bot's code

5:01 unlink1: np

5:06 Chousuke: clojurebot just uses the JVM sandboxing features.

5:17 MikeSeth: didnt know JVM had sandboxing - im very new to both

6:35 AWizzArd: rhickey: is it intended that catch inside a (try ...) block will only take a constant as an exception? I noticed that the exception argument can't be parametrized/filled with a variable.

6:38 Example: (let [x Exception] (try (catch x e (println "Hi"))))

6:41 rhickey: AWizzArd: right it can't be a variable because the exception type must get compiled into the bytecode

6:44 AWizzArd: ok, I wasn't sure about that

7:58 Cark: wew !

8:11 unlink1: Is this 1.0?

8:11 kotarak: It seems so.

8:13 Chouser: someone should do this for contrib as well

8:14 AWizzArd: Is there a function that takes a hashmap HM and a key K and returns a hashmap {K (HM K)}?

8:16 kotarak: (apply hash-map (map hm key-list))

8:16 Ops

8:16 (apply hash-map (interleave key-list (map hm key-list)))

8:19 rhickey: Chouser: yes, that would be good

8:21 unlink1: Is a release announcement planned?

8:29 rhickey: unlink1: working on it

8:36 aperotte: hello everyone

9:04 rhickey: It's official: http://groups.google.com/group/clojure/browse_frm/thread/1e661d16bd910ddd

9:05 Cark: that's great news =)

9:05 Chouser: well, congrats and all that! :-)

9:06 duck1123: sweet

9:06 rhickey: thanks to all for your help, especially you Chouser!

9:06 Chouser: heh, aw shucks...

9:06 kotarak: \o/

9:08 Chouser: rhickey: "self-funded

9:08 sabbatical" sounds scary to me -- thanks for doing that!

9:09 rhickey: Chouser: there's no other way things like this get created

9:09 Chouser: I hope you're payed back, in the end, many-fold in money, quality of life (ie. jobs that hurt less), etc.

9:09 unlink1: Thanks a lot everyone for everything that went into 1.0.

9:11 cgrand: rhickey: thanks!

9:12 aperotte: congratulations!

9:13 duck1123: does anyone know what java.lang.NoSuchMethodError: clojure.lang.MultiFn.<init>(Ljava/lang/String;Lclojure/lang/IFn;Ljava/lang/Object;Lclojure/lang/IRef;)V means?

9:14 kotarak: broken build

9:15 duck1123: of clojure? or the calling library? I'm getting this when I try to compile compojure against a recent clojure.

9:16 kotarak: It depends. Might also be something compojure uses eg. from contrib.

9:16 You have to consult the stacktrace where this exception is thrown.

9:17 duck1123: actually, it looks like this one is comming from swank

9:19 kotarak: And this is rather ominuous. I think the string argument was added recently. So this seems to be some new code in combination with an old clojure?

9:22 duck1123_: might it be, that you have some old clojure somewhere? The named constructor is actually the new one. So it seems, that new (compiled) code is used in combination with an old clojure.

9:31 duck1123_: I my call to swank-clojure, and it compiled. so the problem is there somewhere

9:42 rhickey: Site documentation error reports for inconsistencies with 1.0 welcome

9:43 duck1123_: so is the site now updated to 1.0 documentation? (more or less)

9:45 rhickey: duck1123_: I haven't done a thorough review, but have fixed things as I see them, the API page is freshly generated, the example for refs improved, some clarifications to the seq language in lisps, but as I said, proofreading help wanted, also retrying all the examples

9:45 slava: congrats on 1.0

9:45 rhickey: slava: thanks, it's just a start

9:46 AWizzArd: rhickey: is 1.0 now final?

9:47 rhickey: AWizzArd: yup

9:47 AWizzArd: grats

9:47 rhickey: thanks

9:47 AWizzArd: I will inform Heise then :)

9:47 hoeck: AWizzArd: :)

9:48 kotarak: ~then there was 1.0 and suddenly...

9:48 clojurebot: CLABANGO!

9:51 AWizzArd: rhickey: your email address is like your name here in chat, ending in @clojure.org ?

9:52 rhickey: AWizzArd: no, like on the google group

9:52 AWizzArd: ok

9:56 slava: rhickey: so did you have any idea clojure would take off like it did?

9:57 rhickey: slava: none whatsoever

9:58 kotarak: hehe, the good things always come surprisingly...

10:04 tashafa: congrats on 1.0... what a ride!

10:06 duck1123_: I have a feeling that a lot of people will start giving Clojure a fair look now that it is no longer pre-1.0

10:06 cemerick: rhickey: congratulations! :-D

10:10 hiredman: I imagine a contrib jar should be cut

10:11 rhickey: cemerick: thanks

10:12 Raynes: rhickey: Congratulations on 1.0 :)

10:27 AWizzArd: So, reddit already has the news, heise is informed. Where is slashdot? :)

10:28 Raynes: AWizzArd: I was browing my reddit RSS feed and shat my pants.

10:32 wlr: rhickey: (take as-many-as-you-like (iterate identity "congrats on 1.0!"))

10:42 hoeck: rhickey: congratulations, I have been following and programming clojure since it was first mentioned on reddit and it is now my favourite lisp to program with, big thanks!

11:28 eyeris: I am trying to follow the "gen-class Examples" section of clojure.org/compilation. I am on Windows. If I run "java -cp deps\clojure.jar clojure.lang.Repl", I get a repl, but if I create a classes directory and then run this command "java -cp classes:deps\clojure.jar clojure.lang.Repl", I get an exception "java.lang.ClassNotFoundException: clojure.lang.Repl"

11:28 What am I doing wrong here?

11:29 Chouser: his is a shot in the dark, but try a / instead of a \

11:29 this is

11:31 hiredman: eyeris: windows uses ';' as the classpath seperator, not ':'

11:31 eyeris: Ahh!

11:31 The horrors of trying to be multi-platform :)

11:31 cemerick: would it be crazy of me to suggest that deref should be a multimethod (or, that there should be a corollary to seq-on)?

11:32 hiredman: Yeah

11:32 cemerick: it is crazy

11:32 deref needs to be as fast a path as possible

11:32 cemerick: thus my parenthetical secondary option

11:33 hiredman: I have no idea what 'seq-on' is

11:33 cemerick: it's seq, but a multimethod, so you can define how to obtain seqs from things that aren't ISeqs

11:35 hiredman: I see

11:35 cemerick: I find myself creating various kinds of maps where there is a primary value, and the semantics of deref are appropriate.

11:35 hiredman: you can always proxy IDeref

11:35 rhickey: cemerick: I'm still thinking about how to make more of the core fns extensible with multimethods w/o ruining the fast path

11:36 cemerick: really - maps with deref? are they still values?

11:36 hiredman: actually, that kind of sounds like something you could do with metadata too

11:37 cemerick: rhickey: well, I'm not sure. I'm still feeling out the problem space. Consider a cells impl, where there's a particular Value associated with the map object that tracks cell state.

11:37 hiredman: yeah, that's another option I'm considering.

11:39 rhickey: cemerick: I think deref should be reserved for reference types, having not value other than they thing to which they refer

11:39 having no value

11:40 identity equality and hash

11:40 are you just looking for the convenience of @?

11:40 replaca: rhickey: let me add my congrats on 1.0: Clojure is an excellent piece of work.

11:40 rhickey: replaca: thanks

11:42 replaca: rhickey: I missed you the other day - how does Tuesday evening after your JavaOne presentations work for you for an SF clojure get-together? Or is another time better?

11:44 rhickey: replaca: could work, just looking at my schedule - there are lots of BOFs in the evenings...

11:45 replaca: rhickey: let me know what day is best for you. I'd like to start getting the word out in the Bay Area pretty soon so we get a great turnout

11:46 rhickey: replaca: what format are you envisioning?

11:47 replaca: rhickey: not clear yet - I was thinking a few short Work-in-progress type presentation (think poster session), but really I'm pretty open

11:47 or maybe very open :-)

11:47 mostly the idea is to build momentum for CLojure here in the Bay Area since you'll be here

11:50 rhickey: recruiting from the more lisp-y/fp crowd than Java crowd (though they would also be welcome) with a focus slightly above the "look, it's clojure" talk

11:51 rhickey: replaca: well, I'd like to participate, something other than a formal talk might be interesting, if a full talk, Wed. might be better

11:51 cemerick: rhickey: there are circumstances where I have an object graph that is a heterogenous mix of refs, delays, and various maps that have an 'authoritative' value. I'd like to always use the same fn to access them all (right now I'm using an unpack multimethod that has an IDeref dispatch, and then whatever other dispatches exist for other 'container' objects).

11:51 rhickey: cemerick: what you are doing right now sounds correct

11:52 cemerick: I thought that perhaps this is a common use case, and seeing seq-on in contrib made me think that having parallel multimethods for various base fns made sense.

11:52 replaca: rhickey: I wasn't going to put you on the spot for a formal talk since I know you have a busy week, but if you have something you'd like to say to that kind of audience, I'd be happy to provide a forum

11:53 rhickey: replaca: It might be fun to do a town-hall kind of QA session

11:53 saves me some prep as I can wing it :)

11:54 replaca: rhickey: Sounds cool. I was thinking maybe a mix of that and a few early adopters doing quick demos of what they're using CLojure for

11:54 rhickey: replaca: that sounds great

11:54 replaca: rhickey: I know Amit Rathore is doing some interesting messaging stuff I'd love to hear about

11:55 rhickey: replaca: what time of day are you talking about?

11:55 replaca: rhickey: Would Wed be a good night to lock and load or do you want to wait and see?

11:55 clojurebot: rhickey is a T-1000 sent from the future

11:55 replaca: early eve, right after work

11:55 maybe ~5:30 or 6

11:56 but again, I'm pretty open. I figured I'd get some feedback from the peninsula crown about when they could get up

11:56 *crowd

11:57 rhickey: replaca: Let's shoot for Wed then

11:57 6/3

11:58 replaca: rhickey: It's a plan. I'll put my head together with the other BayArea clojurians and fill in the details

11:58 rhickey: We'll keep you posted

11:58 rhickey: replaca: great, thanks

11:58 replaca: rhickey: np

12:02 djpowell: gz on version 1.0!

12:06 replaca: rhickey: On another subject (from response to my posting to the group last night): Could you add a link to the API docs on the clojure.contrib landing page? I think that is beyond my powers. :-)

12:07 rhickey: replaca: http://code.google.com/p/clojure-contrib/wiki/OverviewOfContrib ?

12:07 replaca: rhickey: you got it!

12:09 rhickey: http://code.google.com/p/clojure-contrib/

12:10 replaca: rhickey: Thanks!

12:11 rhickey: np

12:44 hiredman: replaca: clojure-json pukes on the api index

12:44 danlarkin: *gasp*!!

12:45 hiredman: danlarkin: Yeah

12:45 danlarkin: is it valid json?

12:45 hiredman: how would I know

12:45 danlarkin: *shrug*

12:45 hiredman: are there validators or something?

12:46 danlarkin: probably somewhere... could you point me to it? I will try it with simplejson in python

12:46 replaca: hiredman: it was produced by clojure.contrib.json.write

12:46 hiredman: http://clojure-contrib.googlecode.com/svn/wiki/ApiDocIndex.json

12:46 replaca: it's all one huge line :-)

12:47 hiredman: actually google chrome wraps it

12:47 replaca: hiredman: did you cut and paste it or pull it directly?

12:48 hiredman: I pulled

12:48 replaca: hiredman: ok, that should be ok. I haven't really inspected it myself. I was more focused on fleshing out the namespace doc for contrib this weekend

12:49 danlarkin: I believe this json is invalid

12:49 replaca: but in theory, if json.write can write it, clojure-json should be able to read it

12:49 danlarkin: is there a bug in json.wrie

12:49 danlarkin: not if json.write produces invalid json, which it seems to

12:49 replaca: ?

12:50 hiredman: :(

12:50 replaca: danlarkin: can you see what the error is?

12:50 danlarkin: I haven't done any testing on contrib's json implementation, but I know clojure-json does a bunch of special-casing of peculiarities that I didn't see the contrib one do

12:52 replaca: danlarkin: I can convert to clojure-json, but I'd like to make sure that things that are in contrib are correct

12:52 cause they're the ones noobs are going to grab

12:53 danlarkin: "arglists": [[coll, x]]

12:53 that is wrong, coll and x aren't quoted

12:54 replaca: danlarkin: OK, I'll file an issue

12:54 danlarkin: that's just the first thing that jumps out at me, there might be other stuff

12:54 replaca: hiredman: in the meantime, I'll pick up clojure-json for output

12:55 * danlarkin quietly hopes that clojure-json writes it correctly :)

12:55 replaca: danlarkin: other option is to deprecate json.* and replace with clojure-json

12:55 :-)

12:55 we'll find out!

12:58 bradford: Java integration question...if I do an (:import AMQP$PROTOCOL) and then use it via (AMQP$PROTOCOL/PORT) what is the signifigance of the $ - does that mean that PROTOCOL is a nested strcture (class, enum, whatever) inside the AMQP class?

12:58 kotarak: Yes. $ are nested classes.

12:59 bradford: aha, so that is why my imports that tried to get to nested classes via . do no t work, i suppose they must all use $

13:00 yep, works fine now, thanks kotarak

13:00 kotarak: np

13:15 replaca: hiredman: OK, just checked in a version using clojure-json. See how that works for you.

13:16 hiredman, danlarkin: looked good when I eyeballed it. And no longer all on one line :-)

13:16 arohner: grr. java.io.File has a deleteOnExit, but not a deleteOnGarbageCollect

13:17 replaca: arohner: you could simulate with a weak ref

13:17 arohner: ooh, that would be pretty cool

13:17 if there were a clojure fn that did (weak-ref object on-GC-fn)

13:17 danlarkin: oops, looks like there's a bug with the indenting though, the arglists are left-justified

13:17 arohner: i.e. (weak-ref my-file #(.delete %))

13:19 danlarkin: http://www.jsonlint.com/ says the clojure-json produced version is valid, yay :)

13:20 replaca: danlarkin: I was thinking about doing a JSON formatter based on the pretty printer, it could make a nice extension to clojure-json and simplify your formatting

13:21 danlarkin: the big advantage is that the pretty printer has a very smart fill algorithm that can make things go across more than down when appropriate

13:22 danlarkin: but I want to build the official extensible dispatch stuff first

13:22 arohner: that shouldn't be too hard to write, though it's been a long time since I've done weak ref stuff so my memories of the details are fuzzy

13:23 arohner: I think I can figure it out

13:23 thanks for the pointer

13:24 replaca: arohner: np. I'd like to see what you come up with.

13:28 bradford: is this: (def consumerThreads (for [x (range consumerCount)] (new Thread))) the best way to directly approximate this: Thread[] consumerThreads = new Thread[consumerCount];

13:29 I am porting a bit of java and I want to try to port some things directly first, get it working, and then clojureize it. Although Maybe I should just make these agents now.

13:32 arohner: bradford: it's hard to tell, without knowing more

13:32 agents aren't 1:1 replacable for threads

13:32 they basically just compute one value and exit

13:35 danlarkin: replaca: moving the indenting code out of the core encoding code would simplify the encoder a good deal

13:37 AWizzArd: Woohoo! All german readers please note: http://www.heise.de/developer/Clojure-1-0-funktionale-Programmiersprache-fuer-die-Java-Virtual-Machine--/news/meldung/137231

13:38 Make some nice comments :)

13:38 bradford: arohner: I think it is natural in thsi case because I am working with rabbitmq so each agent is an operation that takes something off the queue and does something with it.

13:38 but maybe there is a better abstraction

13:38 Lau_of_DK: AWizzArd: How's your compojure trip going?

13:39 AWizzArd: Lau_of_DK: I am trying to figure out how I can read the port number of out a server object, returned by start-server

13:39 (.getPort server) doesn't work

13:41 Lau_of_DK: k :)

13:41 danlarkin: if only you were rocking madison...

13:42 Lau_of_DK: if only you were including dependencies :)

13:43 danlarkin: If you have surpassed Compojure I'll be happy to start using Clabango instead - As it is right now, Compojure is just really really funky, and webdeveloping has never been remote this fun/productive before

13:45 replaca: danlarkin: that was my theory. that's what the pretty printer does to earn it's dinner and I'd like to see it work for building all sorts of formatted output, not just s-exps

13:54 arohner: paste

13:54 clojurebot: paste

13:54 clojurebot: lisppaste8, url

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

13:55 arohner pasted "untitled" at http://paste.lisp.org/display/79644

13:55 arohner: that call to name resolves to clojure.core/name

13:55 rather than my local name

13:56 hiredman: arohner: I see no call to name

13:57 arohner: the (.delete ~name)

13:57 resolves to (.delete clojure.core/name)

13:57 hiredman: I disbelieve

13:57 arohner: rather than the local in the destructuring

13:57 java.lang.IllegalArgumentException: No matching field found: delete for class clojure.core$name__3618

13:58 rhickey_: user=> (macroexpand-1 '(with-delete [a b] c))

13:58 (clojure.core/let [a b] c (.delete a))

13:58 hiredman: user=> (macroexpand-1 '(with-delete [foo bar] baz))

13:58 (clojure.core/let [foo bar] baz (.delete foo))

13:58 whoops

13:58 clojurebot: works on my machine

13:58 clojurebot: http://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png

14:03 arohner: the image is cute, but not very helpful

14:03 hiredman: if you proxyed whatever you are using that on you could close => delete and just use with-open

14:03 :P

14:03 arohner: I would try in a fresh environment

14:07 arohner: hiredman: about proxying. I've wanted variants of with-open before. I was thinking of making a generic with-f, like (with-f #(.delete %) [my-file (File. "foo")] ...)

14:12 hiredman: wrap-with

14:13 hmmm

14:13 ~def with-open

14:15 just change that (. ~(bindings 0) close) to some arbitrary function call

14:15 arohner: yup

14:16 hiredman: or just wait for rhickey to push scopes

14:16 and use those

14:17 there is always http://github.com/hiredman/clojurebot/blob/9216e6b2f6c5402be06d093d01590a7dd33131c3/hiredman/horizon.clj

14:18 tashafa: ping danlarkin

14:18 danlarkin: tashafa: pong

14:18 tashafa: hey im using your json library..great stuff

14:19 danlarkin: great!

14:19 tashafa: how would you reommend parsing a java date object

14:19 i get an Unknown Datastructure exception

14:20 arohner: push scopes?

14:20 danlarkin: you mean encoding a Date, right?

14:20 tashafa: yup

14:20 Serkan: hi

14:20 danlarkin: tashafa: look at the README, it shows an example of adding a custom encoder to handle writing dates

14:20 tashafa: should I turn it into a javascript Date Object?

14:21 oh ok...thanks

14:21 dnolen: is test-is working for people? I'm up to date with clojure-contrib and clojure, and it doesn't seem to be working at the moment, an error about clojure.core/if being unbound.

14:21 danlarkin: tashafa: no, you should turn it into a string with appropriate resolution for your needs

14:21 Serkan: Is asm bundled with clojure sources a modified version or direct copy?

14:22 tashafa: danlarkin: thanks man

14:23 danlarkin: tashafa: do you see where I mean? also see the docstring for add-encoder in json.clj

14:23 tashafa: yup including the dat-encoder

14:23 date-encoder

14:24 danlarkin: great

14:25 tashafa: thanks again.. should have read thru the readme

14:26 arohner: dnolen: works for me

14:26 clojurebot: for is not a loop

14:26 arohner: dnolen: do you have an example of it breaking?

14:27 tashafa: danlarkin: hmm... does the decoder have the same behaviour?

14:28 danlarkin: tashafa: no, they'll just be read as strings

14:29 tashafa: yeah..i see why

14:29 no type info

14:29 danlarkin: yeah, it's unfortunate, but probably not too hard to encode the logic in your application to handle it

14:29 tashafa: true

14:30 dnolen: arohner: yeah the most basic test.

14:30 dcnstrct: I just wanted to come say congrats on 1.0, and thank you!!

14:30 dnolen: arohner: (deftest foobar (is (= 1 2)))

14:31 arohner: dnolen: and what's the error?

14:31 dnolen: expected: (= 1 2) actual: java.lang.IllegalStateException: Var clojure.core/if is unbound.

14:32 arohner: what happens if you do (doc if)

14:32 ?

14:32 hiredman: ah, I imagine it is because if is a special form again

14:33 dnolen: I get the expected documentation

14:33 hiredman: during the the lazy-seq transition if was made a macro that depended on the if* special form

14:33 that was reverted back a few svn revs ago

14:33 dnolen: arohner: all I have is the ns the test and (run-tests)

14:35 (is (= 1 2)), throws the error.

14:37 arohner: are you running clojure-contrib from source or jar?

14:37 dnolen: what's weird is that if I fully expand the "is" macro it works.

14:38 aroher: I'm running contrib from the .jar

14:40 arohner: you said your clojure and contrib are up to date. Did you svn up contrib without recompiling?

14:41 dnolen: i use the git mirrors, and everything is up to date and recompiled. but let me double check, I'll wipe then out and load them anew.

14:44 arohner: odd that fixed it, oh well :)

14:45 arohner: dnolen: good to hear

14:45 dnolen: arohner: thx for the help.

16:15 Lau_of_DK: danlarkin: How far are you with Madison ?

16:16 danlarkin: Hmmm

16:17 it'd be usable for a small project no doubt, and having someone else use it would help me know what's important to add next :)

16:21 Lau_of_DK: Aha :) Do you have a public roadmap up somewhere?

16:22 danlarkin: no, no I don't

16:22 I probably should, though

16:22 so much to do, so little time

16:33 Lau_of_DK: Would probably make it easier to get into - You know what there is, and whats coming

16:39 danlarkin: yeah, for sure

16:39 any documentation would help I'm sure :)

17:01 Chouser: when is the word "status" preferred over "state"?

17:02 danlarkin: is this our very own Chouser? http://www.ibm.com/developerworks/edu/os-dw-linuxxwin-i.html

17:03 Chouser: heh, it is. That's a bit ... old.

17:03 rhickey_: Chouser: status implies progress/stature/availability, while state merely condition

17:05 Chouser: hm...

17:06 I've got two external systems that each have a state (status?), and I'm polling info both to decide how and when to update one of them.

17:06 hiredman: :D

17:06 XFree86

17:06 Chouser: hiredman: yeah. back when you had to configure it.

17:06 rhickey_: Chouser: what's in the polled-for info?

17:07 Chouser: so I have in my clojure program snapshots of the status (state?) of each, and in at least some fns access to old versions.

17:08 one is phone, so I get the text output of a query, a boolean conclusion about whether the phone is on the hook or not, a flag indicating if that conclusion should be believed.

17:09 it currently also contains config info about how to connect with the phone, but I think that probably belongs in a separate ref, perhaps an atom.

17:09 the other is jabber status, which contains an id, type, message, and title.

17:10 and I just realized I'm using both the words "state" and "status" in various places, apparently randomly. :-P

17:11 rhickey_: Chouser: on hook or not smells like status, but queries/messages neither status nor state

17:11 Chouser: the jabber api here uses the word "status", and that may be appropriate for all cases in this codebase.

17:13 Cark: call state : state machine ... phone state : status onhook ? hum not sure ...then again i'm no native speaker

17:14 Chouser: I'm collecting all that extra info mainly for diagnostics later. Both these systems are proving to be a bit squirrely, and I'm sure I'm going to get error reports on things I can't reproduce.

17:14 hiredman: all the dictionary definitions of status seem to only relate to people and not inanimate objects

17:14 Chouser: ...so i'm hoping to provide an option to turn on a repl and can ask the user to query things like the text output from the phone, etc.

17:16 Cark: i wonder what's your application doing, care to tell us ? or should it be kept a secret ?

17:16 Chouser: no, it's pretty simple. I've already explained the bulk of it.

17:17 when it notices the phone status has changed, it calls a function that can look at the phone and jabber status and decide how to change the jabber status.

17:18 by default, when you pick up the phone the jabber status will change to "Away -- on the phone". When you hang up (if you've changed nothing else), it goes back to whatever it was.

17:18 Cark: oh i see, nice =)

17:19 rhickey_: Chouser: that's definitely status then

17:19 Chouser: it's pretty specific, though -- assumes one particular kind of SIP phone and that you're using libpurple for jabber.

17:19 Raynes: Did anyone notice that Slava Pestov congratulated Rich in that reddit thread? Also said "Now I need to get Factor 1.0 out this year..."

17:19 Chouser: ...on linux.

17:19 rhickey_: ok, thanks.

17:20 Cark: i had much success using yate as a sip gateway, this one works with any sip phone

17:20 just direct the trafic to it

17:20 and get all the signaling

17:20 from a socket interface

17:21 Chouser: directing the traffic sounds like you'd have to mess with firewall rules or something?

17:22 Cark: well that's a carrier grade piece of software, so you get nat traversal and stuff bundled with it

17:23 though the endopoint you're calling will see the name and password from yate

17:23 instead of your p^hone

17:23 Chouser: interesting -- I may have to look at that later: could open up a lot more options.

17:25 Cark: what i would love to do, is write a sip stack with clojure

17:25 that would be the killer app =P

17:25 ctdean: This is probably Clojure 101, but how do I do the equivalent of (new java.util.Set<java.lang.String>) ?

17:25 So, Java generics

17:25 Chouser: just skip the type-arg part

17:26 It'll Just Work.

17:27 Cark: chouser : the problem about it is testing, you need real phones and gateways to do proper testing

17:27 ctdean: so it does, thanks!

17:27 ,(new java.util.HashSet)

17:27 clojurebot: #<HashSet []>

17:27 Cark: anyways =P enough dreaming !

17:47 opqdonut: why isn't 1.0 in the topic?-)

17:49 Chouser: nobody knows how to change it

17:49 hiredman: #clojure generally has very little op presence, there may be no one around who can change the topic

17:58 powr-toc: Does slime work with clojure 1.0/

17:58 ?

17:59 danlarkin: there's only the one op

17:59 and I have only ever seen him on once since september

17:59 hiredman: yeah

17:59 very littel

18:01 technomancy: powr-toc: it should as long as you've got the latest swank-clojure

18:02 powr-toc: technomancy: thanks

18:25 cipher: how might I call a C function from within clojure?

18:26 sohail: cipher, you'd need to use JNI. I think there is a "pure" Java way to do it

18:26 JNA?

18:26 cipher: clojurebot: JNA?

18:26 clojurebot: It's greek to me.

18:26 sohail: cipher, https://jna.dev.java.net/https://jna.dev.java.net/

18:26 https://jna.dev.java.net/

18:26 sorry...

18:27 cipher: thanks

19:04 powr-toc: Which SVN commit is clojure 1.0?

19:05 rhickey: Which SVN commit is clojure 1.0?

19:12 rhickey_: powr-toc: 1362

19:13 powr-toc: rhickey_: was just looking at that... it looks like the github mirror is a few commits behind

19:14 though the commits it's missing appear to be solely version number changes

19:14 rhickey_: is it only grabbing trunk?

19:15 powr-toc: rhickey_: yeah, looks like it... I'm not sure how it's being mirrored, but I use some unnoficial apache git-svn mirrors, and they correctly grab everything

19:15 rhickey_: also, is it worth creating a 1.0 tag in the svn tags directory?

19:15 rhickey_: powr-toc: just looking at that

19:16 powr-toc: awesome!

19:18 rhickey_: congratulations on 1.0 btw! Very glad to see it! :-) Though I'm intrigued by post 1.0 development (out of curiosity, not yet necessity)

19:19 One thing that crossed my mind, now that clojure has reached 1.0 is there going to be a corresponding release of clojure-contrib? i.e. one that is targetted at the clojure 1.0 release?

19:20 rhickey_: powr-toc: sounds like a good idea - one of the contribbers needs to organize that

19:21 powr-toc: is it worth raising the issue as a thread on the group?

19:21 rhickey_: powr-toc: sure

19:22 powr-toc: rhickey_: cool... I'll fire something off

19:22 chessguy: 'evening

19:22 hey rhickey_ : congrats on a great milestone today

19:22 rhickey_: chessguy: thanks

20:35 danlei: ,(doc defn)

20:35 clojurebot: "([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata"

20:35 danlei: hm

20:36 why does (defn #^{:foo 'foo} foo []) add the metadata, but (defn foo #^{:foo 'foo} []) not? if i read the docstring correctly, the second one should be right, shouldn't it?

20:37 s/doc-string/parameter list/

21:02 Chouser: danlei: leave off the #^ in the second form

21:02 provide a plain literal map instead

21:03 danlei: Chouser: aah, thank you!

21:42 durka42: congrats on the 1.0

22:36 eee: i wonder if anyone has a pointer or two for an approach/design for a little program that does the 15-puzzle

22:37 the puzzle with 16 squares, one is empty and the numbers need to get in order

22:38 basically, I don't really have a feel for when it is ok to use def

22:38 gnuvince_: eee: throw it against the wall :) I hate those puzzles. They're sometimes featured as a mini-game in video games and I need to spend like 2 hours solving it

22:39 eee: ahhhh

22:39 well I know how to solve it quickly

22:39 and want to show how using clojure

22:39 but I know what you mean

22:39 I was thinking there'd be an outer function

22:40 that takes an input state, some scrambled version

22:40 a goal state

22:40 the ordered version

22:40 and a way to transition

22:41 the space would move at most in 4 directions

22:41 and a way to score the move

22:41 the score is the number of out of place pieces

22:42 i guess that helped right there L)

22:42 just saying it out loud

22:45 chessguy: is typing considered "out loud"? :)

22:46 eee: i was too lazy to put the quotes

22:46 chessguy: hehe

22:46 so, what, you're gonna do an AB search on the tree formed by considering all possible sequences of moves?

22:47 s/tree/graph/ sorry

22:47 eee: a* search to demonstrate usefulness of my heap

22:47 chessguy: err, and you definitely don't want AB anyway...

22:47 eee: mope

22:47 only one player

22:47 nope, that is

22:47 chessguy: i think i should stop typing and start sleeping :)

22:48 eee: another question, is anyone for hire to do clojure talks?

22:48 chessguy: g'night

22:48 eee: gnight

22:53 clojure 'let' is sequential let, right? like let*?

22:53 danlei`: yes

22:53 eee: thanks

22:57 do all the bindings work that way?

22:57 like loop []

23:00 danlei`: eee: as far as i know, yes

23:00 eee: "all" was too strong

23:00 thanks

23:18 benatkin: Is there a more succinct way to write (map #(or % %2) [9 2 nil 4] [3 4 2 5])? Something like (function-name [9 2 nil 4] [3 4 2 5]) -> [9 2 2 5]), where function-name is the name of a function in the standard clojure api?

23:20 Chouser: a shame 'or' is always a macro

23:20 benatkin: that was going to be my other question...if there was some way to get or to pretend to be a function

23:21 durka42: that's strange...

23:21 ,(apply #'or [1 2 3])

23:21 clojurebot: (clojure.core/let [or__3311__auto__ 1] (clojure.core/if or__3311__auto__ or__3311__auto__ (clojure.core/or 2 3)))

23:21 Chouser: I can't think of anything more succinct than what you've got.

23:21 durka42: what's strange about that?

23:22 durka42: oh, i see, that is literally pretending to be a function, and apply didn't know it was supposed to be a macro

23:22 Chouser: exactly

23:22 benatkin: just think, if we'd raised this issue a couple of days ago, Clojure 1.0 would have been delayed :D

23:22 Chouser: nah, it's been raised plenty of times, in one form or another

23:24 ,(map #(some identity %&) [1 2 nil 4] [5 6 7 8])

23:24 clojurebot: (1 2 7 4)

23:25 Chouser: ,(for [[a b] (map list [1 2 nil 4] [5 6 7 8])] (or a b))

23:25 clojurebot: (1 2 7 4)

23:25 * benatkin wonders what clojurebot does when you try to print a cycle

23:26 durka42: he times out

23:26 dnolen: Chouser: wow, always something new to learn, what is %&?

23:26 benatkin: durka42: of course! that's sweet.

23:26 durka42: dnolen: like & in the normal parameter list

23:26 Chouser: dnolen: all the rest of the args to #() in a seq.

23:26 benatkin: threading rules!

23:27 dnolen: ahh gotcha, cool!

23:28 benatkin: does identity need to be in there?

23:28 ,(map #(some %&) [1 2 nil 4] [5 6 7 8])

23:28 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$some

23:28 benatkin: ah...apparently

23:33 ,(ffirst [[:ffffound!]])

23:33 clojurebot: :ffffound!

Logging service provided by n01se.net