#clojure log - Mar 29 2010

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

0:27 Raynes: alexyk: Sure. Reify, deftype, defprotocol, and most of all, optional keyword argument destructuring. :D

0:27 alexyk: Raynes: I need a writeup for the dumb ones!

0:27 or, for those who like to read!

0:32 * joshua-choi whoops at optional keyword argument destructuring

0:47 brian__: test

0:49 hi, is it possible to use a regex as a predicate to the "filter" function? I want to filter out things from text?

0:51 joshua-choi: What you should use is (partial re-matches your-re).

0:51 brian__: ok

0:51 thnks

0:52 tomoj: re-matches has always seemed a bit strange t ome

0:52 oh, re-find is what I was looking for

0:54 brian__: ok, well, ill take notice of your comment, thanks

0:57 tomoj: e.g.

0:57 ,(let [matcher (re-matcher #"foo (\S+)" "foo bar foo baz")] (take-while identity (repeatedly #(re-find matcher))))

0:57 clojurebot: (["foo bar" "bar"] ["foo baz" "baz"])

0:57 tomoj: how do we do that more simply?

0:57 oh, re-seq

0:57 of course

0:57 noidi: cemerick, thanks again for the maven post! I converted my hobby project to maven last weekend and now it's simpler, has more features and the dependencies are handled better :)

0:58 tomoj: ,(re-seq #"foo (\S+)" "foo bar foo baz")

0:58 clojurebot: (["foo bar" "bar"] ["foo baz" "baz"])

0:58 cemerick: noidi: nice, glad to hear it. Feel free to share the good news. ;-)

0:58 The polyglot maven stuff appears to be moving along at a faster clip again, which is even better news IMO.

0:59 I might cut a quick demo of that shortly as well, just to provide a complete perspective on where things stand.

0:59 tomoj: cemerick: awesome :)

1:01 noidi: cemerick, it's a bit early to start singing maven's praises, but if a few months go by without problems I'll be a complete convert :)

1:01 cemerick: noidi: sure, that's why I included the ;-)

1:01 :-D

1:01 noidi: :P

1:03 I think what scares people about maven is that it has a lot of new concepts, like the lifecycle, the local and remote repositories etc.

1:04 but they're actually very useful concepts once you learn them

1:07 actually make/etc. vs. maven reminds me a lot of word vs LaTeX... the latter looks incredibly dense and unflexible at first, but when you take the time to learn it, it automates a lot of tedious manual work

1:07 tomoj: hmm

1:07 that comparison is enough to make me try to learn this maven stuff

1:07 I became quite angry when a professor forced me to submit .doc files

1:09 * talios trondles off home - see you later folks

1:10 cemerick: noidi: nice analogy

1:35 AntonyBlakey: ping

1:57 * talios wanders back in

1:58 talios: wb tomoj

1:58 tomoj: thanks

1:58 finally got wifi after suspend/resume working

1:58 :)

1:59 talios: I only just got home/rejoined anyway :)

1:59 tomoj: my wifi has been flapping

1:59 and I habitually M-x freenode so I end up flapping on freenode too :/

2:00 talios: darn emacs user :)

2:01 I could never really get into emacs, I like it more than vi ho

2:01 tho

2:05 tomoj: well, there's hope for you yet

2:05 :P

2:05 talios: You can pry IntelliJ from my cold dead decaying remains.

2:07 tomoj: I don't think emacs can replace intellij for java

2:08 I haven't tried any of the non-emacs clojure tools either :/

2:09 AntonyBlakey: Netbeans/Encloure/PolyglotMaven is turning out to be quite cool.

2:09 tomoj: t

2:09 oops

2:09 really need to disable mouse focusing...

2:10 I plan to make some screencasts about emacs, with some about clojure

2:10 I wonder if anyone has made any for the other tools..

2:10 AntonyBlakey: Yes they have

2:11 talios: tomoj: did you see cemerick's recent video on maven/netbeans with clojure/

2:11 ?

2:11 AntonyBlakey: A good emacs + clojure screencast would be one focusing on typical workflows, with supporting docs for the key binding

2:33 tomoj: talios: hadn't seen that

2:34 AntonyBlakey: I'd intended to focus on typical workflows, basically covering the stuff that I use alot

2:34 good idea re the supporting docs

2:34 especially important with emacs... :(

2:35 AntonyBlakey: It would be good to see a walkthrough of a typical dev session involving multiple source files, xref-ing, building, debugging, packaging etc. So that the view can place themselves in your position and see all the things they need to do to develop in that environment.

2:36 s/view/viewer/

2:37 If the supporting docs were a form an annotated transcript then it would be a great multi-modal learning resource

2:37 s/form an/form of/

2:37 tomoj: hadn't thought of that

2:38 could make a blog-post style writeup mirroring the screencast

2:38 then also provide a reference of all important functions/bindings

2:38 talios: I wonder if there's too much focus on the REPL?

2:38 not that the REPL is bad

2:38 AntonyBlakey: Make the whole thing available as a PDF to go with the video. Easy to print and cogitate on offline, and to have next to you while trying your own stuff.

2:39 tomoj: just have to learn how to make pretty pdfs

2:39 AntonyBlakey: IMO there is too much focus on the REPL as a development environment. Not all programming is exploratory.

2:39 talios: tomoj: I have clojure code for that ;-)

2:40 tomoj: I'd probably try it in org-mode

2:40 talios: tomoj: http://www.talios.com/connecting_the_clouds__the_internet_in_new_zealand_in_pdf.htm <- using clojure + flying saucer to make PDFs

2:40 tomoj: that post + pdf actually got me a 'cease and desist' letter from Internet NZ ;-)

2:41 the actual PDF code is the last 4 lines. which just takes an HTML file with CSS and PDfs it

2:41 tomoj: nice

2:42 talios: mmm, must rewrite it to generate an .epub version of that book :)

2:42 we use flyingsaucer at work for all our report generation

2:44 AntonyBlakey: I've used http://www.princexml.com/ commercially, which gives great results

2:44 talios: we looked at prince, then looked at the price, then looked elsewhere :)

2:45 AntonyBlakey: It's written in Mercury, which appeals.

2:45 Yes, it's expensive for commercial use, although I got a good deal 'cos I was working on an Aid project.

2:45 talios: I don't think I know of Mercury? It rings a bell

2:45 AntonyBlakey: It's free for non-com

2:46 tomoj: http://en.wikipedia.org/wiki/Mercury_(programming_language) interesting

2:46 I'd never heard of it either

2:46 AntonyBlakey: Mercury is like prolog, but with arg typing that makes it efficient

2:48 talios: interesting

2:49 bbl - making myself some dinner, getting hungry here ;)

3:03 LauJensen: Morning all

3:04 Raynes: I think I've heard of most languages at this point.

3:04 Morning Lau.

3:50 wooby: 'lein test' doesn't seem to be referring a certain macro from my tested code, anyone run into something like that before?

3:50 things work nicely in clojure-test-mode

3:58 tomoj: wooby: you mean you get an error because the macro is missing?

3:59 wooby: tomoj, right

4:00 tomoj: hmm

4:00 wooby: i tried to 'lein compile' manually beforehand, didn't seem to make a difference

4:01 http://github.com/alandipert/clj-utils/blob/master/test/org/dipert/test/utils.clj is the code if you'd care to sanity check

4:01 the mystery macro is 'with-private-vars'

4:02 tomoj: puzzling

4:02 I expected you might have to explicitly use the package that defines it

4:02 but you already have :(

4:08 wooby: I see the same error

4:08 wooby: tomoj, thanks for checking, i'm going to look at lein now

4:08 tomoj, are you using a recent lein?

4:09 tomoj: wooby: 1.1.0

4:10 wooby: the problem appears to be that the ns declaration in org.dipert.test.utils is bad

4:11 (:use clojure.test org.dipert.utils)

4:11 only wrap in a list if it's actually a prefix list

4:11 e.g. in the src file, (:use (clojure.contrib math)) works because that's really a prefix list

4:11 wooby: tomoj, you rule!

4:11 thanks

4:12 tomoj: going to confirm that this happens everywhere

4:12 wooby: sweet that fixed it

4:12 tomoj: yeah, when I try using (clojure.test), I get an error about deftest, even when using clojure-test-mode

4:13 Raynes: ,(seq (.split "reege..wf2rewf." "."))

4:13 clojurebot: nil

4:13 Raynes: Huh? :o

4:14 tomoj: ,(seq (.split "reege..wf2rewf." "\\."))

4:14 clojurebot: ("reege" "" "wf2rewf")

4:14 tomoj: it's a regex :/

4:14 Raynes: Screw those nasty things. :|

4:22 wooby: thanks again tomoj, i'm headed out

5:45 talios: /join #java

5:45 bah

6:11 'lo miclorb

6:11 miclorb: talios: ola

6:12 * talios watches an illegal argument mixdown

6:12 miclorb: excellent

6:12 talios: now if only tony and richard would get their edits done I could publish this :) I think 36/37 should go out BEFORE 38 :)

6:13 maybe we should care less about removing ums and ars and silence more.. be good to get a more regular publishing going again

6:13 not heard you on the asylum lately either?

6:14 miclorb: yeah - or just go for the biggest silences

6:14 yeah hasn't been one recorded for a month (aim is only one a month)

6:14 max has been travelling, lots of eclipse activity this time of year etc

6:14 talios: true. looking forward to seeing some videos out of eclipsecon

6:15 miclorb: talios: my eyes still glaze over when I hear osgi, so I gather eclipsecon would be a bit boring for me

6:16 talios: *nod* I still think we would have been more productive if we didn't go OSGi at work, but that decision was made before I started

6:17 modularisation via maven + IoC would have served us just as well I think.

6:17 miclorb: yeah I assume it must be important to some, but I just don't care for the details - too removed from anything I care about

6:18 talios: BTW I retiring from red hat

6:18 will still do the podcast though

6:18 talios: oh? leaving drools as well, or just RH?

6:18 miclorb: just RH - will still contribute, but not that actively

6:19 talios: cool. So what are you doing? Going anywhere hip and c00l?

6:19 miclorb: workign on a startup - hopefully more will be public soon

6:19 but has made me thinkg if we would use maven or not - kind of makes sense for open source projects etc...

6:20 but otherwise - is it worth it? what worries me is hermetically sealed builds

6:20 talios: yeh, do you want to waste your time on builds and arguements on builds, or get your startup - started up.

6:21 miclorb: yeah - I find it easier if a lib is in maven just to slap in the dependency.. and whee... that bit I like

6:21 anything that does that at least is good

6:22 I have this fear though, which has been validated, I go on 3 week holiday, come back, and my code, in the same statae, no longer builds

6:22 due to some dep change... just kind of unpleasant ;)

6:22 talios: well, if you lock down your version numbers that doesn't happen. and plugin versions have been locked by maven itself for awhile

6:23 miclorb: true

6:23 this was specifically with the jetty plugin (used for testing etc) about 6 months ago

6:23 had to go change my pom

6:23 talios: tho Richard pointed out that grails had a spring dep on [2.0,) - which pulled in 3.x and broke everything :)

6:23 miclorb: just annoyed me

6:23 hahahahah

6:23 yeah version ranges scare me

6:24 the best build system to me is one someone else deals with ;)

6:27 talios: so what sort of things are you doing with clojure? I didn't realise you were looking at it

6:28 miclorb: nothing at the moment, just curious

6:30 talios: curious is a good place to be. One thing I love about clojure is its bringing some enjoyment back into coding small things again, in a way thats non-worky

6:30 er, $worky even

6:30 Licenser_: hmm what is a good way to persistantly store data in clojure?

6:32 _ato: Licenser_: if it's small I just 'prn' stuff to a file and 'read' it back in. (well to be safer, prn to file.new, flush, then rename file.new to file)

6:32 talios: Licenser_: as in database? sql? I've seen a few people using neo4j and db4o, theres some nice clojure wrappers for them

6:33 Licenser_: I want something that does not require any extra effort, prn'ing stuff seems as a way but how fast/secure is it?

6:33 miclorb: talios: my only problem with clojure is that is painfully practical for me. With scheme I can keep it fun and at arms length ;)

6:33 Licenser_: I hoped that fleetdb works as an integrated database (without the need of a server) but it does not seem to do that

6:39 _ato: if you're worried about security (eg random people can mess with the stored file) then I guess spitting JSON out would be safer

