#clojure log - Apr 26 2010

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

0:32 remleduff: If I've got m {a 1, b 2, c 3}, is there a better way to do: (map (juxt key (comp inc val)) m) to get {a 2, b 3, c 4} ?

0:33 hiredman: ,(fmap inc '{a 1, b 2, c 3})

0:33 clojurebot: {a 2, b 3, c 4}

0:33 hiredman: ,`fmap

0:33 clojurebot: clojure.contrib.generic.functor/fmap

0:34 cp2: woah

0:34 thats funky

0:34 remleduff: Ah, thank you. Still learning core, hadn't got to contrib ;)

0:36 leifw: is there a clojure priority queue implementation?

0:36 I found one on google code but it looks unmaintained and probably unfinished

0:37 I could use a java class but it would be nice if there were an idiomatic one, and doubly nice if it were all functionalified to be side-effect-free and persistent and such

0:39 cp2: leifw: http://github.com/hiredman/clojurebot/blob/master/src/hiredman/pqueue.clj

0:40 although hiredman is here, so i would listen to him :D

0:41 leifw: neato, thanks

0:46 defn: id like to take serialize a ref to a file, and then be able to read it back in as a ref later -- should i just (with-out-writer file (pr-str @my-ref))?

0:46 how does it get read back in?

1:07 Licenser_: you around?

1:08 Licenser_: why wrap dorun in a (fn [] (dorun (map blah (blah blah))))

1:20 AntonyBlakey: Anyone seen this: "Wrong number of args passed to: core$-cache-protocol-fn" with 1.2.-master-SNAPSHOT?

2:43 yairiny: ,`fmap

2:43 clojurebot: clojure.contrib.generic.functor/fmap

2:46 * yairiny hi, fairly new to clojure, trying to wrap my head around lazy sequences, I have a function defined as: (defn get-primes-helper [xs]

2:46 * yairiny (lazy-seq (cons (first xs)

2:46 * yairiny (if (not (empty? (rest xs)))

2:46 * yairiny (get-primes-helper (remove-mults xs (first xs)))

2:46 * yairiny '()))))

2:47 yairiny: and when I call it with (range 2 100000) it stack overflows

2:47 remove-mults is non-recursive and I can't see why there should be too deep a call stack...

3:29 LauJensen: Morning all

3:31 patrkris: godmorgen lau

3:38 bendlas: hi folks

4:06 Raynes: mmarczyk: Heh. I answer a question correctly, and you come in 30 minutes later and answer it 10 times better. Want to trade brains, sir? :p

4:14 cYmen: how do I append to a list?

4:15 mikem: ,(concat '(1 2 3) '(4))

4:15 clojurebot: (1 2 3 4)

4:16 cYmen: mikem: thanks!

4:16 mikem: ,((fn [l x] (concat l (list x))) '(1 2 3) 4)

4:16 clojurebot: (1 2 3 4)

4:26 Chousuke: Note that such concats shouldn't be a frequent operation. performance degrades pretty quickly due to laziness.

5:05 stilkov: Hi there; how can a program find out the version of Clojure it runs under?

5:10 patrkris: stilkov: look at the *clojure-version* variable

5:10 stilkov: http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/*clojure-version*

5:10 stilkov: patrkris: thanks, exactly what I was looking for

5:27 If you were to pick your favorite 5 Clojure blogs, what would they be? Here's my initial attempt: http://www.bestinclass.dk/index.php/blog/ http://technomancy.us/ http://stuartsierra.com/ http://blog.fogus.me/ http://kotka.de/blog/

5:27 sexpbot: "Blog | BEST IN CLASS"

5:42 LauJensen: Wow thanks :)

6:42 vu3rdd: slightly OT. Can someone recommend a good book on SQL or in general designing proper tables etc?

6:44 cemerick: vu3rdd: "The Art of SQL" is a good read if you already know the basics, etc.

6:45 vu3rdd: cemerick: Thanks. I have never used databases but have done a bit of playing around with mysql on my machine. But that is all. Have not done any real stuff. I will take a look at "The art of SQL".

6:47 cemerick: vu3rdd: in that case, that recommendation probably won't work out for you :-)

6:47 vu3rdd: cemerick: Oh.. ok

6:48 cemerick: I don't know what the good beginner RDBMS books are these days.

6:48 Never did, really.

6:48 vu3rdd: What I am looking for mainly the considerations to be given while designing tables and their relations.

6:50 zmila: one may always start from corresponding wikipedia article, and then follow links

6:58 AWizzArd: Btw, how deeply developed is an implementation of Clojure in JavaScript?

7:11 zmila: if i'm not mistaken - last commit to ClojureScript is Jan 2009?

7:17 bendlas: am i right, that ring sessions stay in memory indefinitely, if you don't delete them manually?

7:21 cemerick: zmila: yeah, it hasn't been worked on in some time. That'll likely change as more and more clojure is written in clojure.

7:22 bendlas: If I'm not mistaken, ring just uses the servlet container's session store. Jetty's default is in-memory, with a variety of configuration parameters.

7:35 bendlas: cemerick: not exactly, it stores the sessions in an (atom {})

7:35 and i can't find the place where a timeout would delete the session

7:40 licoresse: anyone using la clojure (idea) with 1.2?

7:45 cemerick: bendlas: hrm, yes, you're right (it's a ref in compojure 0.3.2). Now I remember why I stuck to using the servlet sessions.

8:05 _exterm: Is the ASM library included in clojure just a repackaged org.objectweb.asm or are there significant changes? I'd like to let the clojure compiler generate other things than JVM Bytecode, therefore messing with clojure ASM.

8:05 -changes +differences

8:06 rhickey: _exterm: clojure's ASM is just a re-packaging, no changes

8:07 jwr7: How can I override a dependency in leiningen (project.clj) with my own fork pushed to Clojars?

8:09 _exterm: rhickey: thanks!

8:10 rhickey: which version of asm is it?

8:10 rhickey: _exterm: old, 2.something

8:11 _exterm: ok, that should help - thanks!

8:14 vu3rdd: rhickey: Debian made some changes (some < 5 lines) so that it uses the asm3 on the classpath. I see that your todo list has such a goal. Do you want such a patch before 1.2?

8:15 rhickey: vu3rdd: dunno, it's under consideration

8:15 vu3rdd: ok

8:45 rhickey: are we ready for #^ becoming ^ ? (#^ will remain around for compatibility)

8:49 AWizzArd: yes

8:49 But how long will #^ survive?

8:51 rhickey: AWizzArd: 42 days

8:51 LauJensen: perfect

8:51 * mikem is ready for #^ becoming ^ :D

8:57 chouser: rhickey: I assumed you'd want a release with #^ deprecated.

8:57 rhickey: chouser: at some point, no rush on that I think

8:57 i.e. you could go out with ^ working and #^ not yet deprecated

8:58 AWizzArd: rhickey: can you make ^ so that it can optionally support many type hints? ^{:jvm BigInteger, :clr SuperInt, :common-lisp bigint}

8:58 With editors that hide/unhide type hints, or only display those for the current plattform, this would look nice in the editor.

8:58 chouser: oh, sorry, I'm confused. Let me try again: I assumed you'd want a release with ^ deprecated.

8:58 rhickey: AWizzArd: ^ just attaches metadata, it doesn't determine its use

8:59 ^rest

8:59 ,^rest

8:59 clojurebot: nil

8:59 rhickey: aargh

8:59 AWizzArd: ,*clojure-version*

8:59 clojurebot: {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "master"}

8:59 rhickey: WARNING: reader macro ^ is deprecated; use meta instead

9:00 chouser: oh, was that in 1.1? perfect.

9:00 rhickey: ah, not deprecated in 1.1, fooey

9:00 chouser: clojurebot is pre-1.1

9:01 Ok, looks like 1.1 way early May 2009. ^ was deprecated early Dec 2009

9:02 -way +was

9:02 but as for me, I'm ready.

9:02 rhickey: http://www.assembla.com/spaces/clojure/tickets/215-deprecate-%5E-reader-macro

9:02 sexpbot: "#215 - Deprecate ^ reader macro (Fixed) | Clojure | Assembla"

9:02 chouser: ~chouser

9:02 clojurebot: Who??

9:02 chouser: ~chouser

9:02 clojurebot: Who??

9:02 chouser: bah, nm.

9:03 rhickey: is it deprecated in 1.1 or not?

9:04 * rhickey only runs experimental new versions of clojure

9:04 chouser: the dates I listed above are from the git log. I'd trust that over manual flags in Assembla, so I think was not deprecated in 1.1.

9:04 I should keep 1.1 built somewhere... :-/

9:04 rhickey: 1.1 was not May

9:05 chouser: oh

9:05 rhickey: http://github.com/richhickey/clojure/blob/1.1.x/changes.txt

9:05 chouser: oh, great!

9:05 rhickey: so, already deprecated, good to go

9:05 rhudson: It's deprecated in 1.1

9:06 chouser: oh, 1.0.0 was may

9:06 I was misunderstanding the commit messages.

9:06 rhickey: but get rid of for one release, then redefine?

9:06 LauJensen: Yea, just confirmed that its deprecated in the 1.1 download from clojure.org (featured)

9:07 rhickey: otherwise we go directly from one (deprecated) semantic to a different one

9:07 chouser: with releases at this pace, I think deprecated in a single release is fine.

9:08 It seems sane to recommend people upgrading from 1.0 try 1.1 along the way instead of jumping directly to 1.2.

9:08 rhickey: is anyone using 1.0?

9:09 LauJensen: rhickey: sure there are some legacy solutions here and there

9:09 fogus: rhickey: Thanks for the annotation support. This may help clear the final hurdle for using Clojure in my team's mainline source!

9:09 rhickey: fogus: great! I'll try to get parameter annotations in today

9:10 fogus: rhickey: Great. I'll hold off on my pitch slides then. :-)

9:10 rhickey: anyone want to work up a patch to use them in gen-class as well?

9:11 chouser: Programming Clojure still points to http://github.com/stuarthalloway/programming-clojure which still refers to SVN revision numbers for Clojure and contrib.

9:11 I don't know if that means there may be learners still using 1.0?

9:12 rhickey: could be

9:13 chouser: anyway, it seems unlikely there's much maintained code still expecting 1.0

9:15 rhickey: removing it for one release prior to repurposing seems most prudent, but...

9:17 zmila: Clojure course on RubyLearning is procrastinated to 30th, is it?

9:18 chouser: I think most uses of ^ as meta will still be reported: java.lang.IllegalArgumentException: Metadata must be Symbol,Keyword,String or Map

9:19 rhickey: chouser: I don't know about that (let [x ^y z 42] ...) will yield error completely unrelated to metadata

9:19 chouser: many will, anyway, though others will be reported as reader errors -- unexpected ) etc.

9:20 hm.

9:20 Chousuke: maybe have a "lint" mode that simply reports any ^ use?

9:21 so that it can be checked if it's up-to-date or not

9:27 defn: still pretty shaky but a bit of a redesign to walton: http://getclojure.org:8080/examples/concat

9:27 sexpbot: "concat"

9:27 rhickey: what does it take to get clojure-mode to highlight ^ as it currently does #^ ?

9:27 defn: enjoy

9:29 AWizzArd: rhickey: there are just three occurrences of #^ in clojure-mode, in regexps. I guess only those need to be edited. So, like 30 seconds.

9:33 rhickey: where does elpa put things?

9:34 manniche: on clean setup, elpa uses .emacs.d/elpa

9:34 please insert 'a' in it's proper place in the above

9:34 rhickey: manniche: thanks

9:34 manniche: np

9:35 defn: rhickey: technomancy is a good guy to talk to about elpa-related stuff, fwiw.

9:37 rhickey: AWizzArd: so what are the three new regex strings that support both #^ and ^ ?

9:38 AWizzArd: http://github.com/technomancy/clojure-mode/blob/master/clojure-mode.el#L297

9:38 and Lines 438 and 486

9:38 though some escaping might be required in the regexps

9:40 sattvik: rhickey: I'll add annotations to gen-class, if you like.

9:41 rhickey: sattvik: great! please assign the issue to yourself: http://www.assembla.com/spaces/clojure/tickets/318-add-annotation-support-to-gen-class

9:41 sexpbot: "#318 - add annotation support to gen-class (New) | Clojure | Assembla"

9:44 sattvik: rhickey: No problem. I will look into it later today and submit a patch soon.

9:48 a_strange_guy: hi there

9:49 how do i call an IFn that is a static field?

9:49 chouser: hehe

9:51 a_strange_guy: ,(clojure.lang.PersistentList/creator 1 2 3 4)

9:51 clojurebot: java.lang.IllegalArgumentException: No matching method: creator

9:51 chouser: ,((clojure.lang.PersistentList/creator) 1 2 3 4)

9:51 clojurebot: (1 2 3 4)

9:52 a_strange_guy: that was just a bad example xD

9:53 chouser: I'm not disagreeing that it was a bad example. But my point is that putting parens around a static field name still just returns the value, which if it is an IFn can then be called.

9:53 ,(clojure.lang.PersistentList/creator)

9:53 clojurebot: #< clojure.lang.PersistentList$1@74bcd3>

9:53 a_strange_guy: ok

9:54 learned something new ^^

9:54 seems undocumented

9:55 chouser: ,((. clojure.lang.PersistentList creator) 1 2 3 4)

9:55 clojurebot: (1 2 3 4)

9:55 chouser: that one's documented. :-/

9:56 a_strange_guy: ah, and (Class/fld) -> (. Class fld)

9:58 i was kindof confused because Class/fld also gets turned into a field access

9:58 except if it is at the beginning of a form

10:00 chouser: a_strange_guy: yes, that's why I laughed when you first posted your question. The thought of an IFn in a static field had never occured to me.

10:01 It's almost a pun

10:01 a_strange_guy: yeah it came to my mind because the new deftypes have no constructor fns

10:02 rhickey: a_strange_guy: they have ctors though

10:02 chouser: they don't have static fields either, do they?

10:03 a_strange_guy: that aren't function though

10:04 AWizzArd: rhickey: btw, do we go with (Foo. ..) for now, without (Foo/create ..) and (create-Foo ...) ?

10:04 rhickey: AWizzArd: I found those lines, looking for *new* regexes to use

10:05 a_strange_guy: if we had static fields, then we could put a creator fn in there

10:05 rhickey: a_strange_guy: or just write a function

10:06 a_strange_guy: that is what i do for now

10:06 i wrote a macro that does a defrecord and creates a create-Type fn

10:07 but it seems kinda messy

10:08 lessthantristan: I have compiled a class with gen-class with a static method, when i call (package.name.ClassName/staticMethod input) it works fine, but if i (import ...) (ClassName/staticMethod input) it throws me an unsupported operation exception. any ideas?

10:12 AWizzArd: rhickey: you need to edit these three lines. Replace the hash with two backslashes. Line 486 for example will after that operation look like this: ("\\^\\sw+" 0 font-lock-type-face)

10:12 a_strange_guy: lessthantristan: is there any reason using the static method instead of the defn that is in your namespace anyway?

10:14 like (-staticMethod input) ?

10:14 AWizzArd: rhickey: or you can put between the # and the ^ in #^ just a questionmark, so that these three will look like: #?^

10:14 In that case it will highlight #^String but also ^FileInputStream

10:14 lessthantristan: hmmm. maybe not. let me think about that

10:22 naeu: can anyone explain why (seq? '#(%)) ;=> true

10:23 AWizzArd: ,'#(%)

10:23 clojurebot: (fn* [p1__11767] (p1__11767))

10:23 naeu: what does fn* mean?

10:23 chouser: doesn't matter in this case.

10:23 a_strange_guy: it's 'fn without destructuring

10:23 chouser: what matters is that #() expands at read-time to (...)

10:24 ' quotes that so that the (...) list is passed to 'seq?'

10:24 lessthantristan: a_strange_guy: i think i'll go with that, it'll probably work out better now i think about it.

10:24 chouser: lists are seqs, so 'seq?' returns true.

10:24 AWizzArd: '#(%) ==> list with three elements

10:24 naeu: ah ok

10:24 I'm still trying to get my head around the different behaviours of -> and ->>

10:24 I understand them in an algebraic sense

10:25 but I'm now trying to get a practical working understanding of their usecases

10:25 AWizzArd: ,(seq? (eval '#(%))) ; this is:

10:25 clojurebot: DENIED

10:25 AWizzArd: okay, false would be the result

10:25 clojurebot: (enable 'eval) ;-)

10:25 clojurebot: Huh?

10:25 AWizzArd: rhickey: did that work out for you? Can you now see ^YourTypeHint colored?

10:26 a_strange_guy: ,(->> (range 10) (map #(* % %)) (reduce +))

10:26 clojurebot: 285

10:26 naeu: (-> [1 2 3] #(* 2 %) #(+ 5 %)) vs (-> >[1 2 3] #(* 2 %) (+ 5 %))

10:26 a_strange_guy: dont use -> and ->> with function literals

10:26 naeu: oops: (-> [1 2 3] #(* 2 %) #(+ 5 %)) vs (->> [1 2 3] #(* 2 %) #(+ 5 %))

10:26 a_strange_guy: why?

10:27 chouser: it's almost certainly not what you mean

10:27 naeu: the ->> works as I expected

10:27 a_strange_guy: because ->> and -> transform source code

10:27 chouser: ,(-> 1 (* 2) (- 5))

10:27 clojurebot: -3

10:27 naeu: each el in the list is doubled then incd by 5

10:27 chouser: ,(->> 1 (* 2) (- 5))

10:27 clojurebot: 3

10:28 AWizzArd: chouser: do you know why we want to replace #^ with just ^?

10:28 chouser: ,(macroexpand-1 '(->> [1 2 3] #(* 2 %)))

10:28 clojurebot: (fn* [p1__11785] (* 2 p1__11785) [1 2 3])

10:28 chouser: AWizzArd: ^ is less ugly

10:28 a_strange_guy: (macroexpand '(-> [1 2 3] #(seq %)))

10:28 AWizzArd: k

10:28 a_strange_guy: , (macroexpand '(-> [1 2 3] #(seq %)))

10:29 clojurebot: (fn* [1 2 3] [p1__11789] (seq p1__11789))

10:29 naeu: I thought one of the main uses of ->> was to transform source code to a more readable form in certain cases

10:29 a_strange_guy: yeah but thos macros ignore the semantics of special forms like fn an dlet

10:30 defn: naeu: http://getclojure.org:8080/examples/->> and http://getclojure.org:8080/examples/->

10:30 sexpbot: "->>"

10:30 a_strange_guy: ,(macroexpand '(->> [1 2 3] #(* 2 %) #(+ 5 %)))

10:30 naeu: a_strange_guy: so are there any guidlines of when to use them?

10:30 clojurebot: (fn* [p1__11794] (+ 5 p1__11794) (clojure.core/->> [1 2 3] (fn* [p1__11793] (* 2 p1__11793))))

10:30 defn: it is loading up right now so you might need to reload a few times but you can see some ideas of use

10:30 naeu: or is it just a tacit notion of good and bad for a give usecase

10:31 chouser: naeu: -> and ->> are simple macros, not high-order functions. This just rearrange the code a bit.

10:31 -This +They

10:31 the only reason not to use #() in them is that it probably isn't what you mean.

10:31 defn: question: is it obvious on the above links that you should click the example to expand it and show its result?

10:31 a_strange_guy: http://vimeo.com/8474188

10:31 AWizzArd: naeu: this is the idea behind macros. Allow the dev to write down the code in a way that is easier to read (and write) for humans. Not only true for ->>

10:31 sexpbot: "Episode 5 - Expression Threading on Vimeo"

10:32 stuartsierra: Good morning.

10:32 I did this over the weekend: http://github.com/stuartsierra/need

10:33 defn: stuartsierra: cool

10:33 chouser: stuartsierra: I like it.

10:34 stuartsierra: thanks

10:34 a_strange_guy: awesome

10:34 chouser: stuartsierra: which way does :rename go?

10:34 stuartsierra: chouser: Same as refer; {original-name new-name}

10:39 naeu: out of interest, does the implementation of the ->> macro even need this clause: (with-meta `(~(first form) ~@(next form) ~x) (meta form))

10:40 seems like the seq? test is superfluous

10:40 and the 2-arity version could just be: ([x form] (list form x))

10:45 chouser: naeu: that would transform (->> 5 (+ 2)) into ((+ 2) 5), wouldn't it?

10:47 naeu: I'm just assuming that `(~(first form) ~@(next form)) is equivalent to (form)

10:47 perhaps I'm wrong...

10:47 chouser: oh, perhaps it could be `(~@form ~x)

10:48 though the metadata-copying is important too

10:51 a_strange_guy: stuartsierra: does (need [java.util.concurrent as juc]) work too?

10:52 stuartsierra: no

10:52 a_strange_guy: my bad

10:52 stuartsierra: It doesn't do Java class imports; I explain why in the readme

10:52 a_strange_guy: didn't read that you didn't support imports

10:53 stuartsierra: I thought about it, but it's impossible to do :as, :all, or :exclude with Java packages.

10:53 naeu: chouser: so what's the difference between `(~@form ~x) and (list form x)

10:53 from within a macro context?

10:54 chouser: ,(list '(1 2) 3)

10:54 clojurebot: ((1 2) 3)

10:54 chouser: ,`(~@'(1 2) 3)

10:54 clojurebot: (1 2 3)

10:56 naeu: ah, ok

10:57 a_strange_guy: stuartsierra: shouldn't it be (defmacro need [& args] `(apply need* ~args)) instead of an apply at macroexpansion time?

10:58 stuartsierra: nope

10:58 That would evaluate the arguments.

10:58 chouser: the purpose of the 'seq?' test is to allow non-list parts.

10:58 ,(5 inc inc inc)

10:58 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

10:59 chouser: ,(-> 5 inc inc inc)

10:59 clojurebot: 8

11:00 a_strange_guy: but (if *var* (need [this ...]) (need [that ...])) will load both this and that

11:00 stuartsierra: that's true

11:00 It should probably be `(apply need* ~(map quote args))

11:01 Chousuke: hmmh

11:01 cemerick: stuartsierra: nice spike. Eliminating prefix lists gets a big +1 from me.

11:01 Chousuke: that won't work either, quote is not a function

11:01 stuartsierra: right, got to do (map (fn [x] (list 'quote x)) args)

11:02 Chousuke: and then you could just splice in the args anyway and remove apply

11:02 a_strange_guy: `(need* ~@(map (partial list 'quote) args))

11:02 rhickey: AWizzArd: #?^ doesn't work. I would like to highlight both #^ and ^

11:02 stuartsierra: although `(apply need* '~args)) might work too

11:03 and that's a lot simpler

11:03 yeah, that works

11:04 a_strange_guy: as long as there are no side-effects at compiletime everything is fine

11:05 stuartsierra: fixed and pushed

11:05 Thanks, strange guy.

11:06 a_strange_guy: this needs to go to c.c.ns-utils at least

11:07 AWizzArd: rhickey: are you using a fresh checkout? i.e. http://github.com/technomancy/clojure-mode/blob/master/clojure-mode.el

11:07 rhickey: I just replaced my old clojure-mode.el with this new one, replace the three #^ with #?^ and can now see #^String and ^FileInputStream highlighted.

11:08 rhickey: AWizzArd: no, does it matter?

11:08 stuartsierra: a_strange_guy: I'm reluctant to add any more confusion to use/require/refer

11:09 AWizzArd: rhickey: depends on the version you use, but in principle it should work with older versions too, which use the same regexps. You need to restart emacs, so that the new clojure-mode.el is used. The highlightning happens in source files, not in the repl.

11:11 * chouser thinks dosync should support not only ensure but also unsure, perhaps for quantum reasoning.

11:11 a_strange_guy: it seems to unify require/use/refer well enough to replace those in the future

11:12 stuartsierra: a_strange_guy: but it won't be supported in 'ns'

11:12 not yet anyway

11:14 rhickey: AWizzArd: ok works now, I had a clojure-mode.elc in there

11:14 AWizzArd: thanks!

11:17 AWizzArd: great

11:34 stuartsierra: Anyone else think Clojure mode should always indent 2 spaces, regardless of the first item in the list?

11:34 lpetit: yes

11:35 rhickey: #^ -> ^ swap done in core

11:35 much cleaner looking

11:36 let's get those editor/IDE patches in place

11:37 stuartsierra: didn't know this was a 1.2 feature

11:37 rhickey: it is now

11:37 Chousuke: heh

11:37 cemerick: zing :-)

11:37 stuartsierra: does #^ still work?

11:37 rhickey: yes

11:37 stuartsierra: ook

11:37 ok

11:39 rhickey: doing it now is better for the books

11:39 IMO

11:39 stuartsierra: ah

11:39 cemerick: Is there another that is impending?

11:39 stuartsierra: So you're saying I have to edit that chapter now? :)

11:39 rhickey: stuartsierra: yes please

11:40 cemerick: are you waiting for something?

11:40 djpowell: btw I thought that deftype was intended to be a bit host-neutral? Does adding annotations there conflict with that?

11:41 cemerick: not at all -- I've just seen books (plural) a couple of times, and I'm not aware of another besides JoC that is close to publication.

11:41 stuartsierra: "Practical Clojure" is in final edits

11:41 cemerick: ah

11:41 That totally flew under my radar.

11:42 stuartsierra: tell me about it

11:42 rhickey: djpowell: annotations are an interop feature, yes, but there will be no semantics for them other than interop, i.e. I'm not making them a Clojure feature

11:42 stuartsierra: it's so far under the radar, even I don't know when it's getting published

11:42 cemerick: "if something happens, and isn't tweeted about it, does it make a noise?"

11:42 rhickey: heh

11:44 djpowell: annotations present on platforms that don't have annotations do nothing

11:44 just like some hints will do nothing on JavaScript

11:44 djpowell: ah ok

11:45 chouser: stuartsierra: ah, congrats -- I didn't know it was that close to done.

11:45 djpowell: are .net annotation sufficiently similar to java ones that they will be implementable do you know? I don't know much about them

11:45 stuartsierra: chouser: thanks

11:51 djpowell: cemerick: re the contrib.io stuff, it would probably be cool if the URL->Reader stuff used the content-type header where possible to get the charset - I might have a go at that later

11:52 stuartsierra: djpowell: http.agent does that I think, if you want an example

11:54 djpowell: stuartsierra: is that a contrib lib?

11:55 stuartsierra: yes

11:56 cemerick: djpowell: Yes, that would be a better default for the URL/reader impl. Should be straightforward, I'd think.

11:57 djpowell: cool. i'll check that it complies to my obsessive conformance to mime/http/xml rfcs

11:57 cemerick: Or, wait, except for HTTP URLs, in which case you'll go mad for the next four days. :-P

12:00 djpowell: stuartsierra: hmm I don't think it does. getContentEncoding, doesn't get the charset - it gets the http content-encoding header, which is blank, or something like 'gzip' or 'deflate'

12:00 i'll take a look later...

12:02 stuartsierra: djpowell: oh, maybe I punted on that; I forget

12:06 * technomancy will update clojure-mode's ^ highlighting

12:07 technomancy: hopefully in a couple weeks there will be a combined swank/clo-mo release

12:07 stuartsierra: yay!

12:07 technomancy: the debug-repl stuff is to good to leave to snapshots

12:08 rhickey: technomancy: TIA for ^

12:11 technomancy: sure, gotta keep up with the frentic pace of clojure =)

12:11 actually I'm surprised how *little* stuff in my code I haven't touched in a year is still working fine in 1.2-snapshot

12:11 I mean how little brok

12:11 ee

12:12 it's practically all been contrib changes

12:12 rhickey: technomancy: yeah, sometimes I hate to see people categorize it as 'Clojure is changing all the time' since change == newness, not breakage

12:13 hopefully we'll be fixing the 1.2 contrib breakage

12:13 stuartsierra: ~def flatten

12:13 clojurebot: I don't understand.

12:13 djpowell: there have been very few breaking changes in clojure. only ones I can think of other than this are the vectors around bindings normalisation for doseq and friends, and lazy-cons - and both of those were prior to 1.0

12:13 technomancy: my stuff breaking in light of the contrib changes is 100% justified IMO

12:14 djpowell: other than clojure.core name clashes with user var names

12:14 technomancy: higher rate-of-churn is what contrib is for

12:14 cemerick: +1 technomancy

12:15 I really don't like the idea of carting around fundamentally dead code (for how long) to support folks that use contrib as a supported stdlib. *shrug*

12:15 stuartsierra: But they're going to complain when 1.2 breaks everything.

12:16 rhickey: cemerick: one release as deprecated seems fair

12:17 stuartsierra: yes

12:17 cemerick: rhickey: I really don't think that's going to satisfy anyone, but we'll see.

12:17 AWizzArd: technomancy: please look into your priv

12:17 technomancy: right, leaving the old namespaces in place with deprecation warnings is definitely worth doing for a season just because it's not much work

12:17 rhickey: cemerick: there are certainly things between change now and change never

12:19 cemerick: rhickey: Sure, I know, but I've never heard someone come in and say "could you hold off on eliminating X, Y, or Z from contrib for a year? That'd help me out a bunch." I've only heard "This is the standard library, it must not break compatibility forever."

12:19 again, *shrug*

12:19 rhickey: cemerick: yeah, forever isn't very useful either

12:20 cemerick: I've never really seen a community that's handled deprecations gracefully.

12:20 rhickey: consideration != permanent accommodation

12:21 cemerick: Python is often cited, but the population holding onto 2.x would seem to suggest otherwise.

12:21 jweiss: you'd think clojure with its homoiconicity would make it easy to automatically upgrade existing code

12:21 or at least i'd think that :)

12:21 technomancy: time to implement M-x precate (opposite of deprecate)

12:23 stuartsierra: jweiss: It's not just names that have changed; it's behavior too.

12:23 jweiss: ah, that's a bit more complex then :)

12:23 cemerick: There's also almost always more code to fix in libraries you depend upon than in your own codebase.

12:25 replaca: cemerick: as things mature, there's no reason not to let folks "stay behind" on old releases if they meet their needs

12:25 dnolen: cemerick: tho that's a different problem. for end users Python 3k is not *that* much better. compare to Clojure 1.1 to 1.2, too much good stuff to not move. you know things are slowing down for a language when most people and libraries aren't excited about following.

12:34 djpowell: somewhere in the world the elimination of #^ line noise will make someone not give up on trying clojure

12:34 slyphon: heh

12:34 it that dissuades you, you need to grow a pain

12:34 pair*

12:35 somnium: grow a perl?

12:35 djpowell: ha - I showed someone a defrecord one-liner today, and I had to put type hints in for parity, and that #^ grated with me even

12:35 technomancy: "They see me coding, they hating. They're just upset cause I'm deprecating." -- http://twitter.com/tenderlove/status/11069179490

12:35 sattvik: rhickey: There is no way to create a no-arg constructor with deftype, correct?

12:36 rhickey: Assuming there are fields for the type, of cours.e

12:39 chouser: sattvik: but you can write your own no-arg factory fn

12:40 I think almost every defrecord and deftype will end up with a hand-written factory fn

12:41 sattvik: chouser: True, but that won't work in an inter-op scenario that expects a no-arg constructor.

12:41 chouser: truwe

12:41 also, true.

12:42 for interop you still pretty often need gen-class

12:42 cemerick: sattvik: Last I knew, factory fns were going to be the way forward.

12:44 sattvik: chouser: That's what I thought. I just wanted to be sure I had not overlooked anything.

12:45 chouser: if you have control of the spec, I'd recommend pushing users toward static factory methods rather than no-arg ctors.

12:46 I think a 'gen-static' is planned that would make such things easy to create.

12:50 lpetit: I remember an idea along the lines of allowing syntactic sugar for "#^String foo" "^String foo" : "foo^String". Still relevant ?

12:51 chouser: lpetit: rhickey has grown increasingly cold toward suffix metadata

12:51 lpetit: ok, no pb, just wanted to update my knowledge

12:51 chouser: I think ^String foo is what we get

12:56 stuartsierra: suffix metadata would be a pain to parse

12:57 rhickey: stuartsierra: yeah

12:58 mmarczyk: is the table of contents for "Practical Clojure" available anywhere?

12:58 cemerick: There was the String:foo craziness I threw out there an age ago. :-P

12:58 mmarczyk: and an excerpt from the text would be totally cool, of course

12:59 stuartsierra: mmarczyk: There are 4 chapters on apress.com, not a very good sample

12:59 no table of contents anywhere

13:00 mmarczyk: stuartsierra: do you mean in the 'alpha'?

13:00 stuartsierra: yeah

13:00 mmarczyk: oh :-(

13:00 it's $35 up front without a sample :-(

13:00 stuartsierra: I know

13:00 Wish Apress were better about that.

13:01 ordnungswidrig: Is there anything like haskell's "tying the knot" in clojure?

13:09 slyphon: so, i create a hierarchy w/ make-hierarchy, but when i pass the :hierarchy option to defmulti, it barfs with a ClassCastException

13:11 wthidden: What is the form for adding meta data to a defrecord?

13:11 chouser: slyphon: ugh. at first glance looks like a regression

13:11 slyphon: :/

13:15 fogus: stuartsierra: When do you get your name on the cover?

13:15 chouser: slyphon: well, I spoke too soon as usual.

13:15 slyphon: hah

13:16 chouser: slyphon: not a regression I think, just weakly documented.

13:16 slyphon: chouser: what's the deal?

13:16 oh?

13:16 chouser: It looks like you have to put your hierarchy in an IRef of some kind.

13:16 slyphon: ohhh

13:16 * slyphon tries that

13:16 slyphon: and hand in the reference?

13:17 weird, because derive works fine

13:17 chouser: right, defmulti expects an IRef

13:17 hiredman: seems odd that make-hierarchy doesn't just return what you need

13:17 chouser: yeah

13:17 slyphon: yeah, can i do (dosync) at the top-level?

13:17 chouser: I can't tell yet if it matters what kind of IRef

13:18 * slyphon nods

13:18 * slyphon tries with an atom

13:18 chouser: global-hierarchy is a var

13:18 slyphon: hrm

13:18 chouser: weird. 2-arg derive mutates global state. 3-arg derive is a pure function

13:18 slyphon: well i have (def *send-msg-hier* (make-hierarchy))

13:19 chouser: that makes sense

13:19 b/c it's mutating the global hierarchy

13:19 how do i hand in the var itself?

13:19 chouser: so if you want derive to change *send-msg-hier* you need to mutate it yourself. (alter-var-root #'*send-msg-hier* derive tag parent)

13:20 hiredman: there is a whole special form for getting vars

13:20 chouser: and (defmulti ... :hierarchy #'*send-msg-hier*)

13:20 slyphon: ahh

13:20 chouser: odd, it *seemed* to work without htat

13:20 for derive, but i'll try it that way

13:20 chouser: seems like a through discussion of multimethods ought to include this.

13:20 * chouser checks the TOC

13:21 chouser: slyphon: well, derive will return your new heirarchy without that, but the change wouldn't "register"

13:21 slyphon: hiredman: oh, right, i hadn't really clued in that's what that does

13:21 chouser: ah!

13:21 chouser: sneaky!

13:22 chouser: pure function

13:22 * slyphon nods

13:22 chouser: that's only the second example I've noticed of a clojure function being pure or not based on arity.

13:23 the other is re-find -- one-arg is statefule, two-args pure.

13:23 * slyphon nods

13:23 chouser: makes me nervous

13:24 slyphon: so (def derive-send-msg (partial alter-var-root #'*send-msg-hier* derive))

13:24 would work, no?

13:24 chouser: sounds about right

13:24 slyphon: yay! i grok partial!

13:24 :)

13:25 chouser: :-)

13:28 ,(-> "Unknown %s of type %s at line %s" (format "message" "Foo" 5) Exception. throw)

13:28 clojurebot: java.lang.Exception: Unknown message of type Foo at line 5

13:28 chouser: abuse of -> ?

13:31 Chousuke: chouser: :P

13:31 chouser: that's not really an answer...

13:32 cemerick: chouser: yeah, probably

13:32 though I've used -?> to optionally toss exceptions sometimes, so who am I to talk.

13:45 mmarczyk: um, sorry, I seem to be behind the curve on this: what's the authorship situation with "Practical Clojure"?

13:46 chouser: mmarczyk: I think Luke Van der Hart wrote a bunch and then stuartsierra stepped in and wrote some chapters.

13:47 But I'm not entirely sure.

13:47 technomancy: it's the dark, mysterious clojure book

13:48 stuartsierra: I wrote 6 chapters out of 14

13:48 Luke VanderHart wrote the rest

13:48 mmarczyk: oh, that's good to know

13:48 rsynnott: There's a SECOND clojure book? :)

13:48 * rsynnott missed that

13:49 chouser: rsynnott: I know of 4

13:49 stuartsierra: same here

13:49 mmarczyk: that definitely makes me want to read it :-)

13:49 stuartsierra: mmarczyk: thanks

13:49 rsynnott: Ah, I've only seen the PragProg one

13:50 slyphon: does the author of "Programming Clojure" hang out in here?

13:50 mmarczyk: I don't suppose any of your chapters would be in the alpha at this point?

13:50 slyphon: stuart halloway

13:50 stuartsierra: mmarczyk: no, to my chagrin

13:50 slyphon: occasionally, but not often

13:50 * slyphon nods

13:50 chouser: rsynnott: Halloways on v1.0 (published), Sierra's on v1.2 (complete but not printed?), Rathore's (incomplete, some chapters available) and Fogus's (incomplete, some chapters available)

13:50 slyphon: that's the one i've been using most

13:50 rsynnott: ah

13:50 stuartsierra: chouser: correct as far as I know

13:51 mmarczyk: oh bother, must Apress have such disheartening policies :-(

13:52 chouser: I don't know what Rathore is targetting. Fogus's will have 1.2 content with perhaps some notes about earlier versions, depending on release timing.

13:52 mmarczyk: chouser: I like the way you say "Fogus's" :-)

13:53 chouser: mmarczyk: credit and blame. :-)

13:53 rfg: My train has broken down.

13:53 mmarczyk: :-)

13:54 rhickey: parameter annotation support is up, definterface annotaiton now up to snuff with deftype/record

13:54 stuartsierra: cool

13:54 maybe I can integrate with JUnit now

13:56 cemerick: ouch, any ideas about this: java.lang.NoSuchFieldError: lastClass

13:56 ordnungswidrig: stuartsierra: you're really obsessed by unit test, right? :-)

13:56 cemerick: I suspect a lib that is AOT-compiled with an older snapshot of 1.2...

13:56 chouser: even if you don't buy the book, I think Fogus's first chapter (free) is likely quite useful.

13:56 rhickey: cemerick: sounds right

13:56 stuartsierra: ordnungswidrig: just a little :)

13:57 ordnungswidrig: stuartsierra: what about quickcheck like stuff? I know there are at least two halfly done libs in clojure.

13:57 * cemerick considers using ns metadata to control AOT compilation

13:57 stuartsierra: ordnungswidrig: it's on my agenda, but farther down the list

13:58 I've never used a quickcheck-like library, so I have to learn more about it.

13:58 ordnungswidrig: stuartsierra: classification tree method?

13:58 i'd love support for that.

13:59 I'm just asking before doing it myself :)

14:00 stuartsierra: I don't know what that is.

14:04 ordnungswidrig: stuartsierra: a method for systematic testing. you decompose the input parameters of the subject under test into a tree of independent parameters (e.g. color of the object vs. shape vs. material). The tools then help generating small test sets that cover e.g. each pairwise combination of two parameters.

14:05 stuartsierra: ah

14:05 yeah that would be useful

14:06 ordnungswidrig: stuartsierra: it's a bit like quickcheck but when the execution of a single test takes long or has to carried out manually. For some problems you just don't want test all combinations of parameters :)

14:06 sut

14:07 stuartsierra: if you like the topic you can try CTE, a free java application http://www.systematic-testing.com/functional_testing/cte.php

14:07 sexpbot: "Systematic Testing"

14:08 stuartsierra: I'll check it out

14:09 Right now I'm still focused on getting the syntax right for specs/assertions/contexts

14:09 Then I'll finish the work on continuous testing.

14:26 ordnungswidrig: stuartsierra: ist lazytest master usable?

14:26 stuartsierra: or loose ground?

14:26 stuartsierra: usable, but not stable

14:26 syntax may change

14:33 algoriffic: when using the clojure.zip api, can branch nodes have data that is not a children of the node?

14:40 technomancy: stuartsierra: are you OK with relicensing your swank-clojure commits under the EPL?

14:40 stuartsierra: yes

14:40 technomancy: great; thanks

14:40 stuartsierra: don't remember making any commits

14:40 technomancy: any other swank contributors in the channel that would like to chime in?

14:41 stuartsierra: I'm just going over raw commit numbers, so build changes are mixed in with the rest of it.

14:41 stuartsierra: oh, ok

14:43 mattrepl: what's change for? but yes, I'm ok with that

14:43 packaging with Clojure?

14:43 technomancy: mattrepl: no, just for general deployments

14:44 algoriffic: anyone with experience using clojure.zip to build trees?

14:44 technomancy: because some of our deployments at work may be considered "distributing", we're currently unable to use swank outside dev scope.

14:44 plus matching licenses with the host environment is just fewer things to worry about

14:44 mattrepl: thanks

14:44 mattrepl: eww, yeah, that's a good point

14:48 slyphon: hrm, what would be a way to represent a jms MessageConsumer as an infinite seq?

14:48 (repeatedly (.receive consumer)) ?

14:48 oh duh

14:48 well

14:48 something like that?

14:49 it would be best if after the consumer's session is shut down, the seq only returns nil

14:49 * slyphon has a feeling he's describing a monad

15:00 slyphon: so, if you do send-off on an agent, it queues up the action to be taken on the agent?

15:00 * slyphon goes to re-read that section in the book

15:01 slyphon: i.e. are you guaranteed order?

15:02 stuartsierra: I think so

15:02 slyphon: http.agent is designed that way

15:02 stuartsierra: agent actions occur in the order they are received

15:02 somnium: a terse little pattern matcher inspired by PLT Scheme's match >> http://github.com/somnium/yap, comments welcome

15:03 slyphon: right, but if you do (send-off agent first-thing) (send-off agent second-thing) ...

15:03 stuartsierra: first-thing happens first

15:03 slyphon: kk

15:03 ok, that's what i thought

15:04 stuartsierra: But if another thread is sending actions, you can't know that first-thing will be immediately followed by second-thing.

15:04 slyphon: right, of course

15:04 i want to, in a single thread, set up a sequence of actions that will take place

15:06 mmarczyk: woo-hoo! just got a Clojure-related GSoC spot! :-D

15:06 http://socghop.appspot.com/gsoc/student_project/show/google/gsoc2010/omii_uk/t127230761862

15:06 sexpbot: " Show Student Project"

15:07 somnium: slyphon: if you just want actions executed in sequence in another thread I think future might be appropriate

15:07 slyphon: somnium: hrm

15:08 technomancy: mmarczyk: wow, that's a lot of acronyms.

15:09 mmarczyk: technomancy: yeah, the project is very proud of them ;-))

15:10 a better description of what this is about:

15:10 http://www.omii.ac.uk/wiki/OgsaDaiDqpClojure

15:10 sexpbot: " OMII-UK: Ogsa Dai Dqp Clojure"

15:13 technomancy: cool

15:13 mmarczyk: :-)

15:24 Hali_303: hi! how to give JVM parameters to leiningen?

15:24 technomancy: Hali_303: JAVA_OPTS should do it

15:24 Hali_303: technomancy: thanks!

15:24 technomancy: np

15:50 slyphon: you know, the stack traces thrown when 'ns' horks could be more helpful

16:01 can you send-off inside an agent modifying function?

16:01 * slyphon tries

17:00 chouser: slyphon: sure, but the send-off is held until the current action completes.

17:00 slyphon: chouser: that's perfect, actually

17:01 an

17:01 man

17:01 "Wrong number of args passed to: PersistentHashMap"

17:02 * slyphon is very confused

17:02 hiredman: maps are functions

17:02 slyphon: hrm

17:02 hiredman: ,({} 1)

17:02 clojurebot: nil

17:02 hiredman: ,({} 1 2)

17:02 clojurebot: 2

17:02 hiredman: ,({} 1 2 3)

17:02 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentArrayMap

17:02 slyphon: oh, weird

17:02 hiredman: ,((hash-map) 1 2 3)

17:02 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentArrayMap

17:03 chouser: heh

17:03 gotcha!

17:03 hiredman:

17:03 slyphon: :D

17:03 * slyphon sighs

17:03 * slyphon tried to figure out where that bug is

17:03 slyphon: tries*

17:03 chouser: slyphon: so really, you're probably calling a map where you mean to be calling something else

17:04 * slyphon nods

17:04 hiredman: (defn x [map] (map foo bar baz))

17:04 patrkris: slyphon: have you tried clojure.stacktrace/e?

17:04 slyphon: i've got like 20 layers of anonymous function wrapping

17:04 patrkris: i don't think so

17:04 chouser: slyphon: you can name your "anonymous" functions, which can help understand stack traces

17:05 slyphon: oh, that shows up in the stacktraces?

17:05 nice

17:05 chouser: yes

17:05 slyphon: cool

17:05 chouser: mangled, but they show up

17:06 hiredman: maybe clojure.stacktrace could include a de-mangler

17:08 slyphon: gak!

17:08 rhickey: does clojurescript have a js reader for clojure data?

17:09 chouser: no, clojurescript relies on clojure's own reader and analyzer

17:09 * slyphon fixed the bug by accident

17:09 * slyphon sighs

17:10 hiredman: my reader written in clojure could be bootstrapped :)

17:10 chouser: rhickey: perhaps clojurescript still works well enough to produce a js version of one of the clojure-readers-in-clojure? :-)

17:10 slyphon: chouser: this is a clojure interpreter in javascript?

17:10 * slyphon googles

17:10 rhickey: chouser: too many moving parts, a reader is so easy

17:11 chouser: slyphon: no, it's a java program that compiles clojure source to javascript.

17:11 rhickey: ok

17:11 slyphon: woah

17:11 rhickey: especially a reader for data

17:11 chouser: slyphon: clojure pre-1.0 source to javascript.

17:12 slyphon: you guys are fucking crazy

17:12 :D

17:12 * slyphon means that as high praise

17:13 chouser: We won't give up until the only thing stopping Clojure from working on every conceivable platform are Apple EULAs.

17:13 rhickey: hah

17:14 hiredman: I guess the most complicated thing in the reader is syntax-quote, which you don't need for data

17:14 slyphon: chouser: hah!

17:14 chouser: rhickey: you're going to write a clojure reader in js??

17:14 rhickey: chouser: write sane web apps?

17:15 chouser: are you asking if I ever have? No. I've tried but they always end up crazy...

17:15 rhickey: dunno really, just seems like JSON is much less expressive than Clojure data

17:15 chouser: ah

17:15 rhickey: chouser: no, not asking, speculating what I would do

17:16 what do the current clojure->json thingies do with, e.g. sets?

17:18 hiredman: ,(encode-to-str #{})

17:18 clojurebot: "[]"

17:18 hiredman: ,(encode-to-str #{:a :b})

17:18 clojurebot: "[\"a\",\"b\"]"

17:18 hiredman: bleh

17:28 eyeris: I have a regex that uses grouping. Is there a way, with the Clojure regex API, to get the indexes of the matching groups?

17:28 dakrone: anyone have a link to that image that explains which one agent/atom/ref/var to use depending on the concurrency needed?

17:28 eyeris: This corresponds to the Java Matcher .start(int group) and .end(int group) members.

17:31 Chousuke: eyeris: I think you need to just use the matcher object directly

17:32 eyeris: Chousuke: Okay, thanks.

17:50 neotyk: I'm trying to build server that can server multiple REPLs at same time, can you guys advice me on how to do that?

17:51 and I would like those repls be separate, so if (def a 42) is executed on one it is not visible on second

17:52 bendlas: Have you looked into swank-clojure?

17:52 hiredman: you'll need either multiple jvms or classloader magicing

17:53 neotyk: also would like not to depend on executing in same thread, if I could store state of repl somehow for later "resuming"

17:53 multiple jvm sound very inefficient

17:53 than class loader magic it will be

17:54 at what level I'll stick it ? in my own reader?

17:55 technomancy: sounds like you also want serializable continuations?

17:56 slyphon: technomancy: don't we all

17:56 neotyk: technomancy: something like that, so I could persist it and later resurect

17:56 technomancy: slyphon: =)

17:57 neotyk: bendlas: no I haven't yet looked at it, was looking at hiredman's clojurebot sandbox

17:58 ,(def a 42)

17:58 clojurebot: DENIED

17:58 bendlas: I've written a timer with restartable delay, comments and advice on idiomaticness, etc. would be helpfull http://gist.github.com/379981

17:58 neotyk: but would like to be able to do that from multiple clients

17:59 bendlas: different namespaces are not an option?

18:00 neotyk: would like to provide users real feel of clojure

18:00 bendlas: feel free to tell me if that's stupid, I'm noob to clojure

18:01 neotyk: so (ns ...) woudl be honored as well

18:01 hiredman: you could possibly patch Namespace.java to persist things to a database

18:01 bradford: anyone know the fastest way to do a remove-at on a vec?

18:01 I'm currently doing two subvecs and then a concat - which feels bad, since it must the be vec'd again to get the result.

18:02 bendlas: right, you want to enforce separation

18:02 neotyk: yes, something like execution context

18:03 bendlas: like a sandbox (in a sandbox it would be then :)

18:03 neotyk: so two clients execute same (def a 42) but it ends up in different contexts

18:04 sandbox has one context

18:04 bendlas: yeah, but maybe there are frameworks to run multiple sandboxed environments in the same vm?

18:05 neotyk: well, are there any?

18:05 djpowell: bradford: i'm surprised there isn't a remove function for vectors

18:06 bradford: djpowell: me too but I can't find one

18:06 djpowell: bradford: i'd guess subvec would work

18:06 bradford: djpowell, I am using two subvecs and a concat now - but then i have to call vec on the result and it feels like there must be a better way.

18:08 technomancy: IIUC vectors aren't designed to be resized easily (apart from conjing on the end)

18:09 djpowell: and popping off the end

18:09 bradford: technomancy, djpowell: yea, but they are designed for subvec, so remove-at should be similar

18:10 technomancy: subvec is ... kind of a hack

18:10 bradford: it's just the normal structure sharing trickery, right?

18:10 technomancy: yeah, but it doesn't let the original get GC'd

18:11 unlike most persistent operations

18:11 bradford: ah, i see

18:11 bendlas: isn't it the same issue with substring?

18:11 bradford: interesting.

18:12 bendlas: like .getSubstring

18:13 djpowell: yeah Java's .substring shares the underlying array

18:14 _brian2_: noob question> Is there an easy idiomatic way to to convert between various kinds of collections? ie to convert a list into a set seems to require a name to a reference and doseq through the list

18:14 lancepantz: _brian2_: i think you're looking for into

18:15 _brian2_: oh, ok, thanks

18:15 djpowell: and if you want to convert to the same collection type, but don't know the type, then (into (empty c) (f c))

18:35 dsantiago: How exactly does the extend macro add to an existing class?

18:55 kmqat: hey all, i'm trying to build labrepl under netbeans via maven. maven can't find the clojure and clojure-contrib 1.2.0 master snapshot jars, even though the build.clojure.org/snapshots repository is specified in the pom and i can find the jars there if i browse manually. thoughts?

19:39 defn: http://groups.google.com/group/clojure/browse_thread/thread/e704414cf36ef2aa : Could anyone comment on whether or not this information is still relevant? (Namely, chouser and rhickey's posts at the end)

19:41 im trying to serialize a ref containing a map a couple levels deep

19:54 kmqat: fixed my labrepl problem. just had to switch from netbeans embedded maven 3 to maven 2 and delete my local repository. odd.

20:01 chouser: defn: yeah, you need to using binding with *print-dup*

20:02 dsantiago: When you call extend, can your functions in the map of implementations be compiled functions? Or do they need to be the source?

20:03 chouser: dsantiago: they're regular function objects, so they can come from anywhere.

20:03 dsantiago: Hm, that's what I thought.

20:03 I keep getting "Unable to resolve symbol: this in this context" as an exception.

20:04 chouser: you need to accept 'this' as an initial argument

20:05 dsantiago: Yeah, I am.

20:09 Oh, does the protocol have to be a symbol? It appears to a map containing all the data of the protocol.

20:09 defn: do i understand correctly that instead of using def instead of a defn i should be using alter-var-root or something like that?

20:09 s/instead/inside

20:10 i'd like to do something like (defn foo [] (def *x* "foo"))

20:10 and have it be accessible everywhere

20:12 chouser: I don't think it's ever recommended to put def inside a defn

20:12 kzar: What kind of pause do you leave between pages when you're scraping a website?

20:13 _ato: defn: yep, use (def foo) (defn foo [] (alter-var-root foo "foo")) -- I assume this is for initialization

20:13 defn: _ato: it is, thanks

20:13 chouser: dsantiago: a protocol is just a map with specific keys/values

20:13 technomancy: how is it that Stuart H was able to co-teach a class with rhickey and still not learn how Clojure is pronounced? =)

20:14 defn: technomancy: haha

20:14 _ato: ,(doc alter-var-root)

20:14 clojurebot: DENIED

20:14 hiredman: ./jrepl.sh

20:14 whoops

20:14 dsantiago: chouser: Yeah. It's just weird, I get different errors when I write it all out myself, vs when I try to extend in my little macro.

20:14 defn: klo-jerr

20:15 also technomancy -- thanks to you for that info on refactoring mire -- that's where i remember reading about using alter-var-root, nice write up

20:15 _ato: defn: whoops you'll probably need to #' quote the var and pass it a function, but yeah you'll figure it out

20:15 technomancy: defn: great. I hope it doesn't make you go off and actually start using alter-var-root all over the place though. =)

20:16 but it is good to know about

20:16 chouser: (extend AType AProtocol {:foo (fn [this x y] ...)}) should do it. Where are you getting "undefined 'this'"?

20:16 technomancy: it helps to start thinking of vars as reference types; it's easy to miss that

20:16 defn: technomancy: haha certainly not -- this is just for reading in some serialized stuff -- mainly this is just for the ease of the user

20:18 dsantiago: I have a list of protocol->{:map of-fns} pairs, and I try to splice that into extend just like you have it. Main difference being that the functions are compiled. Then it throws up that exception.

20:18 I realize it's clearly my macro, I just checked all the arguments and it appears to be what you'd want.

20:20 chouser: dsantiago: perhaps paste your macroexpand output somewhere?

20:20 defn: technomancy: _ato alluded to using #' and passing a function -- here is what im doing: (def *foo*) (defn init-foo [] (alter-var-root #'foo (ref (do some stuff here)))

20:21 err #'*foo'

20:21 that doesnt seem to work -- i get a "No message" error

20:21 dsantiago: chouser: I'd love to, but the exception happens before macroexpand outputs anything.

20:21 chouser: heh. ok, paste your macro?

20:21 dsantiago: OK.

20:22 chouser: lisppaste8: url?

20:23 technomancy: defn: I don't know if earmuffs are appropriate here

20:23 they generally signal rebinding at runtime

20:24 defn: noted

20:24 technomancy: as long as you feel your mutability is constrained enough not to cause issues

20:25 defn: is the way im writing that correct in general? or do i need to lose parens around ref? something isn't right there...

20:25 dsantiago: chouser: https://gist.github.com/af5bd3ad714a11eb58d4

20:25 technomancy: defn: well alter-var-root takes a function as its second arg

20:26 so maybe you meant something like (alter-var-root #'foo #(assoc %1 %2) :stuff-from-file)?

20:26 defn: yeah i dropped the parens around ref so it is (alter-var-root #'myvar ref (deserialize stuff))

20:27 technomancy: if myvar is already a ref then you should use ref semantics to alter it

20:27 defn: it is not a ref yet, it is just (def myvar)

20:27 i was going to make it a ref when i deserialized the file

20:28 technomancy: right, but if it's going to be a ref in the end why not make it a ref pointing to nil up front?

20:28 defn: good point :)

20:28 technomancy: this is why I debated even mentioning alter-var-root =)

20:28 defn: haha

20:31 currivan: test

20:33 Does anyone know how to set -Xmx type parameters from 'lein swank'?

20:34 defn: currivan: yes

20:34 currivan: M-x customize-group swank-clojure

20:34 technomancy: actually doing it from Emacs will only affect M-x swank-clojure-project

20:34 currivan: But I'm running lein swank from the command line and connecting, not launching through emacs.

20:34 defn: under swank-clojure-extra-vm-args you can do (list "-Xms256m" "-Xmx1024m") or whatever

20:34 oh yeah good point

20:34 technomancy: currivan: try setting the JAVA_OPTS environment variable for lein swank

20:35 sattvik: rhickey: Should gen-class support annotations on fields? At the moment, it seems like the only field the user has much control over is the state field.

20:35 currivan: That's an environment var or can it be set in project.clj?

20:35 technomancy: currivan: no way to set it in Clojure since it must be set before the JVM launches

20:35 so yeah, env var

20:36 currivan: Ok, thanks, I'll try that.

20:36 defn: it would be nice if there was some sort of config in the lein project dir where we could set variables like that

20:36 chouser: dsantiago: you're printing the (concat ...) output. that doesn't really look like the forms extend takes...

20:36 lancepantz: technomancy: i think i saw you talking about adding a leinrc at one point, is that still in the cards?

20:37 technomancy: lancepantz: depends on demand I guess. it'll be a couple releases out if it happens.

20:37 if you're volunteering naturally that changes things... =)

20:37 dsantiago: Oh.

20:37 lancepantz: :) it would be useful, but there's other solutions to the problem, so i agree its a low priority

20:38 technomancy: lancepantz: what we need more of is people wandering in here thinking, "I am trying to learn Clojure, but I need a good problem to get started with."

20:38 "delegated!"

20:39 lancepantz: hopefully thats on the rise!

20:39 dsantiago: chouser: Not sure I see what you mean.

20:39 * technomancy wonders if the Ruby Learning online course will bring an appreciable number of folk in here

20:40 currivan: Related question, is there any way to reconnect to a lein repl after disconnecting from emacs?

20:40 Raynes: technomancy: Doesn't seem to be.

20:41 technomancy: Raynes: oh, it's started?

20:41 Raynes: technomancy: 3 days ago.

20:41 defn: technomancy: we're a rare breed, we irc'ers

20:41 technomancy: currivan: I think that might be impossible due to a bug

20:41 needs investigation

20:42 chouser: dsantiago: (count (concat ...)) is 1

20:42 defn: lol technomancy im still struggling on this alter-var-root thing, (def foo (ref nil)) (alter-var-root #'foo (dosync (ref-set foo (deserialize myfile))))

20:42 chouser: dsantiago: I think you want the count to be even

20:43 technomancy: defn: M-s is your friend

20:43 dsantiago: Right, right.

20:43 OK, thanks.

20:43 defn: technomancy: :)

20:43 technomancy: that is: get rid of (alter-var-root #'foo

20:43 defn: oh my god -- what was i thinking!?

20:44 * defn swears off ever using alter-var-root again

20:44 hiredman: good

20:45 technomancy: =)

20:45 dsantiago: Thanks a lot, chouser. I wasn't seeing that.

20:54 currivan: anyone there

21:00 chouser: dsantiago: np

21:10 rhickey: sattvik: no, not until gen-class has fields more like deftype does

21:14 sattvik: rhickey: Thanks, do you have a few minutes? I have a number of questions about what annotations should be supported and how. Or would it be better for me to write an e-mail, comment on the ticket, or post on the dev mailing list?

21:14 rhickey: sattvik: shoot

21:15 sattvik: rhickey: Constructor annotations? If so, I am guessing something like {^{Deprecated true} [String] []}

21:16 rhickey: sattvik: I guess that's ok, if it's easy

21:18 sattvik: rhickey: How about method annotations? At first I thought it would be done like deftype, but what about inherited/overridden methods? It seems like the annotation would have to be read from the implementing function.

21:20 rhickey: sattvik: let's leave out inherited/overriden for now.

21:21 just support the methods in :methods

21:23 sattvik: rhickey: OK, that's fine. Then I won't worry about :init, :post-init, :exposes, and :exposes-methods either, for now.

21:23 rhickey: right

21:24 sattvik: rhickey: However, parameters for methods should be supported. I think you did this earlier today. Wasn't there something else?

21:25 rhickey: parameters for methods are up now. So, types, methods, params, fields

21:26 sattvik: OK, sounds good. For gen-class, it will support types, non-overriding methods, and method params. I have types working. Perhaps I'll finish the rest tomorrow.

21:27 rhickey: sattvik: cool - thanks!

21:29 sattvik: No problem. It is a fun task. Thanks for your input.

21:56 currivan: Anyone here? What's a better server?

22:03 livingston: if i have a java string array in the form of k1 v1 k2 v2 ... obviously I can get that into a clojure seq but what's the fastest easiest way to turn that into a map

22:03 defn: could anyone comment on the appropriate use of earmuffs?

22:04 note: i will roll my eyes at you if you say something about wearing them when it's cold outside.

22:04 livingston: obviously I could do that with recur and conj but I bet there is something slicker

22:04 defn: livingston: some interleave zipmap combination or something?

22:05 lancepantz: thats what i was about to say

22:05 hiredman: ,(let [x (into-array [1 2 3 4])] (zipmap (take-nth 1 x) (take-nth 2 x)))

22:05 clojurebot: {2 3, 1 1}

22:05 chouser: ,(apply hash-map (into-array [1 2 3 4]))

22:05 clojurebot: {1 2, 3 4}

22:07 livingston: (into-array [1 2 3 4])

22:07 whoops wrong window

22:07 chouser: defn: earmuffs are for vars that you intend to be thread-locally bound with 'binding'

22:07 Blkt: does anyone know where to find a good clojure.contrib.sql example? (already looked at sql tests)

22:08 remleduff: If I have collections a and b, where b is either the same size as a, or nil, is there an elegant way to map over both of them without some sort of if?

22:09 Blkt: what function do you have to map?

22:09 remleduff: (map + [1 2 3] [1 2 3])

22:09 (map + [1 2 3])

22:09 Blkt: ,(map + [1 2 3])

22:09 clojurebot: (1 2 3)

22:10 Blkt: ,(map + (1 2 3) (4 5 6))

22:10 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

22:10 remleduff: I'm calling an enlive template function that either takes "items" or "items" and "ranks"

22:10 Blkt: ,(map + [1 2 3] [4 5 6])

22:10 clojurebot: (5 7 9)

22:11 remleduff: ,(map + [1 2 3] nil)

22:11 clojurebot: ()

22:11 remleduff: That's my problem

22:11 Blkt: ,(map (lambda (x y) (cons x y)) [1 2 3] [4 5 6])

22:11 clojurebot: java.lang.Exception: Unable to resolve symbol: lambda in this context

22:11 defn: lambda!? :)

22:11 Blkt: sorry

22:11 that's true

22:11 defn: haha it's fine i know wha tyou mean

22:11 livingston: chouser: hiredman: apply hash-map is probably effecient enough, that's probably not cons-ing up too much compared to the zipmap solution, I don't thing, right? over the zipmap option (which seems more confusing)

22:12 Blkt: (map (fn (x y) (cons x y)) [1 2 3] [4 5 6])

22:12 ,(map (fn (x y) (cons x y)) [1 2 3] [4 5 6])

22:12 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol

22:12 livingston: Blkt: nice, I think that way still too ;)

22:12 defn: ,(map #(fn [x y] (cons x y)) [1 2 3] [4 5 6])

22:12 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--11884$fn

22:12 Blkt: :D

22:12 defn: blech

22:13 Blkt: ,(map (fn (x y) (cons (list x) (list y))) [1 2 3] [4 5 6])

22:13 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol

22:13 Blkt: ...

22:13 livingston: ,(map (fn [x y] (cons x y)) [1 2 3] [4 5 6])

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

22:13 defn: Blkt: dont put your x y in ()

22:13 Blkt: true, sorry again :D

22:13 defn: oh i think i see what you need

22:13 Blkt: > Blkt: dont put your x y in ()

22:13 ERC> > Blkt: dont put your x y in ()

22:13 ERC> wtf

22:14 livingston: apparently that's not the only error ...

22:14 Blkt: ,(map (fn [x y] (cons (list x) (list y))) [1 2 3] [4 5 6])

22:14 clojurebot: (((1) 4) ((2) 5) ((3) 6))

22:14 Blkt: almost right...

22:14 livingston: as ugly as it sounds you probably want to map apply in this case

22:14 Blkt: I think that a struct or something like that should be better

22:14 defn: ,(map #(cons %1 %2) [1 2 3] [4 5 6])

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

22:15 _ato: ,(map #(list %1 %2) [1 2 3] [4 5 6])

22:15 clojurebot: ((1 4) (2 5) (3 6))

22:15 * defn wipes sweat, thanks _ato

22:15 hiredman: _ato: please

22:15 list

22:15 livingston: or something close to mapping apply

22:15 Blkt: remleduff: do you like it that way?

22:16 livingston: hiredman: lol, at least there wasn't a (if (= x y) true)

22:16 defn: this seems like something that could be done with destructuring

22:16 _ato: I think I missed the question

22:18 livingston: ah I know why I can't apply hash-map, unfortunately... sometimes I need to get the keys and values flipped to be {v1 k1, v2 k2 ...}

22:18 Blkt: why would u need that?

22:19 defn: ,(let [[[x y] [[1 2 3] [4 5 6]]] [x y])

22:19 clojurebot: Unmatched delimiter: )

22:19 slyphon: heh

22:19 kind of looks like clojurebot is laughing at you

22:19 livingston: Blkt: need what?

22:19 defn: ,(let [[[x y] & [xs ys]] [[1 2 3] [4 5 6]]] [x y])

22:19 clojurebot: [1 2]

22:19 Blkt: to flip keys and values

22:19 defn: hmm, i wonder...

22:20 livingston: Blkt: because if I want to run my substitutions the other way... the inverse operation

22:21 defn: slyphon: oh, im sure the bot can't laugh

22:21 slyphon: hiredman, on the other hand. ;)

22:21 slyphon: hahahaha

22:21 :)

22:21 clojurebot: botsnack

22:21 clojurebot: thanks; that was delicious. (nom nom nom)

22:21 slyphon: :D

22:21 Blkt: livingston: can't you wrap it in something like (zipmap (values *yourmap*) (keys *yourmap*))

22:22 defn: haha

22:22 slyphon: it's funny, sometimes my kid will actually make that sound when he's really enjoying something

22:22 rhudson: remleduff: (defn vmap [f & seqs] (apply map f seqs))

22:22 slyphon: (he's 14 months)

22:22 defn: livingston: could you restate your question?

22:22 or is this for remleduff?

22:23 remleduff: ,(doc vmap)

22:23 clojurebot: Titim gan éirí ort.

22:24 rhudson: No, that's the defn of a vmap function that does what you want

22:24 Then (vmap + [1 2 3]) => (1 2 3)

22:24 remleduff: Oh, gotcha! Thanks :)

22:24 rhudson: and (vmap + [1 2 3] [4 5 6] ) => (5 7 9)

22:24 slyphon: so, if i wanted to model a jms MessageConsumer as a sequence of messages, and have it so that when the consumer was closed (it returns nil) the seq only returned nil, uhm, what should i look at for an example of how to do that?

22:24 defn: slyphon: haha, it's cute until they're 14 years, then the nom nom nom thing is just annoying

22:24 livingston: defn: I just have the sequection (k1 v1 k2 v2) and I was just looking for an effeceint way to get that into the hashes {k1 v1 k2 v2} and also {v1 k1 v2 k2}

22:25 slyphon: defn: hahaha

22:25 defn: slyphon: and then you realize you're doing it yourself

22:25 slyphon: defn: yeah, then it's probably intentional

22:25 defn: HA!

22:25 remleduff: ,(let [m [{:id 1}{:id 2}{:id 3}] ](map assoc m (repeat :newkey) [4 5 6]))

22:25 clojurebot: ({:newkey 4, :id 1} {:newkey 5, :id 2} {:newkey 6, :id 3})

22:25 defn: livingston: ah okay

22:25 remleduff: That's what I've ended up with since "item" is a map and rank can conceivably be considered an aspect of items

22:25 defn: i really think this is possible with some fancy destructuring

22:26 but im just not skilled enough to do it

22:26 livingston: defn: yeah so I can just loop recur with conj, but I thought there was something nicer

22:28 Blkt: livingston: (zipmap (values *originalmap*) (keys *originalmap*))

22:29 defn: ,(let [m {:foo 1 :bar 2}, k (keys m), v (vals m)] [(zipmap k v) (zipmap v k)])

22:29 clojurebot: [{:bar 2, :foo 1} {2 :bar, 1 :foo}]

22:29 Blkt: ,(let [mappa {a 1 b 2 c 3}] (zipmap (values mappa) (keys mappa)))

22:29 clojurebot: java.lang.Exception: Unable to resolve symbol: a in this context

22:29 livingston: Blkt: that'll reverse it but starting with the inverse that's a 3 pass solution loop conj is still better (and I think there is a built-in to flip maps)

22:30 Blkt: I see

22:30 remleduff: defn: How about (apply assoc {} [1 1 2 2 3 3]) ?

22:30 defn: i wonder if there is something in contrib

22:30 remleduff: that's pretty nice i think

22:32 livingston: remleduff: that's the same as apply hash-map, but that still can't be modified to flip the k/v pairs in reverse

22:33 slyphon: there's clojure.set.map-invert

22:33 Blkt: does anyone succesfully used clojure.contrib.sql ?

22:34 defn: livingston: why not?booya

22:34 slyphon: Blkt: yep

22:34 defn: clojure.set is great

22:34 Blkt: slyphon: could u link me a good example?

22:34 slyphon: it's win

22:34 Blkt: hrm

22:34 Blkt: my version fails badly...

22:35 slyphon: Blkt: i think i used this to get started (more or less) http://ericlavigne.wordpress.com/2008/12/28/using-postgresql-with-compojure/

22:35 sexpbot: "Using PostgreSQL with Compojure « Eric Lavigne"

22:35 Blkt: thanks

22:35 slyphon: sure

22:36 livingston: slyphon: I could invert it, but since I'd have to build the map in the first place to do that, I'd rather just build it in the right order at that time

22:36 lancepantz: Blkt: http://github.com/stuarthalloway/programming-clojure/blob/master/examples/snippet.clj

22:37 Blkt: thanks a lot

22:37 lancepantz: np

22:37 defn: i need to include stuart's examples in walton

22:38 maybe cut out all of the inner expressions from def and defn

22:40 Blkt: may I ask which kind of ide/editor you guys use?

22:40 defn: emacs

22:40 lancepantz: vim

22:40 defn: no, emacs! ;)

22:41 lancepantz: not saying it's better :P

22:41 defn: Blkt: frankly i think emacs is a better IDE-type environment, but if you know vim I wouldn't go out of my way to learn it.

22:41 they're pretty much the same thing, just different

22:41 emacs is sort of nice because as i've learned clojure i've picked up a lot of emacs lisp as a sort of bonus

22:41 lancepantz: i think most people go with emacs/vim/netbeans depending on what they use

22:42 if i had to pick one to learn it'd be emacs

22:42 Blkt: defn: I mostly use emacs (though I'm not uberskilled with it) but I'm having problems configuring clojure-slime on Windows

22:42 rhudson: I'll put in a vote for La Clojure (IntelliJ)

22:42 defn: Blkt: using elpa?

22:42 Blkt: y

22:42 spawning child process: invalid argument

22:43 defn: you shouldn't have to do much work at all IIRC, once you have elpa you just grab clojure-mode, clojure-test-mode, slime, slime-repl, and swank-clojure i think

22:43 then M-x slime

22:43 or M-x swank-clojure-project and navigate to the project root

22:43 Blkt: I was wondering if that's avoidable

22:43 defn: i believe the first time you run M-x slime it will install clojure and clojure-contrib for you

22:44 Blkt: if what is avoidable?

22:44 Blkt: I had SBCL messed up on my laptop thanks to that autoconfiguration

22:44 elpa

22:44 defn: ah, you can use SBCL + clojure without much setup -- think you just need to set some var for additional inferior lisps

22:45 Blkt: wish it was that easy

22:45 * chouser wishes for macrolet

22:45 Blkt: I should dinamically load one of two different slime versions at emacs' startup

22:46 inferior lisp only doesen't work

22:46 for what I've been able to do at least...

22:46 I'll try out, anyway, no ide anyone?

22:47 defn: enclojure?

22:47 lithper1_: two separate .emacs files should work

22:47 Blkt: and two different launchers too

22:48 defn: did you try enclojure?

22:49 defn: i think i did for like 20min, but ive gotten used to my emacs setup

22:50 i like having choices

22:50 Blkt: :)

22:50 defn: and really, if something is messed up like your config, it's just a matter of time before you figure out the problem or write some elisp to work around it

22:52 livingston: ,(reduce (fn [m [v k]] (assoc m k v)) {} (partition 2 '(v1 k1 v2 k2 v3 k3)) )

22:52 clojurebot: {k3 v3, k2 v2, k1 v1}

22:53 livingston: that's the best I figured out for that given a sequence such as that for input

22:56 rhudson: ,(apply hash-map (reverse [:v1 :k1 :v2 :k2]))

22:56 clojurebot: {:k1 :v1, :k2 :v2}

22:57 livingston: rhudson: nice, very clever

22:57 presumably that's even slightly less consing because of the no nested lists

22:58 Blkt: ,(reverse [:v1 :k1 :v2 :k2])

22:58 clojurebot: (:k2 :v2 :k1 :v1)

22:58 Blkt: nice

23:01 chouser: it's not actually a vector, right? Otherwise you should consider 'rseq'

23:02 livingston: it's a Java string array actually (the seq operations just handle it) are Java arrays intercahable with vectors?

23:12 defn: ,(type [1 2 3])

23:12 clojurebot: clojure.lang.PersistentVector

23:14 slyphon: is there a recommended way to mock java objects in clojure unittests?

23:14 is there a mocking lib for java that's not sucktastic?

23:20 rhudson: livingston, do you need both forward & reverse maps from the same string array?

23:21 livingston: rhudson: yes, but not at the same time

23:21 sometimes I'll need it one way sometimes the other, why?

23:22 rhudson: Well, (vec array) gives you a vector, presumably a simple copy of the whole array.

23:23 Then you can use (rseq v) to get the reverse map, and v to get the forward map

23:23 ,(doc rseq)

23:23 clojurebot: "([rev]); Returns, in constant time, a seq of the items in rev (which can be a vector or sorted-map), in reverse order. If rev is empty returns nil"

23:23 livingston: (i'm asking a RDF server for what it's mappings are from short-hand namespaces to long-form --- sometimes I'm translating one way, sometimes the other so...)

23:23 oh very cool

23:24 so if I vec the array off the bat is that any more or less expensive than whatever behavior I get if I just let some sequence handling function do it's business?

23:25 rhudson: Likely not worth it for the forward case

23:26 livingston: for the reverse calse I'm just calling reverse on the java array, I'm assuming that will do the fastest thing it can, right?

23:26 calse -> case

23:27 rhudson: looks like (class (reverse array)) is a PersistentList

23:28 But I don't know the implementation to know whether that's a chain of cons or something more efficient

23:30 livingston: fair enough

23:30 thanks

23:47 if I have a var *foo* it's not expense to call (bindings [*foo* *foo*] is it?

23:48 it would make my macro a lot more clean

Logging service provided by n01se.net