6:39 although prn/read aren't bad you just need to remember to turn off the eval reader macro when reading

6:40 Licenser_: hmm eval reader macro?

6:40 _ato: ,(read-string "#=(println \"hi\")")

6:40 clojurebot: java.lang.RuntimeException: java.lang.Exception: EvalReader not allowed when *read-eval* is false.

6:40 _ato: heh

6:40 ,(binding [*read-eval* true] (read-string "#=(println \"hi\")"))

6:40 clojurebot: hi

6:41 _ato: *read-eval* normally defaults to true, I wonder if thats changed in git master or something

6:41 Licenser_: ,(binding [*read-eval* true] (read-string "#=(def x 1)"))

6:41 clojurebot: java.lang.RuntimeException: java.lang.Exception: Can't resolve def

6:42 Licenser_: ouch

6:42 ouch ouch

6:42 Chousuke: :P

6:42 Licenser_: my sandbox does not check that

6:43 ,(binding [*read-eval* true] (read-string "#=(java.lang.Thread.)"))

6:43 clojurebot: #<Thread Thread[Thread-299,5,main]>

6:43 Licenser_: Ouch

6:43 clojure bot neither

6:43 Chousuke: I don't think it's even possible to guard against that :P

6:43 unless you can somehow make a var that doesn't support thread-local binding

6:43 Licenser_: Chousuke: I'll find a way

6:45 _ato: ,(binding [*read-eval* true] (read-string "#=(.alterVarRoot #'inc (fn [x] dec) [])"))

6:45 clojurebot: java.lang.RuntimeException: java.lang.Exception: Can't resolve .alterVarRoot

6:47 _ato: ,(binding [*read-eval* true] (read-string "#=(println (.alterVarRoot #'inc (fn [x] dec) []))"))

6:47 clojurebot: (.alterVarRoot (var inc) (fn [x] dec) [])

6:48 _ato: strange

6:48 Chousuke: it doesn't actually evaluate things

6:49 ,(binding [*read-eval* true] (read-string "#=(type foo)))

6:49 clojurebot: EOF while reading string

6:49 Chousuke: ,(binding [*read-eval* true] (read-string "#=(type foo)"))

6:49 clojurebot: clojure.lang.Symbol

6:49 _ato: oh right

6:49 Chousuke: ,(binding [*read-eval* true] (read-string "#=(type (eval +))"))

6:49 clojurebot: clojure.lang.PersistentList

6:49 Chousuke: oops

6:49 ,(binding [*read-eval* true] (read-string "#=(eval (type +))"))

6:49 clojurebot: clojure.core$_PLUS___4518

6:50 _ato: ,(binding [*read-eval* true] (read-string "#=(eval (.alterVarRoot #'inc (fn [x] dec) []))"))

6:50 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: No matching method found: alterVarRoot for class clojure.lang.Var

6:50 _ato: ,(binding [*read-eval* true] (read-string "#=(eval (.alterRoot #'inc (fn [x] dec) []))"))

6:50 clojurebot: java.lang.RuntimeException: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.ISeq

6:50 _ato: ,(binding [*read-eval* true] (read-string "#=(eval (.alterRoot #'inc (fn [x] dec) (seqf [])))"))

6:50 clojurebot: java.lang.RuntimeException: java.lang.Exception: Unable to resolve symbol: seqf in this context

6:50 Chousuke: :P

6:50 _ato: ,(binding [*read-eval* true] (read-string "#=(eval (.alterRoot #'inc (fn [x] dec) (seq [])))"))

6:50 clojurebot: #<core$dec__4586 clojure.core$dec__4586@13a1b2>

6:50 _ato: ,(inc 2)

6:50 Chousuke: ,(inc 1)

6:50 clojurebot: 3

6:50 2

6:50 _ato: aww

6:50 oh right

6:50 inc is a bad example

6:50 it'll be inlined

6:51 ,(apply inc [2])

6:51 clojurebot: 1

6:51 _ato: ha

6:51 Chousuke: now please fix it :P

6:51 patrkris: does anyone here know which property to check to see if the JVM is started with the -server flag?

6:51 _ato: whats it normally bound to.. something in clojure.lang.Numbers isn't it? hmmm

6:51 Licenser_: ouch!

6:51 tomoj: you could just check the process?

6:52 _ato: yeah

6:52 tomoj: unless you need to do this in a clojure program?

6:52 Chousuke: _ato: just (+ x 1) ought to be enough

6:52 Licenser_: okay thar'd not be possible with my sandbox I hope

6:52 patrkris: tomoj: Yeah I'd like to do it from a clojure program

6:52 _ato: ,(binding [*read-eval* true] (read-string "#=(eval (.alterRoot #'inc (fn [x] #(clojure.lang.Numbers/inc %)) (seq [])))"))

6:52 clojurebot: #<sandbox$eval__5403$fn__5405$fn__5407 sandbox$eval__5403$fn__5405$fn__5407@15ca0cc>

6:52 _ato: ,(apply inc [2])

6:52 clojurebot: 3

6:52 tomoj: _ato: !!

6:53 why did clojurebot let you do that?

6:53 _ato: cause I just found a hole in its sandbox

6:53 tomoj: the #= read macro doesn't call eval?

6:53 ,(eval '(+ 2 3))

6:53 clojurebot: DENIED

6:54 tomoj: I'm confused

6:54 Licenser_: hmm wait it should

6:54 narf

6:54 Chousuke: tomoj: clojurebot actually checks for the symbol eval, not the string

6:54 tomoj: please blog this

6:54 oh, hmm, interesting

6:54 Chousuke: please don't :P

6:54 tomoj: blog it after it's fixed, I mean

6:54 Chousuke: is it worth a blog entry? :/

6:55 _ato: ,(binding [*read-eval* true] (read-string "#=(eval (defn hiredman-should-fix-this [x] (+ x 5)))"))

6:55 clojurebot: #'sandbox/hiredman-should-fix-this

6:55 tomoj: I think it leads to some deeper knowledge on the innards of clojure

6:55 _ato: ,(hireman-should-fix-this 3)

6:55 clojurebot: java.lang.Exception: Unable to resolve symbol: hireman-should-fix-this in this context

6:55 Chousuke: it's just a hole in clojurebot's sandbox.

6:55 _ato: ,(hiredman-should-fix-this 3)

6:55 clojurebot: 8

6:55 _ato: yeah, okay, I'll stop playing with that now

6:55 tomoj: hehe

6:55 but I still don't understand it, so I think I'm missing some background knowledge about clojure somewhere

6:56 _ato: simple enough to fix I guess, just add *read-eval* to the blacklist

6:56 Chousuke: I suppose hiredman will need to add a check for *read-eval* in the string to be read

6:56 _ato: yeah

6:56 Chousuke: tomoj: #=() is normally read-time eval

6:56 tomoj: *read-eval* bound to false disables that

6:56 tomoj: right, so we would use that for printable and readable data structures?

6:56 _ato: yep

6:56 tomoj: other than just the ones we've got

6:57 kind sucks that we can't demo that in clojurebot

6:57 hmm, how do datatypes fare for readably printing?

6:57 Chousuke: well, yes, but it's not very secure

6:57 datatypes have their own syntax

6:57 #:foo{:key val :key2 val2}

6:57 tomoj: awesome, I need to investigate this

6:57 hadn't tried it yet

6:58 Licenser_: ah no does not work

6:58 tomoj: can't read it?

6:58 Licenser_: no I mean on my sandbox sinde you can't use bindings

6:59 tomoj: oh

6:59 no bindings either?? why not?

6:59 Licenser_: I forgot them :(

6:59 I wonder if they are secure

6:59 tomoj: maybe there are some certain bindings you want to deny

6:59 Licenser_: also it'd not allow you to rebind *read-eval*

6:59 java.lang.SecurityException: Code did not pass sandbox guidelines: (#'clojure.core/push-thread-bindings #'clojure.core/*read-eval* #'clojure.core/read-string #'clojure.core/pop-thread-bindings)

7:00 that it what it says

7:00 tomoj: *print-level*

7:00 though clojurebot deals with that outside the sandbox, I guess?

7:00 Licenser_: in the clj-sandbox you've to whitelist stuff

7:00 tomoj: Licenser_: that's very interesting for certain kinds of applications :)

7:00 Licenser_: ,(binding [*read-eval* true] (read-string "#=(eval (type +))"))

7:00 clojurebot: clojure.core$_PLUS___4518

7:01 Licenser_: ,(binding [*read-eval* true] (read-string "#=(eval (java.lang.File. \"/tmp\"))"))

7:01 clojurebot: java.lang.RuntimeException: java.lang.ClassNotFoundException: java.lang.File

7:01 Licenser_: ,(binding [*read-eval* true] (read-string "#=(eval (java.io.File. \"/tmp\"))"))

7:01 clojurebot: #<File /tmp>

7:01 Licenser_: yuck, THAT is dangerous

7:01 _ato: ,(java.io.File. "/tmp")

7:01 clojurebot: #<File /tmp>

7:01 Chousuke: That's not dangerous yet

7:01 tomoj: java will block your reads, right?

7:01 _ato: yeah

7:02 tomoj: could you also run it in a chroot jail or something

7:02 Licenser_: ,(java.io.File. "/etc/profile")

7:02 clojurebot: #<File /etc/profile>

7:02 _ato: ,(binding [*read-eval* true] (read-string "#=(eval (.exists (java.io.File. \"/tmp\")))"))

7:02 clojurebot: java.lang.RuntimeException: java.security.AccessControlException: access denied (java.io.FilePermission /tmp read)

7:02 Licenser_: ah good :)

7:02 hmm is /tmp is a directory, exists works on that?

7:03 Chousuke: (java.io.File. "foobarsdjfksdj")

7:03 ,(java.io.File. "foobarsdjfksdj")

7:03 clojurebot: #<File foobarsdjfksdj>

7:03 Licenser_: ,(binding [*read-eval* true] (read-string "#=(eval (.exists (java.io.File. \"/etc/profile\")))"))

7:03 clojurebot: java.lang.RuntimeException: java.security.AccessControlException: access denied (java.io.FilePermission /etc/profile read)

7:03 Chousuke: basically, it doesn't matter to File whether the file exists or not

7:03 Licenser_: okay good news are you can't read them :)

7:04 tomoj: are there people like engineyard in the jvm world?

7:04 Licenser_: as in they know how it works or as in they run it on solaris?

7:07 _ato: google appengine I suppose might kind of count

7:07 tomoj: hmm, they have bad restrictions though, no?

7:07 I mean, you don't get as much control

7:07 _ato: yep

7:07 tomoj: and limited choices

7:08 I imagine you point to the git repo of a clojure project and boom

7:08 and many options for data storage or whatever

7:12 _ato: googling java servlets hosting returns a lot of results

7:12 never heard of any of them, so I dunno if they're any good

7:17 Licenser_: oh wrong channel sorry

7:17 argh

7:17 ,(eval '(+ 1 1))

7:17 clojurebot: DENIED

7:17 Licenser_: ah good

7:23 _ato: ,(@(resolve (symbol "eval")) (read-string "(def on-a-roll-tonight true)"))

7:23 clojurebot: #'sandbox/on-a-roll-tonight

7:23 _ato: ,on-a-roll-tonight

7:23 clojurebot: true

7:23 _ato: Licenser_: are you safe on that one?

7:26 Licenser_: _ato: let me test

7:27 java.lang.SecurityException: Code did not pass sandbox guidelines: (#'clojure.core/deref #'clojure.core/resolve #'clojure.core/symbol)

7:27 _ato: nice

7:27 Licenser_: while deref and symbol might want to work

7:27 resolve likely not

7:29 _ato: the approach I took is entirely differnt (at least on the security model, not the code, I got a good bit from clojurebot there). I work on a 'if it is not allowed it is forbidden' base, clojurebot works with 'if it is not forbidden it is allowed'

7:31 _ato: aah right

7:31 * _ato checks out a copy of clj-sandbox

7:32 Licenser_: _ato: it's not entirely secure either, but it is quite OK)

7:33 * talios heads to bed - night all

7:34 _ato: ah it won't even let you use symbol

7:34 hmm tricky

7:35 oh.. but you have read-string

7:35 Licenser_: _ato: you can allow symbol, it will on the next version

7:35 yes just added it, not sure if it is good that I did :P

7:35 but you don't have eval

7:38 _ato: if you find any hole I will gladly fix it

7:40 _ato: found one!

7:40 err wait

7:40 maybe...

7:41 keep crashing my repl

7:41 hehe

7:41 Licenser_: oi, within our outside the sandbox?

7:42 _ato: outside

7:43 I'm just trying to do the same read-eval trick but with push-thread-bindings

7:43 Licenser_: ah okay, protectig you against yourself will not be implemented in 0.* of clj-sandbox

7:43 ah sneaky I think I nknow where you're going

7:44 but you can't access *read-eval*

7:44 _ato: yeah, just realised that

7:44 hmm

7:45 actually... (read-string "#'*read-eval*") works

7:45 Licenser_: yuck

7:45 that is sneaky

7:46 hmm hmm I wonder how to handle this

7:47 _ato: can you give me the exact test case?

7:47 _ato: oh

7:47 no it doesn't

7:47 Licenser_: of cause I could forbid read-string

7:47 _ato: cause its not evaled

7:47 Licenser_: great!

7:47 _ato: hehe

7:48 tomoj: you don't forbid read-string, but the (read-string "#=(eval ...)") trick above won't work in your sandbox?

7:48 Licenser_: tomoj: the sandbox runs with *read-eval* false.

7:49 at least my newest version :P

7:49 the one I just pushed

7:50 tomoj: oh, and you can't use binding, yeah, I get it

7:50 Licenser_: tomoj: you can

7:50 just can't bind *read-eval*

7:51 or any var that is prebound and not explictly allpowed

7:56 tomoj: oh, nice

7:57 at what point does clojure block symbols?

7:57 or does it just refuse to look inside strings?

7:57 Licenser_: tomoj: if you want to see examples, there are by now 4 projects I know of using clj-sandbox all are linked at the github page

7:57 tomoj: after reading the data structure is examined for possible 'bad functions'

7:58 or actually examined to make sure everything in there is allowed

7:58 tomoj: this is in clojurebot?

7:58 Licenser_: tomoj: no

7:58 tomoj: ah, in clj-sandbox?

7:59 clojurebot has a problem clj-sandbox doesn't right?

7:59 Licenser_: clojurebot uses it's own sandbox, I just got many ideas from clojure bot :)

7:59 tomoj: I see

7:59 Licenser_: tomoj: they use different approachs

7:59 tomoj: I'm just wondering why clojurebot allows you to call eval when it's in a #= in a string

7:59 right

7:59 I think I understand yours

7:59 and it sounds great

7:59 laynor: hi, I just got clojure box working. I noticed that the repl hangs if I (read-line). Is there any solution for this?

7:59 Licenser_: clojurebot blacklists a few functions clj-sandbox (at least by default) whitlists a few functions

8:00 laynor: why would you want to read line on the repl?

8:00 laynor: Licenser_: because I'm new to Clojure, just learning the basics

8:00 Licenser_: tomoj: it does not allow it but as seen above you can rebind *read-eval* and then it allows it

8:00 ah :)

8:01 * _ato is running out of ideas

8:01 _ato: nice job on clj-sandbox ;-)

8:01 Licenser_: laynor: well I think the problem is that read-linbe reads from STDIN and you can't access that from the repl

8:01 _ato: thanks a lot!

8:01 Raynes did a lot of good testing killing a few evil bugs

8:02 laynor: Licenser_: what puzzles me is that it works flawlessly with slime/sbcl

8:02 Licenser_: laynor: read-lines or repl?

8:02 laynor: Licenser_: yeah

8:03 Licenser_: it is a or question, 'yeah' isn't a valid answer there :P

8:03 laynor: oh, i just read "on" not "or"

8:03 Licenser_: ^^

8:03 laynor: lol

8:03 Licenser_: it's like 'do you want coke or fanta?', "YEs please."

8:04 laynor: so, I can (read-line) on the repl with slime/sbcl, I can't with slime/clojure, ergo must be a problem with swank-closure

8:04 Licenser_: laynor: sbcl is what?

8:04 some comon lisp thingy?

8:04 laynor: Steel Bank Common Lisp

8:04 yeah

8:04 Licenser_: I gues the reson is that the clojure repl is forwarded over TCP or at leaqst some other way

8:05 repl != repl ;)

8:07 laynor: I'd say it's the same for sbcl

8:07 uhmuhm

8:10 Licenser_: also, if I run (read-line) in the *inferior-lisp* buffer, it works. Problems arise only on the repl.

8:10 Licenser_: ah sneakyt

8:10 perhaps you can write a bug report, then again I'm not sure if slime is maintained :(

8:10 laynor: uhm, but it's not slime, it's swank-clojure i'd say, as the repl works flawlessly with sbcl

8:11 Licenser_: then that :P)_

8:11 sorry I never can keep them apart

8:11 for me it is one bug fluffy emacs thingy

8:11 *big

8:11 laynor: I see :) So you basically use emacs for the sake of clojure?

8:12 Licenser_: laynor: yes

8:12 never used it before I started with clojure

8:12 * Licenser_ was a vim person :P

8:12 laynor: oh, I am a vi person

8:12 Licenser_: still am I guess

8:12 laynor: I use viper/vimpulse on emacs

8:12 Licenser_: hmm no clue what that is

8:13 laynor: so I get slime and swank and vim bindings

8:13 Licenser_: in the end I just want it to work :( sadly didn't found any editor that really does that

8:13 laynor: Licenser_: vim emulation for emacs

8:13 Licenser_: ah

8:13 laynor: you should try it XD

8:14 Chousuke: I gave up viper because it didn't work so well with paredit

8:14 Licenser_: I fear I might get even more confused :(

8:14 I never understood this paredit thing, never got it to work, I guess I'm too stupid for emacs :P

8:14 Chousuke: if I used any of viper's deletion commands it would mess up the structure and throw off paredit:/

8:14 laynor: uhm, I don't really use paraedit, what can it do for me?

8:15 Chousuke: it's basically structural editing for lisp code

8:15 laynor: Chousuke: you can di( and da( on vimpulse btw

8:15 Licenser_: I think it is for editing sexps

8:15 _ato: Licenser_: (my-sandbox "(.alterRoot #'inc (fn [str] dec) (list))")

8:15 doesn't get you eval, but lets you mess up builtin functions

8:15 that might not count as breaking it thoug

8:15 Chousuke: works with non-lisp languages too.

8:15 Licenser_: _ato: of cause it does

8:16 can you give me the code to create my-sandbox?

8:16 Chousuke: (though obviously not as well)

8:16 _ato: it's just the one from your example: (def my-sandbox (stringify-sandbox (new-sandbox)))

8:16 Licenser_: okay

8:16 _ato: I just ask because I've had odd things already where people did strange things :P

8:16 laynor: uhm, I should give it a try and setup some bindings for viper ^^

8:18 Licenser_: _ato: okay this gets tricky ^^

8:19 I should just forbid . :P

8:20 _ato: got eval

8:20 but using .

8:21 Licenser_: *nods*

8:21 user=> (fn-seq '(.alterRoot #'inc (fn [str] dec) (list)))

8:21 (. #'clojure.core/inc fn* #'clojure.core/str #'clojure.core/dec #'clojure.core/list)

8:21 That is how I filter stuff

8:21 _ato: ((.get (.findInternedVar (:ns (meta #'inc)) (read-string "eval"))) '(+ 1 1))

8:21 Licenser_: since it can't resolve alterRoot it ignores it

8:21 this is very trucky

8:22 hrm

8:22 but cutting off . make things harder :(

8:22 _ato: :(

8:22 Licenser_: hmm tricky thing

8:22 java interop is evil

8:23 _ato: sure is, clojure objects have too much stuff public ;-)

8:23 Licenser_: *nods*

8:23 I think the only way to work around this is either forbidding . or making very strage things

8:24 if you want people to use certainb java interop functions you could publish wrappers to the sandbox

8:25 _ato: yeah

8:25 probably the best way to do it

8:26 'spose that works for clojurebot too

8:26 ,((.get (.findInternedVar (:ns (meta #'inc)) (read-string "eval"))) '(+ 1 1))

8:26 clojurebot: 2

8:26 Licenser_: most likely

8:26 hmm I wonder if I could override .

8:27 no can't bind it

8:27 _ato: but you could substitute it

8:27 Licenser_: *nods*

8:27 that might be a way

8:27 _ato: walk the entered forms and replace all . with something else

8:27 Licenser_: but the first fix will be remove it\

8:28 SynrG: win 7

8:28 Licenser_: _ato: yea but read would still le- no wait it won't

8:28 since you can't eval

8:28 _ato: yep

8:28 Licenser_: hmm yea that might be a good way

8:28 then agai I'd have to either white or blacklist stuff

8:28 or ... go a diferent way and allow to call stuff ON certan types

8:29 hmm that is a idea

8:29 I'll see into this

8:29 but for now I head home

8:29 see you all later!

8:30 _ato: see you

8:30 laynor: bye :)

8:31 uhm, (.. System out (println "asdf")) doesn't print the output on the repl, only on the *inferior-lisp* buffer

8:44 raek: laynor: yes. the repl is connected to the swank server (*inferior-lisp*) with a socket

8:45 and technically, you could have multiple repls connected to the same swank server

8:45 slime seems to rebind clojure *out* to it's own repl buffer

8:46 so (println "hello world") will print in the repl

8:46 tomoj: hmm, that's interesting

8:46 is there support for multiple repls for one swank in other lisps?

8:46 raek: but since *out* is a thread-local binding, other threads will still print in *inferior-lisp*

8:47 tomoj: yeah

8:47 that is awesome

8:47 raek: I have no experience with doing these sort of things in other lisps

8:48 tomoj: oh well

8:48 what would be interesting is a way to provide a macro that causes all new threads spawned from something entered at the repl to use the repl *out* binding

8:49 raek: I think that's what bound-fn is for

8:49 IIRC

8:49 ,(doc bound-fn)

8:49 clojurebot: Excuse me?

8:50 raek: "Returns a function defined by the given fntail, which will install the

8:50 same bindings in effect as in the thread at the time bound-fn was called.

8:50 This may be used to define a helper function which runs on a different

8:50 thread, but needs the same bindings in place."

8:52 tomoj: aha

8:52 raek: ok, this is not a perfect match for the problem, but it is related, anyway

8:52 tomoj: very interesting

8:52 where is that located?

8:52 raek: clojure.core

8:52 http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/bound-fn

8:52 tomoj: never noticed it before

8:52 chouser: bound-fn is fairly new. 1.1 I think.

8:53 raek: haven't used it myself, yet

8:53 tomoj: bound-fn* is the real function

8:55 can you optionally but unobtrusively add bound-fn's everywhere they need to go to make agents etc work with *out*?

8:57 raek: bound-fn would need to be added to all functions passed to the agent

8:58 as the agent doesn't have to run the functions in the same thread

9:01 zmila: your are a bit stuck in clojure if looking at http://poehali.net/attach/meri_96_4.jpg you misread the name

9:02 raek: hehe, true

9:02 :)

9:16 tomoj: raek: right, hmm

9:16 Licenser: aloa

9:16 * Licenser is back!

9:17 tomoj: it might be possible by thread-locally rebinding the agent fns, no?

9:17 with an with-out-repl macro or something

9:32 cburroughs: My recollection is that contrib 1.1.0 made it into maven central. But empirical evidence shows that this is clearly not the case. Does anyone know what the status of that is? The last message I could find on clojure-dev was by Stuart Sierra on Jan 4

9:35 dnolen: cgrand: ping

9:35 hugod: cburroughs: I'm not sure about central, but you might want http://build.clojure.org/releases/

9:36 cburroughs: hugod, yeah thanks. I'll probably just add that to the proxy list if our internal repo.

9:36 cgrand: dnolen: pong

9:37 cemerick: cburroughs: yeah, that's what we do *shrug*

9:37 although contrib really should be in central, too

9:37 dnolen: cgrand: I've been looking at moustache :) so how do you do a redirect with moustache? Also app generates functions right? So it's easy to nest them.

9:41 cgrand: dnolen: funny you ask since I'm planning to dust off moustache :-) yes, apps being function compose, you can "mount" an app

9:43 dnolen: cgrand: I like the destructuring aspect of route definition in moustache, very idiomatic.

9:43 cgrand: dnolen: there's no support for redirects, you have to send your body map with the correct :status code

9:44 dnolen: cgrand: I see.

9:45 cgrand: I should add a middleware to handle relative redirections -- must check if compojure has one

9:45 dnolen: cgrand: any specific plans you have for moustache?

9:49 cburroughs: Now if I swank-clojure was just in a nice repo.

9:49 cgrand: dnolen: nothing specific except I'd like to dust it off since ring 0.2 makes moustache more useful

9:50 dnolen: lockstep selectors are in http://gist.github.com/335527

9:51 dnolen: cgrand: nice :)

9:52 cgrand: and they are fast :-)

9:52 dnolen: :D

9:52 tomoj: hmm, how did we do that before?

9:53 cgrand: dnolen: are you planning a moustache tutorial? ;-)

9:55 dnolen: cgrand: heh, why not? Honestly it was more about getting fed up with my dog slow WordPress setup. I'm thinking about moving stuff over to Clojure. Ring+Moustache+Enlive looks like a good combination.

9:57 tomoj: moustache looks interesting

9:57 but is it dead?

9:57 raek: what is this moustache? a ring-based web framework similar to compojure?

9:57 tomoj: looks even smaller than compojure

9:57 perhaps something approaching compojure's features could be built out of it?

9:58 hugod: cburroughs: swank-clojure is in http://clojars.org/repo

9:58 tomoj: does moustache benefit from the destructuring improvements?

9:58 clojurebot: destructuring is http://clojure.org/special_forms#let

9:58 dnolen: tomoj: compojure 0.4 will be pretty small. since Ring 0.2 implements many of features now.

9:58 many of its

9:58 tomoj: cool

9:58 but I like the looks of moustache

9:58 clojure's destructuring for routes is genious

9:58 raek: clojurebot: moustache?

9:58 clojurebot: No entiendo

9:58 tomoj: pure unadulterated genius

9:58 * raek googles

9:58 tomoj: http://github.com/cgrand/moustache

9:59 see also http://gist.github.com/109955 (linked there)

9:59 is anyone around who understands the change to destructuring?

9:59 cburroughs: hugod I know, but clojars is very un-conventional as a maven repo.

10:00 chouser: tomoj: I think so -- what do you want to know?

10:01 raek: ah, moustache looks really neat!

10:01 tomoj: chouser: umm.. can you just show something new that works?

10:01 I can't tell from the code what the heck it does

10:02 I'm wondering particularly if this opens up new routing possibilities for moustache

10:02 but also just curious

10:02 willing to blog about it if you get me started :)

10:02 (or has someone already?)

10:02 chouser: ,(let [f (fn [a b & {:keys [c d]}] [:my-args a b c d])] (f 1 2 :d 5))

10:02 clojurebot: [:my-args 1 2 nil nil]

10:02 tomoj: maybe I should search the logs

10:04 chouser: ,(let [{a :a, b :b, c :c} (seq [:c 1 :b 2])] [a b c])

10:04 clojurebot: [nil nil nil]

10:04 chouser: heh. well, try those on a more recent clojure to see how they're useful. :-)

10:04 tomoj: oh, thanks a lot

10:05 ok, very interesting

10:06 the :my-args tag was helpful, good way to illustrate things

10:07 so, hmm

10:07 is there ever a case like that in routing?

10:07 something like a PHP style /var1/value/var2/othervalue maybe

10:07 but I'm not a big fan

10:08 noidi: is there a function that wraps its argument in a seq unless its one already?

10:08 i.e. (ensure-seq 1) => (1), (ensure-seq [1 2 3]) => [1 2 3]

10:08 chouser: a vector is not a seq

10:09 noidi: well, a coll then :)

10:09 chouser: but, probably not. rather few things in clojure core accept a collection or not and then treat them differently

10:10 collections are values too, so such usage would tend to be useful in more specific, rather than general, circumstances.

10:11 noidi: yeah, you're probably right

10:12 I'm writing swing code and would like to be able to say something like

10:12 (doto-named! widgets :foo enable, [:bar :baz] disable)

10:12 where widgets is a map

10:13 tomoj: that makes sense

10:13 noidi: and I was thinking that if there was something like ensure-coll, then I could deal with both the single names and colls of names with a doseq

10:13 tomoj: write your own, I suppose

10:13 would coll? be best to use?

10:14 chouser: actually, might be one of the few good uses of 'sequential?'

10:14 tomoj: coll? accepts maps as well

10:14 chouser: ,(sequential? {:a :b})

10:14 clojurebot: false

10:14 chouser: ,(sequential? [:a :b])

10:14 clojurebot: true

10:15 wooby: ,(sequential? #{:a :b})

10:15 clojurebot: false

10:15 chouser: ,(sequential? (java.util.ArrayList. [:a :b]))

10:15 clojurebot: false

10:15 chouser: eh. so maybe not. :-)

10:15 tomoj: noidi: are you going to release a swing clojure wrapper?

10:16 cemerick: noidi: this is what we use in a similar use-case, but chouser's right to note that it won't work with java collections: http://paste.lisp.org/display/97020

10:16 noidi: tomoj, no, just getting rid of the boilerplate in my code :)

10:16 bsteuber: yeah, a swing wrapper would rock!

10:16 tomoj: ah

10:17 I kind of want a rewrite of ruby's shoes in clojure

10:17 noidi: and doto-named! will not be swing-specific either, since it could be used to execute any side-effecty functions on any things in maps

10:17 man, my abstractions became _so_ much more effecient when I bit the bullet and got rid of all encapsulation and started thinking in seqs and colls

10:18 cemerick, thanks. I already have your let-map in my util.clj, btw. ;)

10:18 tomoj: how do I even build moustache?

10:18 cemerick: heh, good ol' let-map :-)

10:19 chouser: aren't they more often grown than built?

10:19 cemerick: that was a little crazy

10:19 chouser: sorry, nm.

10:20 cemerick: chouser: I wasn't referring your pun :-)

10:20 dnolen: tomoj: build it? just include it in your own code as you do with any library.

10:20 tomoj: huh

10:20 joke?

10:23 fogus: tomoj: Chapter 9 of Joy of Clojure will be a good start for that Shoes port. ;-)

10:24 tomoj: cool

10:24 dnolen: http://gist.github.com/347880, cgrand

10:24 's moustache example updated for Ring 0.2

10:24 tomoj: I personally want to be able to tinker with math stuff

10:24 chouser: cemerick: heh, yeah I know.

10:24 tomoj: but if people could use interaction, sound, graphics, it would be awesome

10:24 cp2: oh cool

10:24 tomoj: and I think java is capable

10:24 Chousuke: That reminds me... when do we get more chapters? :P

10:25 fogus: Chousuke: I wish I knew... they have been submitted are in review and should have been posted last week... but it seems chouser and I are the last to know the specifics. :-(

10:25 Chousuke: :/

10:26 tomoj: that's too bad, what is it they have to do?

10:28 fogus: tomoj: Some highly involved process of posting them to the site. :-p

10:29 tomoj: lame

10:29 automate that shit

10:29 noidi: I'm glad to see that you have section about testing in "12. Clojure Will Change the Way You Program"

10:30 fogus: if it were in our hands you'd have updates every time we pushed to git

10:31 noidi: now that I've dropped the shackles of encapsulation, I've noticed that I don't feel the need to write unit tests anymore, wheras in Python I felt that TDD really helped me

10:31 chouser: for more instantaneous typo feedback. :-)

10:32 tomoj: got rid of all encapsulation?

10:32 as in, just functions/values/macros, no classes/big deftypes/whatever?

10:33 noidi: yeah

10:33 tomoj, I used to write almost OO code in Clojure, but it seemed that no one else did that and got along just fine, so I took the plunge and decided to give it a try

10:34 tomoj: what clojure features did you use to emulate OO?

10:34 noidi: I'm not quite sure why, but for some reason Clojure code turns out just find with plain-old-data-objects

10:34 tomoj: :)

10:34 noidi: tomoj, namespaces for "classes", treating objects as black boxes only accessed via the namespaces' functions

10:35 tomoj: I see, and the objects are what?

10:35 I mean, internally

10:35 noidi: whatever happened to be a natural fit, but mostly maps

10:36 tomoj: I see

10:37 noidi: I thought that it was pretty nice actually, even better than writing OO code in a language with built-in support

10:39 but don't worry, I got over that phase now. now my code looks much more like "normal" Clojure :)

10:46 raek: noidi: did this OO-like code invovle changes in state or was it persistent like clojure maps?

10:47 btw, when is it ideomatic to use "next"?

10:48 like this? (if (next some-lazy-seq) (there-is-a-rest) (no-rest))

10:49 noidi: raek, I tried to avoid side-effects and returned new "objects" from the "methods"

10:50 Chousuke: raek: that would be sensible

10:50 dnolen: cgrand: is the following valid? http://gist.github.com/347905. Will those fns get the request map?

10:55 slyphon: is the difference between binding and with-bindings that one is global and one is thread-local?

10:57 wooby: anyone know a nice way to do something like (map :title (map :attr ...) without repetition?

10:58 drewr: wooby: (map (comp :title :attr) ...)

10:59 raek: noidi: to me, that sounds like functional code with a lot of abstraction

10:59 wooby: you are awesome, thanks drewr

11:00 mattrepl: wooby: alternatively, (map #(-> % :attr :title) ...)

11:02 wooby: ah yes, thanks mattrepl

11:02 mattrepl: and there's also get-in

11:02 slyphon: heh

11:02 we really need a get-over-here!

11:04 drewr: and get-back which operates on jojo collections

11:04 slyphon: drewr: :D

11:04 winnar!

11:10 cgrand: dnolen: all your *-post functions should get the request map as their only arg

11:11 dnolen: cgrand: yeah just got it working :) moustache is _cool_.

11:12 cgrand: heh, ring has redirect

11:13 cgrand: dnolen: you know that you merge your two ["new"] routes to dispatch to {:get new-post :post save-post}

11:13 dnolen: absolute redirect I guess

11:14 dnolen: cgrand: yeah

11:14 cgrand: btw, what did you update in the walkthrough? Only the ns form and the definition of server?

11:14 dnolen: cgrand: yes

11:14 ring 0.2 support defining a server that doesn't join with the main thread.

11:15 slyphon: hey, what's the difference between with-bindings and binding? i looked at the code, but the subtlety escaped me

11:15 tomoj: dnolen: how?

11:15 I can't figure it out

11:15 dnolen: tomoj: http://gist.github.com/347880

11:15 line 13

11:15 tomoj: oh, ok :join false

11:16 how do you start it up?

11:16 (.start server) ?

11:16 dnolen: run-jetty starts the server and returns it

11:16 you can stop it with (.stop server)

11:17 tomoj: great

11:17 and this picks up changes to my-app?

11:17 dnolen: tomoj: yeah

11:18 tomoj: maybe want a defonce for server?

11:21 dnolen: tomoj: yeah that's what I did.

11:48 technomancy: hugod, LauJensen: hey guys

11:48 sorry; been offline for a while

11:48 LauJensen: technomancy: Hey :)

11:48 hugod: technomancy: good morning

11:48 technomancy: I think swank-break is ready to merge

11:48 tomoj: awesome

11:48 LauJensen: Great !

11:49 hugod: :-)

11:49 technomancy: earlier when I tried it I was seeing some odd debug-ish (slime-rex) output in the repl buffer, but that was a while ago and I haven't been able to repro since

11:49 lpetit: hi all

11:49 LauJensen: Hi Laurent

11:49 lpetit: a question to emacs users

11:50 is there a paredit command which allows to wrap with parens a text selection ?

11:50 technomancy: hugod: and it looks like you fixed inspector hyperlinks as well; that wasn't working a while ago.

11:50 lpetit: if there's an active selection, pressing ( will do that

11:50 same with [ and { iirc

11:50 lpetit: ok

11:50 will the selection be lost at the end of the command ?

11:51 hugod: technomancy: yes - inspector should work fully now

11:51 noidi: lpetit, M-( wraps the sexps on which the point is on

11:51 technomancy: lpetit: no, it's preserved

11:51 lpetit: but you don't have to emulate every single detail. =)

11:54 hugod: technomancy: how about the other branches? any concerns?

11:54 technomancy: hugod: can you tell me a bit more about the other branches you mentioned?

11:54 jinx?

11:55 I haven't gotten a chance to look at them yet

11:55 hugod: autodoc fixes autodoc for slime head

11:55 compile-file fixes compile-for-emacs in slime head

11:55 technomancy: oh, I was thinking that was related to Tom F's autodoc project, heh

11:56 hugod: exception-location does a better job of locating source code from stack trace and compile errors

11:56 hyperdoc links to clojure api docs

11:56 technomancy: awesome

11:56 tomoj: hmm

11:57 lpetit: nodi, technomancy: ok, from reading the docs, I thought it was just wrapping the next form

11:57 tomoj: (app ["hi" & {:strs ["name" "age"]}] {:get (format "Hello %s, age %s." name age)})

11:57 that look right?

11:57 doesn't seem to be working

11:57 lpetit: technomancy: /every single detail/ : agreed, I intend to improve it where it sucks :-p

11:57 technomancy: hehe

11:57 good

11:57 chouser: tomoj: try [name age] instead of string literals there

11:58 tomoj: oh, I see

11:58 lpetit: technomancy: does paredit have structural selection of text ? Or maybe it's provided outside paredit ?

11:58 s/have/provide/

11:59 tomoj: I think the question is, what do you want to do with the selection?

11:59 technomancy: hugod: btw, you don't necessarily need to run these branches by me; review by anyone who uses and is somewhat familiar with swank is enough to get them merged to master.

11:59 tomoj: chouser: hmm, more errors

12:00 lpetit: tomoj: answering to me ? (too many concurrent discussions, I'm lost :-) )

12:00 tomoj: lpetit: nope

12:00 lpetit: oh, yep

12:00 I mean, do you want to copy it?

12:00 hugod: technomancy: ok, I just discovered there's a ml for swank-clojure - I'll try and make use of it ...

12:01 lpetit: tomoj: why answer my question with a question ? :-) I may want to wrap it with (, copy it, cut it, send it to the REPL, there are a lot of answers !

12:01 tomoj: indeed

12:01 but what I am saying is that you might not need some feature

12:01 lpetit: tomoj: so again, my question :-)

12:01 technomancy: hugod: asking in here would probably get you some volunteers too

12:01 tomoj: three of those use cases don't need "selection" as such

12:01 wrap with ( - put the point before the sexp and hit M-(

12:02 lpetit: tomoj: agree on the general case. Concerning the particular case, I'm pretty sure I need it (though you can try prove I'm wrong :-) )

12:02 tomoj: cut - put the point before the sexp and hit C-M-k

12:02 send to repl - put the point after the sexp and hit ... some key

12:02 (depending on how exactly you want to send it to the repl)

12:03 lpetit: I don't want to put the point before the sexp, I want to discover what I want to wrap while I'm expanding to the left, to the right, or with the parent sexpr

12:03 tomoj: I'm not sure how that makes sense

12:03 like, a couple keys you can press over and over to expand the selection iteratively?

12:03 lpetit: tomoj: First: I don't have to remember a new command for wrap with ( (I will then just hit ( ), etc.

12:04 tomoj: yes

12:04 tomoj: ok

12:04 I don't think there is anything for that

12:04 but the wrapping keys aren't that hard to remember :) they're M plus whatever you want to wrap with

12:04 if you write something like that I'm sure people would be interested

12:04 lpetit: tomoj: imagine you want to select 3 siblings (so not just a single form) from one point to another

12:05 tomoj: agreed, the particular examples were not that bad

12:05 s/from/and move them from/

12:05 tomoj: C-SPC C-u 3 M-f

12:05 then C-w to cut, C-y somewhere else to yank

12:05 s/cut/kill/

12:06 lpetit: tomoj: wow, we don't have this in Eclipse. And I'm not sure I miss it either ;-)

12:06 tomoj: of course you can just hit M-f multiple times instead :)

12:06 hehe

12:06 well, maybe you have to be a bit insane

12:07 lpetit: tomoj: I'm dead sure I'm insane, or I won't be on the clojure bandwagon :-)

12:07 s/won't/would'nt/

12:07 tomoj: I meant, insane to like emacs

12:07 lpetit: tomoj: oh :-)

12:08 tomoj: I'm also sure I'm insane :)

12:08 lpetit: tomoj: no, I'm quite sure it's a great environment for power users.

12:08 tomoj: yep

12:08 a big investment I think, though

12:09 lpetit: woops, was deconnected for a minute or two. Missed smth ?

12:09 cgrand: tomoj: I don't think you can make it work without modifying moustache

12:09 tomoj: that's what I had guessed

12:10 it seems to be using clojure.core/destructure

12:10 but taking chouser suggestion, I get "java.lang.String cannot be cast to clojure.lang.IFn"

12:13 ,(let [[foo & {:strs [name age]}] ["hi" "name" "tom" "age" "22"]] (format "Hello %s, age %s." name age))

12:13 clojurebot: "Hello null, age null."

12:13 tomoj: well, yeah

12:14 but, moustache must be doing something to allow literals in there

12:15 oh, whoops

12:16 cgrand: tomoj: try (app ["hi" & [& {:strs ["name" "age"]}]] {:get (format "Hello %s, age %s." name age)}) with url /hi/name/Lucy/age/23

12:16 not pretty but it should work

12:17 tomoj: still getting an error

12:18 chouser: unless you're doing something really unusual, the vector after :strs should contain symbols, not string literals

12:18 tomoj: yes, made that change

12:18 still no joy

12:19 (app ["hi" & rest] {:get (str rest)}) doesn't even work

12:19 cgrand: chouser: true, I blindly copy-pasted

12:20 tomoj: what the heck, now ["hi" name] doesn't even work

12:22 uhh

12:22 I am boggled

12:25 https://gist.github.com/c139721c1fdcda8ee34f

12:26 the exception https://gist.github.com/037ed61415f0f7ce464f

12:28 I think I understand

12:29 (app ["hi" & {:strs [name age]}] {:get ["" (format "Hello %s, age %s." name age)]})

12:30 need a literal string there or the string will be called as a function

12:30 chouser: exception handling is so messy.

12:42 tomoj: cgrand: thanks for leinifying

12:46 cgrand: tomoj: yw but I haven't been able to push it to clojars yet (it seems down)

12:46 tomoj: no problem

12:46 I had already leinified myself anyway

12:54 Crowb4r: When is 1.2 being released?

12:54 chouser: when it stops changing

12:55 or myabe that's the other way around

13:05 * joshua-choi is glad that fns can now have metadata

13:10 * raek loves <C-x (> do stuff <C-x )> <C-x e>

13:12 raek: how would you name functions for serializing/unserializing or interpreting/emitting data structures?

13:13 as a part of a web server, I have functions to serialize and unserialize to various data formats

13:13 I think "render" is a term that is used in some web frameworks, but what would the inverse be called?

13:14 tomoj: hydrate?

13:14 I dunno

13:16 raek: analyze/synthesize is a nice combo

13:16 but maybe too general

13:16 for (un-)serialization to strings I consider parse/format

13:17 tomoj: sounds goo

13:17 good

13:18 dnolen: cgrand: are you going to push moustache to clojars?

13:22 technomancy: hugod: merged/pushed break to swank master

13:23 thanks a bunch!

13:23 cgrand: dnolen: yeah as soon as clojars is back -- wait it is

13:23 technomancy: I'll try to take a look at the other branches later this week.

13:23 hugod: technomancy: yeah!

13:24 technomancy: of course if someone else reviews them first you're welcome to merge them without me

13:24 just be sure if you're using slime master also to check against elpa slime

13:25 hugod: I'll try and find time to do that - I'd rather find someone with elpa slime installed than checking elpa myself

13:26 dnolen: technomancy: so does that mean swank-clojure will work with slime master again? :)

13:27 technomancy: dnolen: maybe so... if you help hugo review his branches you can make it happen sooner. =)

13:27 hugod: dnolen: that requires the compile-file (and autodoc) branch

13:27 technomancy: tbh I am not sure I know about all the details of the divergence in master that's causing breakage

13:27 dnolen: hugod: in your fork right? or techonmancy's ?

13:28 hugod: autodoc is only required if you are using slime-autodoc

13:28 in technomancy's

13:28 I should delete my fork

13:28 dnolen: cgrand: cool. it also looks like ring 0.2 just got released.

13:30 cgrand: dnolen: well it seems clojars still has problems so be patient

13:30 dnolen: cgrand: oh gotcha.

13:37 hugod: so how do you test your stuff? do you create an uberjar?

13:39 hugod: dnolen: I do a lein install locally. Maybe it would be easier if we created versions of swank-clojure in clojars for each of the branches?

13:40 dnolen: hugod: oh I see, never used lein install before. So that jars up the project and put's it into .m2 ? then you can add it as a dependency ?

13:43 hugod: dnolen: indeed - though I normally edit project.clj to give it a different name 1.2-xxx-SNAPSHOT

13:45 lein jar should work too - and then manually copy the jar into your project

13:46 dnolen: hugod: cool, I'll definitely give the compile-files branch a spin later today.

13:47 tomoj: if you have lein jar might as well use lein install, eh?

13:48 hugod: depends whether you want the modified jar in your local .m2, where it will be picked up by all your projects

13:48 tomoj: oh, good point

13:48 guess you could tag your branch name in the version, but meh

13:49 hugod: I do locally, but commiting that would make merging the branch more painful

13:51 tomoj: ah yeah

13:54 hmm, gotta install jruby to get polyglot-maven working?

14:00 stuartsierra: tomoj: probably a development thing

14:05 tomoj: stuartsierra: as in, this problem should go away?

14:05 I can't get pmaven-cli to build because pmaven-jruby fails

14:05 pmaven-scala might as well, dunno

14:08 stuartsierra: tomoj: I dunno, you'd have to ask talios.

14:12 tomoj: ok, thanks

14:18 TakeV: Is there a way to get keyboard input, without using the java libraries?

14:21 The-Kenny: TakeV: (read-line)?

14:21 ,(read-line)

14:21 clojurebot: Execution Timed Out

14:21 The-Kenny: ,(doc read-line)

14:21 clojurebot: "([]); Reads the next line from stream that is the current value of *in* ."

14:22 TakeV: Huh, didn't know about that. Thank you.

14:22 The-Kenny: You're welcome

14:38 Borkdude: hi

14:39 raek: hello

14:40 Borkdude: I have posted a Clojure question on StackOverflow, maybe you guys want to take a look. http://stackoverflow.com/questions/2540237/are-the-square-brackets-in-clojures-defn-defmacro-and-binding-really-a-vector

14:43 dcorbin_work: Is the J in clojure pronounced as a J or an S?

14:43 chouser: I think rhickey has said it's pronounced exactly like "closure"

14:43 lancepantz: thats how i pronounce it

14:43 chouser: I tend to harden it toward a "J" just enough that it sounds different to me, but to nobody else. Kinda useless.

14:44 Raynes: chouser: Likewise.

14:44 TakeV: Huh, I've been pronouncing it "Clo-jer".

14:46 Borkdude: ah I had a conversation with someone from the Java community, I asked him if he ever heard of Clojure

14:46 then he answered: a closure, yes I heared about it

14:46 Raynes: Hehe.

14:46 Borkdude: then I tried to explain him, no, not the programming language concept closure, but the language Clojure

14:47 so now I still dont know what he meant... :)

14:48 fogus: ,(eval (list (list 'fn (vector 'x) (list '* 'x 2)) 100))

14:48 clojurebot: DENIED

14:48 fogus: :(

14:48 LauJensen: I blogged about some high performance Clojure for Fluid Dynamics here: http://www.bestinclass.dk/index.php/2010/03/functional-fluid-dynamics-in-clojure/

14:48 fogus: fogusbot> 200

14:48 TakeV: Neat.

14:49 drewr: LauJensen: is that stuff related to your professional work?

14:49 LauJensen: drewr: Fluid Dynamics? No its for the kids :)

14:50 drewr: just wondering how you have time to write these elaborate (and apparently esoteric) posts

14:50 LauJensen: hehe

14:50 Borkdude: fogus, thanks for explaining the vector question on SO

14:51 hugod: LauJensen: cool - I do fluid dynamics too

14:51 LauJensen: drewr: This was 1) Because Ive always wanted to do some kind of swirly smoke sim, because I didnt know how, and 2) I ran into a former Epic Games engine developer, so I figured I'd grab the opportunity and ask him a few questions

14:52 drewr: LauJensen: fair enough :-)

14:53 cemerick: LauJensen: Stellar stuff. :-)

14:53 LauJensen: cemerick: Thanks :)

14:53 fogus: Borkdude: I hope it helps

14:53 Borkdude: it sure does

14:58 TakeV: So, is clojurebot hooked up to a REPL?

14:59 cemerick: LauJensen: How long should it take for a call to main to return? I'm pegged at 100%, but there's no jframe visible yet.

15:00 hrm, seems like the frame should show up immediately

15:00 LauJensen: cemerick: On my system it shows up straight away

15:00 Oh, if youre on OSX I this setUndecorated and setLocation can trip you up

15:00 Borkdude: ,(+ 1 2)

15:00 clojurebot: 3

15:00 LauJensen: cemerick: Try and remove those please, i it solves it, I'll remove them

15:00 if

15:01 Borkdude: ,(println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))

15:01 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader)

15:01 Borkdude: :)

15:01 Raynes: TakeV: Clojurebot simply evaluates code in a sandbox.

15:01 TakeV: Ah, that makes sense.

15:01 Raynes: TakeV: I do the same thing in my bot using Licenser's clj-sandbox.

15:02 TakeV: Clj-sandbox?

15:02 Raynes: http://github.com/Licenser/clj-sandbox

15:02 It's pretty stable at this point. At least, I've not found anymore bugs. The default whitelist is seriously lacking because I haven't yet had time to go through the API adding safe functions.

15:03 any more*

15:03 cemerick: LauJensen: Yup, that fixed it.

15:03 LauJensen: Thanks !

15:05 TakeV: Neat library.

15:10 Licenser: greetings Raynes

15:10 Raynes: Greetings.

15:11 Licenser: I see you removed the . special form. What happened there? :o

15:28 dakrone: is there a way to get the REPL to allow me to type stuff like "せん" ?

15:29 it shows up as "??" instead

15:29 raek: dakrone: clojure itself should not have any problems with unicode characters

15:29 just make sure the source is in UTF-8

15:30 dakrone: raek: from the REPL though, not a file

15:30 raek: and that your terminal running the repl also is set up for UTF-8

15:30 TakeV: Is there a way to get Ant to make Clojure project?

15:30 dakrone: the terminal is working fine I am assuming since I can type those chars in zsh

15:30 maybe it's jline?

15:31 raek: could be

15:31 coult you try to enter the characters with "java -jar /path/to/clojure.jar"?

15:32 dakrone: ahhh yea, it's jline

15:32 danielfm: TakeV, Clojure uses Ant to build itself, which includes .clj files. Check out the source code

15:32 dakrone: removing it allows me to type it fine

15:32 raek: java sometimes uses the "system default encoding"

15:32 you should be able to set that with some environment variable

15:33 export LANG=en_US.UTF-8

15:33 ...in a sh-like shell (such as bash)

15:33 dakrone: raek: would that fix jline?

15:34 raek: maybe I should try this myself first...

15:34 danielfm: TakeV: http://github.com/richhickey/clojure

15:34 TakeV: Thanks.

15:37 raek: hrm, jline seems to ignore my LANG environment variable

15:37 köttfärssås -> köttfärssÃ¥s :(

15:38 dnolen: raek: dakrone: I've been looking into it but I haven't found any good answers yet. And I think jRuby ran into the same issues.

15:38 dakrone: hmm...I'm wondering what leiningen is doing to it too

15:38 dnolen: lein swank and lein repl both freeze if they receive unicode chars :(

15:39 ska2342: hi. feeling rather stupid right now, but how am I supposed to read 9 chars from a file? (apply (str (take 9 (repeatedly #(.read the-reader))))) ?

15:39 dakrone: if I do java -cp .:clojure.jar clojure.main, I can type "せん" fine, but "lein repl" and I get "??"

15:39 ska2342: uhm, forgot a char: #(char (.read the-reader)) ...

15:40 dakrone: technomancy: is there a way to see leiningen's command for running the repl with 'lein repl'?

15:40 raek: dnolen: that can be fixed

15:40 dnolen: raek: what did you do?

15:40 raek: swank-server has latin1 as the default

15:40 Raynes: dakrone: It's in the lein file itself.

15:40 raek: posting in a sec

15:41 dakrone: Raynes: ahh, looks like leiningen itself is including the jline jar

15:41 I'll file a bug report

15:41 raek: dnolen: http://gist.github.com/348309

15:42 I use this to start a swank server

15:42 and then in .emacs: (custom-set-variables '(slime-net-coding-system (quote utf-8-unix)))

15:44 if you leave out the slime or the swank option (I don't remember which) the repl will hang

15:44 if both are set to latin1 or utf-8, it works

15:45 dnolen: raek: thanks for the pointers will try that out.

15:50 raek: *sigh* sometimes I wish that the English alphabet utilized more füñňý ĉḥäřáçťêrš, so that encoding related issues would be detected alot quicker

15:50 TakeV: I always thought that Q was a pretty funny letter.

15:51 Raynes: Not nearly as hilarious as w

16:05 Borkdude: Raynes: is there also such a clj-sandbox behind a Twitter account already?

16:05 so you can tweet a Clojure sexp and it replies its evaluation?

16:06 Raynes: Borkdude: No idea. Not that I've heard of.

16:09 KirinDave: lein test is broken?

16:10 LauJensen: Wee, Clojure on the frontpage of HackerNews :)

16:10 nuba: cool

16:11 fdaoud: link?

16:11 clojurebot: your link is dead

16:13 Raynes: http://news.ycombinator.com/

16:13 LauJensen: #24 :|

16:13 KirinDave: I dunno what I need to do to get lein test working. it's never worked for me. :(

16:13 eternally bitching: java.lang.IllegalArgumentException: No matching field found: getCommandLine for class org.apache.tools.ant.taskdefs.Java

16:14 fdaoud: silly me, I was looking at http://www.hackernews.com

16:14 Raynes: Lol.

16:14 KirinDave: Wow. Wft is that.

16:14 I dunno where to even begin with that site.

16:14 Borkdude: There's a nice interview with Rich in Linux Journal this month

16:14 fdaoud: yeah that's what i said

16:15 tried .net and .org before asking

16:15 KirinDave: fdaoud: Consider google.

16:16 fdaoud: hey how would you implement the observer pattern in Clojure? or any way of notifying listeners that something happened?

16:16 LauJensen: ,(doc add-watcher)

16:16 clojurebot: "([reference send-type watcher-agent action-fn]); Experimental. Adds a watcher to an agent/atom/var/ref reference. The watcher must be an Agent, and the action a function of the agent's state and one additional arg, the reference. Whenever the reference's state changes, any registered watchers will have their actions sent. send-type must be one of :send or :send-off. The actions will be sent after the reference's state is

16:16 KirinDave: That's good for observables.

16:16 fdaoud: excellent, thanks LauJensen

16:16 KirinDave: LauJensen: The canonical lisp way is "hooks"

16:17 LauJensen: If its' not a data thing.

16:25 kotarak: ,(doc add-watch)

16:25 clojurebot: "([reference key fn]); Experimental. Adds a watch function to an agent/atom/var/ref reference. The watch fn must be a fn of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference's state might have been changed, any registered watches will have their functions called. The watch fn will be called synchronously, on the agent's thread if an agent, before any pending sends if agent or ref. Note that

16:26 glogic: kotarak: where does the doc come from

16:26 kotarak: doc string?

16:27 kotarak: yes

16:27 glogic: kotarak: so doc is apropos

16:27 tha'ts quite the doc string then

16:27 kotarak: doc is doc

16:29 glogic: clojurebot should probably send long docstring via privmsg imho

16:29 Raynes: glogic: Bother hiredman about it.

16:30 I doubt he would want to do that though.

16:30 glogic: Raynes: well

16:30 Raynes: that doc string

16:30 Raynes: Being able to pull up a docstring for somebody would be useful.

16:30 glogic: Raynes: is clearly too long it's cut off

16:30 Raynes: ref. Note that

16:30 Raynes: not contextually useful

16:31 tha'ts all i was saying

16:31 Raynes: It's pretty useful. :\

16:31 glogic: righ tup until it cust the rest off

16:31 Raynes: Or, you could just direct output to the person you have in mind.

16:32 glogic: that would be ideal

16:32 if tha'ts possible already just ignore the suggestion then

16:32 alexyk: is there a version of nth with swapped parameters?

16:32 glogic: ,(doc nth)

16:32 clojurebot: "([coll index] [coll index not-found]); Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences."

16:33 alexyk: and?

16:33 glogic: oh no idea i just wanted to look something up

16:33 mostly because i don't know what nth looks like

16:33 alexyk: ok this one time

16:33 :)

16:34 glogic: what do you mean by swapped parameters

16:34 dakrone: (defn nth2 [index coll] (nth coll index)) ?

16:34 alexyk: in FP it's typical to curry, so if you want a partial with a fixed index instead of collection, you need swapped-nth n coll

16:35 dakrone: yeah, I can do it; was wondering why nth is swapped w.r.t. say take, and maybe there's a swap adaptor already or something in stdlib

16:35 glogic: alexyk: least surprise maybe

16:35 alexyk: that's my initial guess

16:35 alexyk: to me it's most surprise, after take/drop

16:35 glogic: i bet

16:36 dakrone: alexyk: or (->> 1 (nth [1 2 3]))

16:36 glogic: ,(doc ->>)

16:36 clojurebot: "([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."

16:36 dakrone: which is *kinda* like what you want I think

16:36 ,(->> 1 (nth [1 2 3]))

16:36 clojurebot: 2

16:36 alexyk: dakrone: indeed

16:36 glogic: ok wow

16:37 Raynes: ,(nth 1 [1 2 3])

16:37 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number

16:37 Raynes: ,(nth [1 2 3] 1)

16:37 clojurebot: 2

16:38 alexyk: let's all buy qlogic and Raynes a repl shall we

16:38 Raynes: Why would you use ->> for such a simple form?

16:38 * alexyk kidding

16:38 timmcd: Hello!

16:38 dakrone: just to be able to have the index before the collection

16:39 timmcd: I was wondering if there was a way to import all classes from a group? Ie: (import '(java.net *) '(java.io *))

16:39 or the like?

16:39 Raynes: Nope.

16:40 timmcd: :( Have to by hand import all the classes? K

16:41 TakeV: Huh.

16:42 ,(nth {:x 5 :y 7 :z 12} 1)

16:42 clojurebot: java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap

16:42 TakeV: Aw.

16:42 glogic: splendid exception handling though

16:42 pretty

16:43 ,(nth (1 2 3 4))

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

16:43 glogic: aw

16:43 ,(nth (1 2 3 4) 1)

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

16:43 alexyk: when working with agents for N threads speedup, does it make sense to have N global agents and send them work, or create agents in defn's locally?

16:43 glogic: ,(doc nth)

16:43 clojurebot: "([coll index] [coll index not-found]); Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences."

16:43 glogic: :(

16:43 * glogic cries

16:43 fdaoud: ,(nth [1 2 3 4] 1)

16:43 clojurebot: 2

16:43 dakrone: glogic: it's trying to call the function called "1"

16:43 fdaoud: ([1 2 3 4] 1)

16:43 glogic: ya i redid it though

16:43 fdaoud: ,([1 2 3 4] 1)

16:43 clojurebot: 2

16:43 glogic: ,(nth (1 2 3 4) 1)

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

16:44 glogic: aw

16:44 ,(nth [1 2 3 4] 1)

16:44 clojurebot: 2

16:44 fdaoud: ,(nth '(1 2 3 4) 1)

16:44 clojurebot: 2

16:44 fdaoud: ,('(1 2 3 4) 1)

16:44 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

16:44 glogic: you guys are fun

16:44 TakeV: Wait, you don't need the nth?

16:44 fdaoud: not for vectors

16:44 TakeV: ,([1 2 3 4 5] 2)

16:44 clojurebot: 3

16:44 fdaoud: vectors are functions of their indexes

16:44 TakeV: ,(count [1 2 3])

16:44 clojurebot: 3

16:45 TakeV: Ah, true.

16:46 shales: Has anyone used a java.nio.ByteBuffer in clojure to pull apart or build some binary data like a packet?

16:47 * glogic goes back to pair programming, which rihgt now seems more like clusterf*ck progamming

16:52 The-Kenny: shales: Yeah, I've done this. But rather ugly and imperative

16:53 shales: http://github.com/the-kenny/netwars-clj/blob/master/src/netwars/map_loader.clj#L123

16:53 It's rather ugly, with much special cases

16:54 shales: thanks. I've written some helper functions for working with ByteBuffers too http://github.com/geoffsalmon/bonjure/blob/master/src/bonjure/bytebuffer.clj

16:54 Wanted to see how other people had approached it

16:56 The-Kenny: shales: Oh, they look very nice. Maybe I'll try them :)

16:57 shales: missing your read-n-string and read-null-string

16:59 TakeV: So, with compile, it compiles the passed namespace into a class? Even namespaces that were created in REPL, without any source file?

17:05 astoddard: Has anyone out there been using the "map-invert" function in clojure.set? It ignores duplicated values (becoming keys), with the one picked being arbitrary.

17:06 Maybe that behavior is considered obvious but I wonder if it should at least be documented.

17:13 slyphon: so, is there a difference between "with-bindings" and "binding"?

17:14 binding uses this "var-ize" fn, but i'm not really sure what that does...

17:17 kotarak: slyphon: with-bindings is more low-level. Normally you should use binding.

17:17 slyphon: ok

17:17 kotarak: slyphon: (binding [a b] ...) <=> (with-bindings {(var a) b} ...)

17:17 slyphon: i was concerned at first that one was thread-local and the other wasn't, but it seems they both are

17:17 ahhh

17:18 dnolen: nice: http://mmcgrana.github.com/2010/03/clojure-web-development-ring.html

17:18 slyphon: before you die, you see "the ring"

17:20 raek: I really like the idea of this standardized way of representing requests and responses

17:22 TakeV: Is Ring supposed to be to Clojure as what Rails is to Ruby?

17:22 chouser: no

17:22 lancepantz: it's rack

17:22 slyphon: yay rack!

17:23 chouser: we don't have anything as big and frameworky as rails yet, I think.

17:23 TakeV: Ah.

17:23 Rails is quite a nice system.

17:23 slyphon: rails is "ok"

17:23 lancepantz: i've seen a couple of project on github attempting, they are all pretty new still though

17:23 chouser: compojure may have been headed there at one point, but has fortunately been adjusting more toward being a comprehensive library

17:24 lancepantz: TakeV: compojure is similar to sinatra, if you've used it

17:24 TakeV: I have not.

17:24 To google!

17:27 dnolen: well from the looks of it tho, Compojure 0.4 is now really just a routing library. Like Moustache.

17:28 gstamp: Quick question... Say I have an array [1 2 3] and I want to repeat it indefinitely so that the output looks like (1 2 3 1 2 3 1 2 3...), how would I do it? I originally was thinking (repeat [1 2 3]) but that gives me ([1 2 3] [1 2 3] ...)

17:28 dnolen: Ring 0.2 does all the heavy lifting that Compojure (and then some it seems) that Compojure 0.3.2 used to do.

17:28 lancepantz: dnolen: i think actually uses clout for the routing library

17:28 chouser: ,(take 20 (cycle [1 2 3]))

17:28 clojurebot: (1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2)

17:28 lancepantz: it's pretty thin now, just a few macros

17:28 gstamp: awesome, thank you

17:29 dnolen: lancepantz: oh yeah, yr right

17:29 chouser: gstamp: note the input there is a vector (not an array) and the output is a seq

17:30 gstamp: chouser: that's fine for my purposes. I actually remember reading about cycle but had forgotten it. :-)

17:40 brian__: Hi, Is there a better way to increment through two or more sequences than this: (doseq [line (map #(str %1 " (" %2 ")") w v)]) , pull the values from "line" ?

17:41 raek: brian__: have you tried "for"?

17:42 brian__: no, i'll take a look, thanks

17:42 chouser: 'map' is the way to walk two or more seqs in step

17:42 raek: brian__: what is the desired input and output for your function?

17:42 chouser: or sometimes 'zipmap', but I don't think that applies here

17:43 brian__: it seems a little clunky to have to parse the values from a string

17:43 I mean sequence

17:44 raek: brian__: can you give an example input and output?

17:44 brian__: ok

17:45 v - names , w - ages and I want to input to a database

17:45 for example

17:46 so in the above I have to figure out the exact index for each variable I want to input to the database, seems a little clinky

17:46 clunky

17:47 raek: so, you have two sequences, eg names = ["fred" "ethel"], ages = [30 40]

17:48 what should the code output?

17:48 ("fred (30)" "ethel (40)") ?

17:48 brian__: db.input(:age 30)

17:48 db.input(:age 30 :name fred)

17:49 i mean

17:49 raek: ,(interleave ["a" "b" "c"] [1 2 3])

17:49 clojurebot: ("a" 1 "b" 2 "c" 3)

17:50 raek: ,(partition 2 (interleave ["a" "b" "c"] [1 2 3]))

17:50 clojurebot: (("a" 1) ("b" 2) ("c" 3))

17:50 kotarak: (doseq [[name age] (map vector names ages)] (.input db :age age :name name))

17:50 brian__: ok , thats good

17:50 raek: ah, (map vector name ages) accomplishes this better

17:50 Chousuke: or (doseq [name names age ages] ...)

17:51 or hm

17:51 kotarak: or (doseq [[name age] (zipmap names ages)] ...)

17:51 Chousuke: I think that does a cartesian product :P

17:51 brian__: ok because i didn't see ant example of multiple sequences for doseq online

17:52 thanks guys

17:56 raek: oh btw, has anyone thought about making a if-not-let macro?

17:56 if-let is great for error handling

17:57 but I like having special cases and error handlig first

17:58 I was thinking about something like this: (if-not-let [foo (might-yield-nil)] (report "foo is nil") (do-stuff foo))

17:58 simply if-let, but with the true and false branch swapped

18:14 nteon: is there a way to examine a function I've created in a slime session?

18:14 perhaps a way to dump the bytecode to disk, and use a disassembler?

18:16 arohner: nteon: the tools are all there, but undocumented

18:16 nteon: all clojure fns are classes

18:16 and you can ask the classloader the class came from for its bytecode

18:20 nteon: hrm, maybe I was wrong about asking the classloader for its bytes. I can't find the method now

18:22 nteon: one thing I'm more sure about is if you precompile your clojure code, you'll get a directory full of .class files

18:22 nteon: arohner: yea, thgats what I'm going to resort to

18:23 mattrepl: arohner: re: classloader and fetching compiled class' bytecode, sounds familiar

18:25 maybe it's just the other way bytes -> class

18:26 arohner: mattrepl: yeah, I found the method to define a class by passing a byte []. I thought the inverse existed. *shrug*

18:42 glogic: ,(doc defn)

18:42 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"

18:43 glogic: ok wow i'm lost

18:46 dakrone: glogic: what are you trying to find?

18:48 glogic: dakrone: well

18:48 dakrone: i dont' expect all the docstrings to make perfect sense obviously but that one is kind of a dump of all the possible forms of defines i think

18:49 dakrone: so it takes some parsing, whcih is fine i just wans't expecting quite that much ifnromatin on that

18:49 * glogic is typing like shit

18:49 Raynes: Type a little slower. ;)

18:49 glogic: for real bro

18:49 lol

18:49 dakrone: ahh, okay, well luckily almost all the options are optional

18:50 glogic: ya i kind of get the impression i can stumble a bit

18:50 ,(defn [name "doc???" x] (+ x 1))

18:50 clojurebot: DENIED

18:50 glogic: oh right nvm

18:50 well anyway would that work?

18:51 you just really need a sandbox for clojurebot so you can define safely

18:51 laynor: Hi, I'm not really experienced with the jvm. I'd like to play with clojure and swt, but I don't really get where to place the library and stuff

18:51 Raynes: (defn name docstring [args] body)

18:51 glogic: then you can serialize evalution and build apps collbaoratively

18:51 althought iw as suggested to me that the best way is to start sessions via irc if your'e going to do any serious editing

18:51 Raynes: glogic: There really isn't a way to define safely. Anything defined will pollute the namespace. clojurebot is there for showing people how to do stuff they're asking about.

18:51 glogic: Raynes: oh ok i parsed that really wrong lol

18:52 dakrone: (defn add-numbers "Adds two numbers together" [a b] (+ a b))

18:52 there's a simple example

18:52 glogic: Raynes: oh ok, i had an eval bot i did up in chicken, i used the sandbox library it was reasonable never had any major issues tehre

18:52 dakrone: the docstring is optional

18:52 ,(defn add-numbers "Adds two numbers together" [a b] (+ a b))

18:52 clojurebot: DENIED

18:52 glogic: dakrone: right

18:52 dakrone: i wasn't sure where it went was all

18:52 dakrone: so right after name

18:52 dakrone: yep

18:53 glogic: is that where docstrings go

18:53 i dont' remember

18:53 nteon: what java disassembler do people recommend?]

18:54 glogic: oh CL puts them after arguments i think

18:54 * glogic looks

18:54 laynor: glogic: yeah

18:54 :)

18:54 glogic: laynor: seems silly

18:54 laynor: it actually makes more sense to me where it is in clojure

18:54 laynor: really?

18:54 glogic: kind of

18:54 name -> what i am

18:54 dakrone: nteon: I like jad

18:54 glogic: although splitting up the function signature has some caveats on readability

18:55 dakrone: but it looks like it hasn't been updated in quite a while, and it's been a while since I've used it

18:56 nteon: wikipedia suggests http://java.decompiler.free.fr/

18:56 laynor: glogic: http://paste.lisp.org/display/97047 looks totally good to me, i think it wins in readability

18:57 * glogic checks

18:57 glogic: laynor: ya

18:57 laynor: you know compared to the othr way

18:57 laynor: i think yo'ue right

18:57 laynor: I guess clojure opted for documentation after the name because of overloads

18:57 nteon: dakrone: thanks!

18:58 glogic: laynor: having the argumentsa fter is a little wierd now that you showed methat

18:58 ,(doc defn)

18:58 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"

18:58 glogic: hrrm

18:59 laynor: for me it's also strange how in some clojure code they split the line after the function name

18:59 glogic: are arguments always []

18:59 laynor: in clojure? i think so

18:59 but I'm no clojure expert

19:00 i downloaded it yesterday

19:00 ahah

19:00 glogic: laynor: ya me too

19:00 laynor: lol

19:00 laynor: I'd like to use swt, but i really don't get how to load the library

19:00 glogic: is the jvm somehow less dynamic with jruby?

19:00 laynor: i always avoided the jvm like the plague

19:00 oh

19:01 no idea

19:01 :)

19:01 glogic: i'm just readint eh topic

19:01 laynor: ^^

19:07 -_-'

19:08 anyone that can help me loading swt ? ^^

19:31 technomancy: wouldn't it be cool if calling a vector with two arguments called subvec?

19:31 also: wouldn't it be cool if calling a vector with a negative number counted from the end?

19:32 also: it would be great to have serializeable continuations.

19:32 that is all.

19:36 bsteuber: laynor: what's your exact problem?

19:46 laynor: bsteuber: I got it now :) But i got another problem...

19:46 bsteuber: ic

19:46 laynor: when i use java from the command line it's by default the 64 bit server machine

19:47 and I can load the 64 bit swt library correctly

19:47 but emacs for somewhat reason runs clojure with a 32 bit jwm

19:47 jvm

19:48 so, basically, I can't experiment with swt from the slime repl :/

19:48 and i can't run code from emacs

19:49 any idea how to solve this?

19:50 uhm, a clojure emacs clone would be nice :O

19:51 technomancy: laynor: just wait a while. Emacs now has threads, so as soon as clojure-in-clojure is done we can begin porting clojure to the Emacs VM.

19:51 phren0logy: laynor: why not start your repl then connect to it instead of starting it in emacs?

19:52 _mst: laynor: perhaps (add-to-list 'swank-clojure-extra-vm-args "-d64") ?

19:54 laynor: _mst: Unrecognized option: -d64

19:54 :(

19:55 _mst: ah, sorry. Turns out that only works on solaris :P

19:55 laynor: lol

19:55 uhm

19:56 _mst: ah actually no, it works on an intel box here too

19:56 laynor: java -version?

19:57 _mst: java version "1.6.0_02"

19:58 but it works on java 1.5.0_12 too...

19:58 laynor: what about the server vm? mine says Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01, mixed mode)

19:58 _mst: Java HotSpot(TM) 64-Bit Server VM (build 1.6.0_02-b05, mixed mode)

19:58 laynor: no idea

19:58 lol

19:58 _mst: ... it's not a path difference between emacs and your shell is it?

19:58 like emacs picking a different java implementation or something?

19:58 laynor: no :)

19:59 i ran emacs from cmd to be sure

19:59 also, that doesn't explain why -d64 doesn't work

19:59 uhm

20:01 oh

20:02 if i wanted to run it manually, should i do something like java -d64 -jar clojure.jar?

20:02 _mst: yep, that should work

20:02 laynor: it doesn't work for me

20:02 java doesn't recognize the -d64 option

20:04 could it be it depends on emacs being 32 bits, and being unable to run 64 bit processes? (no idea if it makes sense at all)

20:05 _mst: hm, mind you, your version string suggests that it's 64-bit anyway...

20:05 laynor: uhm

20:05 _mst: from emacs you could try M-x eshell then run 'java -version' from there--see if it matches what you get from the shell

20:06 laynor: wait, i try to Java HotSpot(TM) Client VM (build 16.0-b13, mixed mode, sharing) :O

20:06 s/wait, i try to//

20:06 _mst: hm, how about: java -server -version

20:07 laynor: Error: no `server' JVM at `C:\Program Files (x86)\Java\jre6\bin\server\jvm.dll'.

20:07 lol

20:09 _mst: hm, yick. I must admit I'm fairly ignorant of java on windows :)

20:10 laynor: you know more than me anyway ^^ I tried to avoid the jvm as long as I could

20:10 but clojure is tasty

20:12 I'm looking forward to clojureclr

20:12 what's the status?

20:21 licoresse: looking forward to a clojureobj-c, or whatever the name should be

20:22 * licoresse enjoying The joy of Clojure

20:23 lancepantz: licoresse: the book? did it get released?

20:23 licoresse: lancepantz: no, only the MEAP early bird

20:24 it's well written, I like it

20:24 lancepantz: ah, yeah i had the first few chapters on there

20:42 defn: http://lbrandy.com/blog/2010/03/never-trust-a-programmer-who-says-he-knows-c/

20:42 heh

20:43 licoresse: have they added some more chapters yet?

20:43 once i heard they were going to rearrange things i decided to hold off for awhile

20:43 licoresse: not yet, but saw a tweet that it could happen any day now

20:44 defn: yes me too -- hope it happens soon

20:44 licoresse: yes

20:47 wooby: hm, having some issues with this macro: http://gist.github.com/348620

20:47 licoresse: def: haha; “C++ is a language strongly optimized for liars and people who go by guesswork and ignorance.”

20:47 wooby: experimenting with auto-gensym for the first time, and the second iota# isn't the same name as the first

20:48 clojurebot: multimethods is what separates the boys from the men.

20:48 wooby: thanks in advance for any tips

20:48 licoresse: isn't the ...# gensym shortcut?

20:49 wooby: indeed

20:50 licoresse: and this is in a macro

20:51 wooby: right

20:51 joshua-choi: ...Why did clojurebot just talk?

20:52 licoresse: gensym creates a symbol, whatever# refers to it

20:53 where is your gensym wooby

20:53 wooby: it's in the let

20:54 it gets referred to again in the line starting with ~@

20:54 unfortunately the second time it creates a new sym, when i would like it to expand to the first one

20:57 technomancy: joshua-choi: he's practicing for an upcoming turing test

20:57 licoresse: just refer to it by deleting the #

20:58 pschorf: I am having an issue installing swank-clojure via ELPA

21:00 Whenever i attempt to install the package, I receive the following error: Error: Cannot open load file: slime

21:01 dnolen: hugod: technomancy: I tried the compile-file branch and things seem OK with ELPA slime. One thing I notice that is weird tho is that lein-swank no longer starts on 4005, but on a random port.

21:01 technomancy: pschorf: shouldn't be a problem; proceed as per the readme

21:03 pschorf: technomancy: when i run M-x slime, i get the following http://pastebin.com/KKeSY1MW

21:03 technomancy: pschorf: maybe try rm -rf ~/.swank-clojure and M-x slime again?

21:04 pschorf: also try some of the other ways of launching from the swank readme; lein swank or M-x swank-clojure-project

21:04 standalone repls are not used very often

21:07 pschorf: technomancy: no luck with the rm -rf... I was actually hoping for a standalone REPL to toy around with clojure a bit: I don't have any need to set up projects right now

21:17 technomancy: it appears I had a pre-existing .clojure directory, removing that fixed the problem

21:17 technomancy: thanks for the help

21:20 hugod: dnolen: Thanks for the testing. I think that has been that way for a while with the port

21:21 dnolen: hugod: so that's intentional?

21:23 hugod: I believe so, though technomancy would know better than I why it's that way - I guess to provent port collisions if you're already running other swank processes

21:23 dnolen: hmm. ok. hugod: so how does the new SLDB stuff work? I'm trying that out.

21:30 hugod: dnolen: there's a (swank.core/break) that should put you in sldb with locals available for inspection/available at the repl

21:35 dnolen: hugod: wow, that works! and you can even put in multiple breaks and continue :D

21:38 hugod: dnolen: glad you like it. You should also get nested exceptions all displayed in the same sldb buffer

21:39 dnolen: hugod: what do you mean by nested exceptions?

21:40 hugod: dnolen: exceptions that are caught and rethrown as a different exception

21:42 * dnolen thinks (swank.core/break) is going to be as big a deal as (swank.clj-contrib.macroexpand) was

21:48 licoresse: dnolen: where?

21:48 how do you use it?

21:51 dnolen: licoresse: one sec

21:55 hugod: dnolen: compile-file is now merged

21:55 still looking for volunteers to test or review the other swank-clojure branches...

21:59 dnolen: hugod: nice, any other branch you really want to see tested?

22:00 licoresse: basically you need to "lien install" the master branch of swank-clojure and use this instead in your project depedency list.

22:00 laynor: yay!

22:00 dnolen: licoresse: then you can effectively put (swank.core/break) to breakpoint anywhere in your code.

22:00 laynor: i got emacs to start the 64bit jvm :)

22:01 hugod: dnolen: it's in clojars 1.2-SNAPSHOT too

22:01 laynor: all working now, thank you all, good night

22:01 :)

22:01 dnolen: hugod: 1.2-SNAPSHOT of lein-swank? nice!

22:01 even better

22:01 * licoresse checking swank

22:02 hugod: dnolen: of swank-clojure - which I believe is used by lein-swank 1.2-SNAPSHOT

22:03 dnolen: the exception-location branch gets slime highlighting of compile errors to work

22:04 autodoc fixes for slime-autodoc in slime head - this one needs particular testing with elpa

22:04 licoresse: [null] An error has occurred while processing the Maven artifact tasks. WTF?

22:05 dnolen: hugod: I'm assuming if I test the branch I should create the jar from source and not pull from Clojars, right?

22:06 hugod: hyperdoc gets you links to the clojure api web page (C-c C-d h)

22:06 dnolen: yes

22:09 dnolen: licoresse: you need to add dev dependency [leiningen/lein-swank "1.2.0-SNAPSHOT"], probably need to use the 1.2.0 master snapshots for clojure and clojure.contrib as well.

22:09 licoresse: dnolen: ah, ok, thanks

22:12 hugod: dnolen: swank-clojure doesn't require clojure 1.2

22:13 dnolen: hugod: yeah I just noticed that.

22:13 I thought env stuff was 1.2.0

22:14 hugod: ahh yes, you only get that with 1.2 - what was I thinking - but it still runs with 1.1

22:21 arohner: I think I remember someone saying you have to specify the character encoding for swank or it gets fussy. Can someone point me to instructions?

22:22 dnolen: arohner: raek knew what to do, somebody needs to write this up somewhere.

22:22 hugod: Ok I see that I'm getting the option to jump to the exception location but the line number is wrong.

22:22 for me it says line 1, when it's line 31

22:23 arohner: right now, if I print say, an html page over swank, slime fails to parse the output from clojure, and then slime gives me exceptions on every action after that until I disconnect and reconnect

22:24 dnolen: arohner: yes it's very broken. you can't even input a unicode character, it will hang the REPL.

22:25 hugod: dnolen: so the stack trace in the sldb buffer gives a line number of 1 and it jumps to line 31?

22:25 dnolen: hugod: no line number 1 and jumps to 1. but the error is actually on line 31

22:26 hugod: btw, these are some amazing changes. thank you.

22:28 hugod: more detailed info.

22:29 hugod: dnolen: thanks for the appreciation

22:29 dnolen: if I have an undefined symbol, it jumps to the right place, however if I call a function with the wrong number of arguments I get line number at 1

22:30 shales: I'm trying out (swank.core/break) too, with [leiningen/lein-swank "1.2.0-SNAPSHOT"] from clojars. It's working when I directly call the function containing the break from the slime repl, but I get an exception if break is called on the AWT thread in response to clicking a JButton. Is this expected?

22:31 java.lang.IllegalStateException: Var swank.core.connection/*current-connection* is unbound.

22:31 at clojure.lang.Var.deref(Var.java:142)

22:31 at clojure.lang.Var.get(Var.java:133)

22:31 at swank.core$send_to_emacs__334.invoke(core.clj:77)

22:31 at swank.core$sldb_loop__403.invoke(core.clj:204)

22:31 at swank.core$invoke_debugger__407.invoke(core.clj:215)

22:32 hugod: shales: thanks for the report - I hadn't tried it from AWT

22:32 shales: No prob

22:33 Oh, and hi Hugo. This is Geoff from bonjure =)

22:33 hugod: Hi Geoff!

22:34 shales: I now see what you meant about how much better debugging in emacs could be

22:35 hugod: Still has a way to go

22:36 dnolen: I'll try and repro in a while

22:36 shales: ya, but shows plenty of promise

22:36 dnolen: hugod: cool I'll check out the other branches later.

22:42 arohner: how am I supposed to grab http://github.com/stuartsierra/lazytest via lein?

22:42 I get [WARNING] repository metadata for: 'snapshot org.clojure:clojure:1.2.0-master-SNAPSHOT' could not be retrieved from repository: stuart sierra snapshots due to an error: Unsupported Protocol: 'ftp': Cannot find wagon which supports the requested protocol: ftp

22:49 dnolen: this fixed my slime character encoding issues:

22:49 (setq slime-net-coding-system 'utf-8-unix)

22:49 my emacs and JVM are already set on utf-8

22:53 dnolen: arohner: hmm, I'm still getting ? when I try to print é

22:53 arohner: how did you set your JVM? -Dfile.encoding=UTF8

22:53 ?

22:54 arohner: I was able to print 'é in my slime repl

22:54 wooby: anyone a gensym guru? stuck on this macro, thanks in advance for help: http://gist.github.com/348703

22:54 arohner: dnolen: yeah, -Dfile.encoding=UTF-8

22:55 dnolen: can you print it in the console?

22:56 dnolen: arohner: I'm giving up on the utf stuff, it looks like lein-swank does the wise thing and select the default encoding for the OS. that seems to work much better.

22:56 lein-swank 1.2.0 that is.

22:56 arohner: wooby: I would write that as `(let [~'iota (atom -1)] ~@body)

22:57 wooby: ~'iota means insert the literal as-is, without ns-resolving the var

22:57 * dnolen can't wait for 1.2.0 of Clojure-everything

22:58 wooby: arohner, the effect i'm going for is (with-iota (let [a iota b iota] ;; a=1, b=2))

23:00 arohner: wooby: you want iota to increment after every time it's evaluated?

23:00 wooby: arohner, right

23:00 and i'm stumped on this gensym business :)

23:00 i can syntax quote iota# a second time but then it expands to a different symbol :\

23:01 arohner: foo# expands to the same symbol inside the same `

23:01 I'm not quite sure why that's breaking for you now

23:02 but if you want users to be able to refer to iota, instead of iota#, use ~'iota

23:03 wooby: arohner, thanks

23:45 sramsay: Dear clojurians: I am so confused by the functional universe.

23:45 To wit: I have a list of number and a list of structs.

23:46 Want to make successive numbers in the list keys to the corresponding structs in the hash.

23:47 I know how to do this with loops. How to do it with clever sequence functions?

23:48 wooby: sramsay, is your code somewhere? it sounds like you're looking for zipmap

23:48 ,(zipmap [:a :b :c] [1 2 3])

23:48 clojurebot: {:c 3, :b 2, :a 1}

23:48 sramsay: No! Really?

23:48 (looking in docs)

23:49 Unbelievable. That's it. Thanks.

23:50 namaste, wooby

23:50 wooby: no problem, have fun

23:51 sramsay: I'm sitting here thinking, "No functional programmer could possibly do it as stupidly and convolutedly as I'm doing it."

23:51 And indeed . . . ;)

Logging service provided by n01se.net