#clojure log - Apr 19 2010

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

0:06 dcnstrct: MadWombat, try installing it all using ELPA

0:22 defn: !walton zipmap

0:27 oops...

0:29 !walton zipmap

0:30 !part #clojure

0:36 !walton zipmap

0:38 !walton zipmap

0:38 defn-bot: ((zipmap [:a :b :c :d] (iterate inc 0)) :b)

0:38 => 1

2:17 vIkSiT: hi all

2:36 Licenser_: greetings

2:37 licoresse: hi

2:38 TheBusby: er, simple question, what's the trick for doing (let [{:foo :bar} my-map] (println (str foo "\t" bar))) ?

2:38 dcnstrct: ,(let [{:foo :bar} my-map] (println (str foo "\t" bar)))

2:38 clojurebot: java.lang.Exception: Unsupported binding form: :foo

2:39 TheBusby: I know you can do, let [{:foo foo :bar bar} my-map], but I thought there was a trick so you didn't have to type each element twice

2:39 licoresse: keys

2:40 (let [{:keys [:foo :bar]} ...

2:40 or maye just [foo bar]

2:41 TheBusby: ,(let [{:keys [foo bar]} {:foo 1 :bar 2}] (println (str foo "\t" bar )))

2:41 clojurebot: 1 2

2:41 TheBusby: licoresse: thank you!

2:41 licoresse: np

2:44 hiredman: you have it reversed, in destructuring the keyword goes in the value position

2:44 ,(let [{bar :foo} {:foo 1}] bar)

2:44 clojurebot: 1

2:45 TheBusby: so (let [{[foo bar] :keys} {:foo 1 :bar 2}] (println (str foo "\t" bar ))) ?

2:46 licoresse: ah

2:46 TheBusby: ahh, you mean from the earlier comment

2:46 licoresse: idiomaic?

2:46 ye

2:46 yes

2:48 ,(let [{:keys [foo bar]}] (str foo ", " bar))

2:48 clojurebot: java.lang.IllegalArgumentException: let requires an even number of forms in binding vector

2:52 licoresse: to early for me...

2:52 Licenser_: ,(let [{foo :foo bar

2:52 clojurebot: EOF while reading

2:52 hiredman: you have to, you know, bind something

2:52 Licenser_: ,(let [{foo :foo bar :bar} {:foo 1 :bar 2}] (str foo ", " bar ))

2:52 clojurebot: "1, 2"

2:52 licoresse: hiredman: I know, I was just not really thinking

2:54 hiredman: ,(let [{[bar _] :foo} {:foo [1 2]}] bar)

2:54 clojurebot: 1

2:54 Licenser_: destructing is fun :D

2:55 hiredman: fn

3:26 tomoj: can anyone clue me in on where to learn how to set up polyglot maven for clojure?

3:27 ohhh

3:27 I think I got it

3:28 hadn't noticed there were binary snapshots available and was trying (and failing) to build from source

3:29 medical: on binding, is there a way to keep that bound structure as whole with destructured form? something like (defn norm2d [[x y] :as point] (println x ":" y " len:" (len point))

3:32 or should i just use defn with the whole thing and destructure with let ?

3:33 hiredman: ,(let [[a b :as x] [1 2 3 4]] x)

3:33 clojurebot: [1 2 3 4]

3:34 medical: oh :) it really was :as

3:35 thanks

3:47 LauJensen: Morning

3:47 licoresse: Morning

3:47 Licenser_: morning LauJensen

3:52 hmm I have a odd problem with lein, I've a lein plugin that isn't recognized - so the same jar works at home, anyone had this problem before?

3:53 AntonyBlakey: tomoj: current 0.8 download doesn't include the latest stuff. You can either build from source (which is easy, 'cos it's a maven build) or you can grab a later snapshot from http://linkuistics.com/downloads/polyglot-maven/linkuistics-pmaven-0.8-SNAPSHOT.zip

3:57 tomoj: AntonyBlakey: easy?

3:58 I think not

3:58 AntonyBlakey: mvn install

3:58 how hard is that?

3:59 tomoj: hmm

3:59 not hard at all

3:59 I wonder what I was doing the other day

4:00 LauJensen: the only thing tricky about maven is setting it up and customizing a build

4:00 tomoj: aha

4:00 in fact, I had been doing 'mvn install' but it doesnt' work

4:01 https://gist.github.com/9cae90fafd8dee5a8c1e

4:04 AntonyBlakey: A jruby installation problem it looks like. Maven itself isn't the issue here - polyglot maven installs and runs jruby, clojure, scala and groovy as part of the build process, so there's lots that could go wrong with the build.

4:04 What platform are you on?

4:04 tomoj: ubuntu karmic

4:04 I just wish I didn't have to deal with jruby, groovy, or scala to use the clojure stuff

4:05 Licenser_: hmm is it possible to write classes in clojure that are used from jruby?

4:05 AntonyBlakey: Problem is that Polyglot Maven needs support for all the languages it supports so you can feed it any project with a pom written in any DSL and it will work. So subsetting isn't really possible.

4:06 In practice you would just download a binary - see the link I posted to get one with clojure support.

4:06 Licenser_: yes

4:06 All the JVM languages interop through POJO classes

4:07 i.e. Java can use JRuby classes and Java can use Clojure classes, and the reverse, QED.

4:08 tomoj: AntonyBlakey: ah, great, thanks

4:09 a lot

4:09 will try again in the morning

4:10 Licenser_: AntonyBlakey: cool, is there by chance some example you know of?

4:11 AntonyBlakey: Nothing I can point you to publicly. I've done it at the REPL. You can start JRuby from Clojure in a REPL and run Ruby code that way,

4:12 It's all just Java calls.

4:13 Licenser_: kk I'll see to dig into that :)

4:13 AntonyBlakey: I've not tested every edge case, 'cos I was just mucking around to see what different language plugins for Polyglot Maven would look like e.g. write your maven plugins in Clojure.

4:15 Using Clojure macros allows you to write plugins in-line in the pom.clj, or just hook into build lifecycle events and execute arbitrary Clojure as certain points.

4:15 Makes maven into quite a different kettle of fish.

4:17 Licenser_: that is quite powerful

4:17 AntonyBlakey: And of course you can run Ruby tools from within your pom.clj at will via JRuby. This is one are where the JVM ecosystem is useful for more than just one language <-> Java libs.

4:17 Licenser_: but my usual question, is it also simple? :P

4:18 AntonyBlakey: It will be, although there is a certain amount you will need to know e.g. what are the hooks. This is *just* a matter of documentation.

4:18 IMO that is.

4:18 Licenser_: AntonyBlakey: I mean for time simple case

4:18 see I am a big fan of keeping simple stuff simple :P usualy I prefare (close to) no work for the simple cases

4:18 AntonyBlakey: Yes. Rememver Polyglot Maven accepts lein project.clj files, so it starts that simple.

4:19 dcnstrct: Licenser, where can I read about calling Ruby code from clojure ?

4:19 AntonyBlakey: And a real pom.clj isn't much more complicated.

4:19 dcnstrct: err address that to antonyblakey

4:19 or whoever

4:19 Licenser_: dcnstrct: I have no cluie

4:19 AntonyBlakey: dcnstrct: look for information about calling JRuby from Java, JRuby<->Java interop etc.

4:19 dcnstrct: AnthonyBlakey, assume I have the jruby-complete jar in my classpath

4:20 Licenser_: hmm that calls for another lib :P

4:20 cljruby

4:20 AntonyBlakey: http://www.ics.muni.cz/~makub/ruby/

4:20 dcnstrct: calling Jruby from Java was kind of painful last time I checked.. you have to do all this stuff to launch the interpreter

4:21 AntonyBlakey: that shows how to start jruby from java. Now just do that Java stuff in Clojure and you're cooking with gas.

4:21 dcnstrct: nice

4:21 thanks

4:21 AntonyBlakey: Scripting APIs make it simple.

4:22 Also here: http://java.sun.com/developer/technicalArticles/scripting/jruby/. Rest you can google :)

4:23 dcnstrct: a cljruby would not suck. that's a good idea Licenser

4:23 could you get started on that for me ?

4:23 ;)

4:23 Licenser_: dcnstrct: heh

4:23 I will some day

4:25 dcnstrct: maybe we can start packaging clojure jar files as rubygems and bring them in with cljruby.. then you'll finally have that maven free dependency system you've always wanted

4:25 Licenser_: :D

4:25 dcnstrct: with lein search I already am quite happy

4:26 aside from the fact that I broke it for some reason :(

5:06 Bendlas: hi folks

5:07 i get some odd behavior from compojure 0.4

5:08 the `_method` parameter doesn't work anymore

5:08 I suspect this is because ring doesn't pass parameters as :keywords but as "strings"

5:08 can somebody confirm this?

5:10 arbscht: Bendlas: that's correct. btw, there is a #compojure channel

5:11 Bendlas: i see

5:11 .. which is not exactly crowded

5:12 anyway, somebody fixed this already?

5:13 arbscht: compojure 0.4 is not fully compatible with 0.3. you'll likely have to port your code

5:15 Bendlas: true but this is a bug, isn't it?

5:15 Licenser_: ah sneaky lein does use features of find that solaris does not have

5:22 LauJensen: Bendlas: Its not a bug, but a revision of the entire framework

5:22 Lots and lots of things break :)

5:27 Bendlas: yeah, tell me about it.

5:27 got the hint, I'll fix it myself

6:44 Licenser_: hmm what is the artifact for clojure 1.2.0?

6:50 nurv: Morning.

7:01 Licenser_: morniung nurv

7:45 AntonyBlakey: Licenser: [org.clojure/clojure "1.2.0-master-SNAPSHOT"]

7:45 [org.clojure/clojure-contrib "1.2.0-master-SNAPSHOT"]


7:46 There is also [org.clojure/clojure-contrib "1.2.0-SNAPSHOT"] which has different package names and breaks a few existing libraries

7:48 cemerick: 1.2.0-master-SNAPSHOT is old.

7:48 I mean, if you need the old namespace structure, OK, but know that no fixes or new features are going to be added to that lineage.

7:49 Licenser_: ^^

7:55 AntonyBlakey: I know, and I don't use the master- tag except when certain libraries that are precompiled break, in my case hiccup and congomongo. I could patch them, but then I'm committing to maintaining forks because such a patched lib won't work with 1.1. The fact that 1.2.0 contrib isn't backwards compatible is a PITA.

7:56 Is there a backwards compatibility addon?

7:56 i.e. one that does some ns magic....

8:07 Licenser_: cemerick: what is the new one?

8:07 cemerick: Licenser_: 1.2.0-SNAPSHOT

8:08 Licenser_: ah w/o mater

8:08 so it did not work for clojure itself w/o the master

8:08 cemerick: AntonyBlakey: no, and it's unlikely one will be made -- the contrib changes aren't just moving around namespaces, there are fn name changes, signature changes, etc.

8:09 you can make a lib 1.1 and 1.2 compatible without forking

8:10 Licenser_: hmm I am confused I do a lein compile on a 1.2 project and ti compiles c.c.seq-utils stuff :( that shouldn't happen right?

8:10 cemerick: exactly that is what I am trying bot I seem to have faulty test cases :/

8:10 cemerick: AntonyBlakey: e.g. http://github.com/jclouds/jclouds/commit/82f6b1c7772ec8416f35124e5ab5cc97c22d7987

8:10 Licenser_: if you have your dependencies set properly, no

8:11 Licenser_: I use (if (= (clojure-version) "1.1.0") (some version specific stiff)

8:11 cemerick: I would generally advise that version-sniffing be avoided.

8:11 Licenser_: might it be that lein compile uses 1.1.0 to compi;le since lein usees it?

8:12 cemerick: I don't know much about lein's compilation process. One would hope it'd fork a new process using whatever dependencies you've declared.

8:12 Licenser_: cemerick: I work on clj-sandbox and some classes only exist in 1.1.0 has that is why I hope the version sniffing is kind of apropriate

8:12 it is not for using them just for having them in the whitelist

8:13 cemerick: IMO, it's easier and more reliable to just try to use such classes, and if they can't be found, catch the exception and move on.

8:13 Licenser_: see the link I pasted above for an example.

8:14 Licenser_: *nods* Tried that didn

8:14 't work

8:14 cemerick: In what way?

8:14 Licenser_: since I had something like (class-matcher clojure.lang.ArrayStream) so it wasn't the code throwing exceptions but the compiler

8:14 which I could not catch it seems

8:15 cemerick: no, you can catch compiler-emitted exceptions -- that's what I'm doing in the jclouds code above

8:15 Licenser_: hmm it did not work for me I'll investigate in that

8:15 so I tried exactly that try catch construct

8:16 _ato: (use ...) isn't a compiler-emitted exception

8:16 cemerick: I mean, do what works for you, but version-sniffing is notoriously unreliable in a variety of contexts.

8:16 _ato: (use ...) is just a function

8:16 Licenser_: user=> (try java.lang.bla (catch Exception e "eeee!"))

8:16 java.lang.ClassNotFoundException: java.lang.bla (NO_SOURCE_FILE:1)

8:16 no working

8:17 hmm could use resolve there

8:17 _ato: what are you use ArrayStream for?

8:17 Licenser_: _ato: for the whitelist of allowed classes :P

8:18 I don't need the functionality I just need the class

8:18 _ato: I'd just leave it out, it was experimental functionality never supposed to be used by anyone

8:18 but if you really want it

8:18 you can get it like this:

8:18 Licenser_: there are more

8:18 (try (resolve 'java.lang.bla) (catch Exception e "eeee!"))

8:18 that works

8:18 but it's ugly as hell when done with like 6 classes :(

8:19 _ato: ,(resolve 'java.lang.String)

8:19 clojurebot: java.lang.String

8:19 _ato: ,(class (resolve 'java.lang.String))

8:19 clojurebot: java.lang.Class

8:19 Licenser_: *nods*

8:19 _ato: huh...

8:19 so it does

8:19 Licenser_: well I'll have to run thanks foir the help :)

8:19 _ato: ,(Class/forName "java.lang.String")

8:19 clojurebot: java.lang.String

8:19 Licenser_: I'll see if I can make a nice combination of apply and resolve to handle the situation

8:19 _ato: ^ what I was thinking, but your resolve way is probably nicer ;-)

8:20 Licenser_: ^^

8:20 _ato: could maybe just do (map resolve '[java.lang.Foo clojure.lang.Bar ...])

8:21 well, with the error handling

8:49 Bendlas: is there anything in the std lib, similar to (defn- map-key-alter [map key f]

8:49 (assoc map

8:49 key (f (map key)))) ?

8:51 AntonyBlakey: Hmmm... very sad to see that approach to backwards compatibility in clojure-contrib.

8:51 Rather than deal with the problem where it is caused, *every* client has to be modified.

8:52 If a function changes semantics or signature it should be given a different name, or moved to a different namespace (which is roughly the same thing).

8:55 Not to mention the problem it causes non-open-source uses.

9:26 * licoresse looking for someone affordable to host my clojure-servlets

9:28 ordnungswidrig: licoresse: what about google appengine?

9:28 licoresse: ordnungswidrig: hmm, yes, why not...

9:30 ordnungswidrig: licoresse: despite the rather good specification and the security model of the JVM serlvet / j2ee hosting did not break through before. I don't know how GAE handles the separation between application but I gues it's some advand linux kernel sourcery.

9:32 licoresse: ordnungswidrig: know any good tut. to bring me up to speed (with a clojure perspective)?

9:33 ordnungswidrig: google for it, there were some tutorials in the blogosphere. I'll have a look at my delicious bookmarks as well...

9:33 sattvik: licoresse: Kattare is a decent Java-oriented hosting service.

9:38 ordnungswidrig: hmm, kattare manages to have a type in the company's name on their website...

9:40 licoresse: I think appengine will work just fine

9:40 thanks

9:42 ordnungswidrig: hmm, the sure is somebody which offers servlet hosting on top of ec2. I a way that you deploy and forget your .war file and don't have to care about the stuff around. If not, there should be somebody.

10:43 brandonw: how would one test a multi-dimensional array for a certain value over a certain area?

10:44 for example, if i had a 10x10 array or vector of booleans, and i wanted to test if *any* of the values in the square from coord 3,2 and 6,4 were false

10:50 remleduff: Something like: (some true? (for [x (range 3, 6) y (range 2 4)] (get-in *arr* [x y])))

10:51 Probably other ways too, I'm a newbie :)

10:52 I have the test backwards, you wanted false values, but, same idea

10:53 brandonw: Sorry, should have said your name

10:58 ,(some (not true?) (for [x (range 1 1) y (range 2 4)] (get-in [[true true true] [true false true] [true true true]] [x y])))

10:58 clojurebot: nil

10:58 remleduff: ,(some (not true?) (for [x (range 0 2) y (range 2 4)] (get-in [[true true true] [true false true] [true true true]] [x y])))

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

10:58 npoektop: hi! if someone declared defn- a func in some file, how to :use that func? Is it possible?

10:58 hircus: remleduff: #(not true? %)

10:58 remleduff: ,(some #(not true? %) (for [x (range 0 2) y (range 2 4)] (get-in [[true true true] [true false true] [true true true]] [x y])))

10:58 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$not

10:58 hircus: oops: #(not (true? %))

10:59 remleduff: ,(some #(not (true? %)) (for [x (range 0 2) y (range 2 4)] (get-in [[true true true] [true false true] [true true true]] [x y])))

10:59 clojurebot: true

10:59 remleduff: There we go :)

10:59 arohner: cemerick: why do you think git SHA1's make lousy version numbers?

11:00 cemerick: arohner: where to start? ;-)

11:00 chouser: npoektop: they wanted it to be private, so ... are you sure you want to try to use it?

11:00 npoektop: chouser, yes, i'm sure.

11:01 chouser: npoektop: if you're really sure, and don't mind the breakage that will result when they change their "internal" api, there are ways...

11:01 arohner: cemerick: how about with something that justifies the assertion :-)

11:01 hircus: arohner: they're not ordinal

11:02 cemerick: arohner: version numbers should be sequential. Anything else makes it far more difficult to determine lineage. Beyond that, your SHA may disappear at some point, and non-sequential version numbers make it impossible to use version number ranges in pom files (and I presume lein version numbers accept ranges as well).

11:02 npoektop: chouser, i'm absolutely sure. How to do that? )

11:02 cemerick: Finally, the SHA is already recorded in the deployed POM

11:02 hircus: arohner: I think Mercurial has the right balance, with both a global changeset ID (like Git) and sequential rev numbers (that might not be the same in different clones)

11:03 chouser: npoektop: (def foo @#'other.namespace/foo) should be sufficient.

11:03 npoektop: chouser, thank you

11:03 arohner: cemerick: yes, but semantic versioning can't properly represent branched versions.

11:03 cemerick: I've seen lots of SHAs in clojars, which is a shame. I understand the impulse (tie a build to a rev in git), but there's already mechanisms for doing that.

11:03 arohner: that's what the qualifier in maven version numbers is for

11:03 * cemerick looks for alink

11:04 arohner: so 0.3.3-A98723DEF?

11:04 cemerick: http://mojo.codehaus.org/versions-maven-plugin/version-rules.html

11:04 hircus: arohner: I'd prefer 0.3.3-20100418-A98723DEF

11:04 cemerick: arohner: well, no, you want the qualifier to be indicative of the branch

11:04 I'd choose 0.3.3-clojure1.2 or something

11:05 hircus: still traumatized by some Maven POMs having versions such as x.y.z.Beta instead of x.y.z-Beta

11:05 arohner: AFAIK, lein can't download by SHA1, even though it's contained in the pom

11:05 cemerick: yeah, few read the docs :-/

11:05 arohner: and I've never heard of maven doing it

11:06 hircus: cemerick: including the core Scala devs :p

11:06 cemerick: arohner: I don't think that's a reasonable use case at all.

11:06 The SHA is useful for re-tracing provenance, but not for indicating dependencies.

11:06 hircus: ouch :-(

11:06 AntonyBlakey: Maven intends classifiers to be used for things like 0.3.3-clojure1.2

11:07 arohner: we'll have to disagree on that. I've been burned too many times by two artifacts having the same version and different code

11:07 SHA1s handle that nicely

11:07 remleduff: I like a git SHA id in the version if you're talking about a few patches you've made against a "known" version

11:07 cemerick: arohner: well, that's a failing on whoever published the artifact,

11:07 arohner: cemerick: what about snapshots?

11:08 the whole reason for the 0.3.3 builds was that major were introduced in the contrib build that broke our compojure builds

11:08 *major changes

11:08 cemerick: AntonyBlakey: In general, I'd agree, but lein doesn't support classifiers, and that's what people are using to deploy to clojars.

11:08 arohner: yes, that's what we get for relying on snapshot builds, but it's a reasonable use case to pick a specific version and run with it

11:08 AntonyBlakey: And thus is lein broken :/

11:09 cemerick: arohner: well, was 0.3.2 released depending upon SNAPSHOTs?

11:09 arohner: no, but it ran just fine against 1.2-SNAPSHOT until the middle of last week

11:10 cemerick: arohner: ah, that's because the hudson builds were fixed to clean the old namespaces out :-)

11:10 AntonyBlakey: I've had to copy files from contrib 1.1.0 into my 1.2.0-SNAPSHOT using ring/compojure/enlive/congomongo project to make it work.

11:10 arohner: cemerick: yeah, I found your post about that, right around the time the snapshot stopped working

11:11 AntonyBlakey: Specifically json/read json/write str-utils java-utils duck-streams

11:11 cemerick: arohner: yup. You can blame that one me if you like, but the status quo was incorrect (although convenient for those that weren't actually tracking the latest contrib changes).

11:12 arohner: cemerick: I don't blame you; you correctly fixed a bug

11:12 AntonyBlakey: IMO not being backwards compatible is a big mistake.

11:12 cemerick: AntonyBlakey: they weren't changed on a whim. It's in preparation for those namespaces to move into clojure proper.

11:13 AntonyBlakey: Sure, but clojure-contrib should have left the old ones in there as well.

11:13 cemerick: arohner: FWIW, the only 0.3.2 artifact I can find in clojars does depend on snapshots http://clojars.org/repo/org/clojars/robertpfeiffer/compojure/0.3.2/compojure-0.3.2.pom *shrug*

11:13 AntonyBlakey: I disagree. For how long? If people want the old code, then target c.c-1.1.0

11:13 arohner: cemerick: IMO, VCS already handles version numbers. Maven's own system only adds a layer of confusion on top of that

11:14 cemerick: arohner: *D*VCS does not provide for sane version numbers at all.

11:14 AntonyBlakey: Here's an issue. I want to use 1.2.0, but ring depends on clj-html and clj-stacktrace, neither of which are compatible with 1.2.0

11:15 hircus: cemerick: not true -- Mercurial does, as long as you have a canonical "master" repository (which most projects tend to have)

11:15 cemerick: hircus: Fair enough :-) I don't know hg. I revise to: git does not provide for sane version numbers at all.

11:15 AntonyBlakey: There's *no* reason to force the clients of a library to all change. The clients aren't the one changing the code. And what's more, *every* client has to change, which is more work and more disruptive than simply making it backwards compatible.

11:15 arohner: cemerick: that's not arbitrary. They do it because that's the only way to properly version the files. Throwing that information away causes problems

11:16 AntonyBlakey: Eventually entire ecosystems will be stuck in transitive-old-versions-required hell

11:16 hircus: AntonyBlakey: surely it won't be an issue once Ring is updated?

11:16 AntonyBlakey: Just think where we'd be if the Java updates were so majorly non-backwards compatible.

11:16 cemerick: AntonyBlakey: there's nothing keeping people from using 1.1-only libs, etc. Otherwise, it's like expecting Java 5 libs to work with Java 1.4 or something.

11:17 AntonyBlakey: No, it's expecting Java 1.4 libs to work with Java 5

11:17 Which they do.

11:17 As do Java 1.1, 1.2, 1.3 libs

11:17 cemerick: right, sorry

11:18 AntonyBlakey: IMO clojure-contrib is really part of the platform.

11:18 cemerick: AntonyBlakey: well, no, that's not at all true. It's a staging area for things that may become part of clojure proper.

11:18 In that role, things will change as people beat on libraries and vet them.

11:18 AntonyBlakey: That's disingenuous.

11:19 It's advertised on clojure.org, promoted

11:19 Who doesn't use it?

11:19 hiredman: <-

11:20 cemerick: (nearly) everyone uses it, but that doesn't mean that its API is guaranteed stable from here to forevermore.

11:21 AntonyBlakey: Given that nearly everyone uses it, don't you think that one *should* accept that fact, no matter what the intention of it is, and realise that non-backwards compatibility has the potential to act as an viral anchor to progress.

11:22 cemerick: AntonyBlakey: Depends on what one considers to be progress. How long would you like the 1.1 APIs to stick around?

11:22 hircus: AntonyBlakey: within a particular release, I agree that breaking compatibility is bad. but expecting perpetual forward compatibility leads to the Java trap. see how slowly the language evolves compared to C#

11:23 AntonyBlakey: Language evolution isn't held back by backwards compatibility in Java's case. It's a sociological factor - consider the 'closures are too hard for corporate programmers' argument.

11:24 cemerick: Forever, but maybe partitioned so that deprecated components can be packaged separately

11:24 cemerick: AntonyBlakey: That's crazy.

11:24 Contrib is not the standard library, as much as you'd like to think it is.

11:25 esj: dude - this is the bleeding edge

11:25 AntonyBlakey: There is no noticable transition from bleeding edge to 'business ready'.

11:26 cemerick: if it walks like a duck... then accept that you've built a duck.

11:26 cemerick: AntonyBlakey: True enough -- but if you want to use bleeding edge stuff, you have to be prepared to do some legwork on your own. e.g. forking libs that depend on 1.1 to work on 1.2 if you need to, etc.

11:27 AntonyBlakey: But the problem isn't that 1.2 is unstable, rather that the released 1.2 will be incompatible

11:27 hircus: AntonyBlakey: with closures, I agree. with tail call, I think there are worries about changing the Java bytecode format

11:28 AntonyBlakey: hircus: all political, not technical.

11:28 cemerick: AntonyBlakey: 1.2 clojure with be compatible with 1.2 contrib. That's the only guarantee that's provided.

11:28 AntonyBlakey: That limited guarantee isn't really suitable for commercial use.

11:28 cemerick: AntonyBlakey: Note the precedent at the bottom of http://github.com/richhickey/clojure-contrib

11:29 stuartsierra: The problem is that contrib had no controlling design. A bunch of people, myself included, used it as their personal idea pad.

11:29 cemerick: AntonyBlakey: who are you looking to for this rock-solid guarantee?

11:29 AntonyBlakey: I'm not looking to anyone.

11:30 I'm arguing a point from a commercial perspective.

11:30 cemerick: stuartsierra: Given the outcome, I wouldn't say that's a problem. :-)

11:30 The vast majority of it is rock-solid stuff.

11:30 stuartsierra: I disagree. It works, but most of it does not represent a consistent design philosophy.

11:30 AntonyBlakey: Even more reason that people treat it as a core part of the ecosystem.

11:31 stuartsierra: Keep in mind, Clojure itself is less than 3 years old.

11:31 AntonyBlakey: The Java libs don't have a consistent architectural philosophy

11:31 And that has remained backwards compatible from 1.0

11:32 With 4 books, growing evangelism, overtaking Scala on the JVM language list, IMO it's important to consider these longer term issues. And it;s not technically hard.

11:33 stuartsierra: But Java had the huge corporate infrastructure of Sun behind it. Clojure has one guy and a handful of volunteers, most of whom have never met.

11:33 Stability will come in time. No way to rush it.

11:34 AntonyBlakey: That's a poor excuse. Java had Gosling, we have Rich Hickey. The handful of volunteers *can* build something with backwards compatibility.

11:34 stuartsierra: Ok, go for it. :)

11:35 AntonyBlakey: Well, we are going for it aren't we?

11:35 And just look at the $ contributions. Java didn't inspire that.

11:36 cemerick: AntonyBlakey: The funding efforts have nothing to do with contrib.

11:36 rhickey: AntonyBlakey: I think it is important not to pour concrete on something so young

11:37 early adopters have to be somewhat tolerant of change, if not, better to wait

11:37 AntonyBlakey: It won't be used in commercial projects, which will generate more $ to fund more work if no-one cares about this issue.

11:37 cemerick: AntonyBlakey: Lots of commercial use out there. :-)

11:38 AntonyBlakey: And how many will upgrade to 1.2?

11:38 cemerick: AntonyBlakey: we've been using a 1.2-lineage build of clojure since before 1.1 was released. :-P

11:38 AntonyBlakey: If no-one wants to upgrade to 1.2 because it involves work (i.e. a budget) then people will start to care less about the future of the platform.

11:39 hircus: AntonyBlakey: given that 1.2 makes it much easier to generate named Java classes, probably a lot

11:39 AntonyBlakey: As am I, by copying bits of 1.1.0 contrib.

11:40 If every upgrade requires work, then managers will say 'why did you get us into this? - to use this new feature we have to go through all our code? Are you kidding me?"

11:40 cemerick: I heard once that "forced backwards compatibility places more value on the code that's been written to date than all of the code that will be written in the future", or something to that effect. I think that's a pretty compelling counter-argument to any thought of blindly maintaining compat for an indeterminate amount of time.

11:40 AntonyBlakey: This argument depends on the cost of maintaining backwards compatibility.

11:41 In my case, if some files had been left in contrib 1.2 then I wouldn't even be thinking of this.

11:42 Unless you are a corporate developer (and I'm not, although I consult to them) this issue doesn't seem so important.

11:44 brandonw: remleduff: thanks. i had thought it might be a for loop

11:44 remleduff: can you convert anything using a for loop to using a composite of simpler functions? if so, how would you do it with the 2d vector example?

11:45 rhickey: AntonyBlakey: I don't disagree that people could/should have been more considerate re: removals vs deprecations, using new namespaces and leaving old alone etc in contrib

11:45 AntonyBlakey: That's all I'm suggesting.

11:46 rhickey: more considerate != a commitment to compatibility though

11:47 AntonyBlakey: Well, I would have gone further and made that commitment. I think it's not dificult given that much of contrib is wrappers around Java.

11:48 Could have been zero cost.

11:49 cemerick: AntonyBlakey: That's incredibly unfair to the people that have done the work. The debate around argument order in c.c.string alone was enough to make it not "just a wrapper".

11:49 rhickey: AntonyBlakey: submit a CA, restore the files, do an analysis of what's changed etc. Zero cost

11:49 AntonyBlakey: I didn't say 'just'.

11:50 rhickey: zero cost to not do it, not zero cost to undoit.

11:50 rhickey: you've got to be in it to win it

11:50 AntonyBlakey: cemerick: but I take your point about the importance of those design decisions.

11:51 rhickey: I

11:51 I'd rather sell more and donate more

11:52 rhickey: contrib is unfunded - you could probably sponsor someone to advance your changes

11:52 AntonyBlakey: cemerick: but to use string as an example. str-utils could have stayed.

11:53 cemerick: AntonyBlakey: Again, I ask, for how long? Should we be carrying around duck-streams in 5, 10 years?

11:53 AntonyBlakey: Why not. Why not 100 years to use a limit-analysis. What is the cost.

11:54 cemerick: For one, I don't want to have to point people away from it in irc for the rest of my career :-)

11:54 AntonyBlakey: Java carries AWT.

11:54 rhickey: AntonyBlakey: a lot of cruft in the way of people looking to use the correct latest stuff

11:54 AntonyBlakey: Deprecation warnings in compiler output would help.

11:54 Couldn't that be solved via packaging and documentation?

11:55 i.e. default docs don't show deprecated stuff.

11:55 but you can turn on deprecation back to a release point?

11:55 rhickey: AntonyBlakey: but contrib is essentially an experimentation area, no need to keep every failed experiment running

11:55 AntonyBlakey: (while viewing docs that is)

11:55 chouser: I did some reading on how python does configurable deprecation warnings. There's a lot of value there, but also a lot of complexity.

11:56 cemerick: yikes, now we're hiding docs on code that we'd like to rm anyway

11:56 AntonyBlakey: I've already made the argument that regardless of intention, contrib is used by nearly everyone as a core piece of kit.

11:56 chouser: anyone able to help with my SAX question? http://gist.github.com/371105

11:57 google and javadoc are both failing me so far.

11:57 AntonyBlakey: cemerick: no, your documentation reflects the version history of the API.

11:57 cemerick: chouser: I only see "foo". You must be getting a different sax impl.

11:57 stuartsierra: chouser: Do you have a non-standard parser JAR like tag-soup?

11:58 cemerick: yeah, tag-soup would explain the added html goo.

11:58 chouser: the existence of a jar could change the behavior of this code!?

11:58 cemerick: yup

11:58 AntonyBlakey: yes, it's part of the metainf in the jar

11:58 chouser: ugh

11:58 cemerick: SAXParserFactory looks up SAX impls in the classpath.

11:58 AntonyBlakey: auto-registration/discovery

11:59 chouser: so .. I need to check my classpath for ... jars that might include ... what?

11:59 cemerick: or, actually, in the jars on the bootclasspath, I think

11:59 chouser: or can I specify something to pin down the implementation it uses?

12:00 stuartsierra: chouser: I think you can specify, but I don't know how.

12:00 AntonyBlakey: Use the javax.xml.parsers.SAXParserFactory system property

12:00 cemerick: chouser: you can set the javax.xml.parsers.SAXParserFactory system property to the classname of the impl you want to use I think.

12:00 AntonyBlakey: Use the properties file "lib/jaxp.properties" in the JRE directory

12:00 chouser: :-(

12:01 cemerick: chouser: it might be easier to figure out which rogue jar is causing the issue.

12:01 AntonyBlakey: javadocs: Setting the jaxp.debug system property will cause this method to print a lot of debug messages

12:01 (that's the newInstance method)

12:01 chouser: I'd never considered the possiblity that adding a class to the classpath might break existing code. This seems really awful. Am I being unreasonable?

12:02 arohner: chouser: no

12:02 AntonyBlakey: If it is tag-soup, it shouldn't be registering itself. That's bad form.

12:02 IMHO

12:02 arohner: the GNU XML parser does it too

12:02 chouser: ok, I think I've found appropriate docs now. Thanks for the pointers, guys.

12:03 AntonyBlakey: It's not a class by the way, it's in the jar's meta-info

12:04 chouser: ,(class (javax.xml.parsers.SAXParserFactory/newInstance))

12:04 clojurebot: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl

12:04 chouser: ok, mine says org.apache.xerces.jaxp.SAXParserFactoryImpl

12:05 cemerick: chouser: so does mine, interestingly

12:05 AntonyBlakey: That's compliant, doesn't explain the html wrappers

12:06 chouser: well, if I use (com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl.) instead of (javax.xml.parsers.SAXParserFactory/newInstance), I get correct results

12:09 so considering the evil that has been brought upon me, how bad is it to use a specific Impl class name like that?

12:10 cemerick: chouser: different JDKs may not have that impl available

12:10 the same JDK on another platform may not have that impl available

12:10 chouser: yeah, I probably have other dependecies on the sun jvm.

12:10 oh.

12:10 *sigh*

12:11 cemerick: it's funny how the pain pre-JAXP has just been shifted around

12:11 though fewer people feel pain under the new regime, presumably

12:11 chouser: there's nothing stopping you from declaring a direct dependency on your XML parser of choice

12:13 chouser: Specifying via (System/setProperty "javax.xml.parsers.SAXParserFactory" ...) fails no less spectacularly if the class doesn't exist.

12:17 AntonyBlakey: You might be able to find out where the parser is coming from by using .getClassLoader on the class.

12:17 Then you could re-order your jars

12:17 chouser: that seems so fragile

12:18 AntonyBlakey: I've used Xerces *a lot* and never seen that problem you're having. It doesn't seem configurable via a SAX property either.

12:19 chouser: I mean depending on the jar order seems fragile.

12:19 AntonyBlakey: I know

12:19 chouser: this problem could show up again later after some "innocent" change

12:19 AntonyBlakey: You could fix it by explicitly including a SAXParser implementation and then referencing that.

12:20 That's bloat, but it's not fragile.

12:20 chouser: I think for now I'd rather name the class explicitly and put a comment there. That way when it breaks, it'll be clear why (the class I'm trying to use doesn't exist)

12:24 AntonyBlakey: chouser: this might be worth checking: https://svn.apache.org/repos/asf/xerces/java/tags/Xerces-J_2_6_2/samples/xni/xerces.properties - check what the value of that property is, maybe change it to stop the html interpretation. If you can be bothered with this crap :)

12:26 chouser: AntonyBlakey: hm, thanks -- that might be sufficient for now.

12:28 remleduff: In a map call, how do you get the index of the element being looked at? So (map #(pr <index> %) '[a b c]) -> 0 a 1 b 2 c

12:30 noidi: remleduff, http://richhickey.github.com/clojure-contrib/seq-api.html#clojure.contrib.seq/indexed

12:30 opqdonut: ,(map #(prn % %) '[a b c] (iterate inc 0))

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

12:31 opqdonut: ,(map #(prn % %) [:a :b :c] (iterate inc 0))

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

12:31 noidi: ,(use '[clojure.contrib.seq :only [indexed]])

12:31 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/seq__init.class or clojure/contrib/seq.clj on classpath:

12:31 chouser: opqdonut: not quite, but close

12:31 opqdonut: ,(map #(prn %1 %2) [:a :b :c] (iterate inc 0))

12:31 clojurebot: (nil nil nil)

12:31 opqdonut: my bad

12:31 noidi: ,(use '[clojure.contrib.seq-utils :only [indexed]])

12:31 clojurebot: nil

12:31 chouser: ,(map prn [:a :b :c] (iterate inc 0))

12:31 clojurebot: (nil nil nil)

12:31 opqdonut: and anyway, prn isn't that nice :D

12:31 chouser: ,(map vector [:a :b :c] (iterate inc 0))

12:31 clojurebot: ([:a 0] [:b 1] [:c 2])

12:31 opqdonut: yeh

12:31 noidi: (indexed [:a :b :c])

12:31 ,(indexed [:a :b :c])

12:31 clojurebot: ([0 :a] [1 :b] [2 :c])

12:32 remleduff: Thanks

12:36 jlb: Anyone doing RESTful things w/ compojure or ring? Is there a "right" way to read the POST/PUT body?

12:38 remleduff: jlb: I'm trying at the moment: http://github.com/remleduff/MCMS, take a look and let me know if you think it looks "right" ;)

12:39 jlb: remleduff: will do!

12:42 cemerick: jlb: there's multipart middleware...

12:44 jlb: cemerick: I need to read in a JSON object... ideally I would read the InputStream from the servlet into a string and hand that off to clojure-json, or something along those lines.

12:46 cemerick: jlb: well, you can get the InputStream on a PUT from the servlet request. And post parameters are just strings (as opposed to binary portions of multipart requests).

12:46 carkh: i don' know about compojure 4, but until recently, the GET and POST macros would produce a function looking like this : (fn [request] your-code)

12:47 so i guess you have access to the request object

12:47 cemerick: right

12:47 carkh: and the request objzect has a body parameter

12:47 cemerick: so (-> request :params :your-parameter json/read-str) (or whatever the name of the json parsing fn is)

12:48 carkh: he'(s talking about accessing the body of the request asd opposed to a parameter

12:48 jlb: cemerick: there won't be form parameters... there would be if it was a browser submitting a urlencoded form

12:49 cemerick: jlb: my bad; was assuming the common case :-)

12:49 jlb: carkh: right, I probably just need a function that sucks an InputStream into a string... maybe there's something in duck-streams?

12:49 cemerick: slurp*

12:50 Raynes: slu... I hate you.

12:50 :(

12:50 carkh: second i'm reading the source

12:51 remleduff: Is there a way to make a request like that asynchronously, that doesn't involve javascript?

12:53 carkh: jlb : so in your GET POST PUT forms, you have access to the request variable, it has a :body field

12:53 which is already a stream

12:54 this is for compojure 0.2 ... which is the one i'm still using

12:55 actually i throw the whole "ring" stuff away and did my own routing, to many macros in compojure for my taste =P

12:57 jlb: carkh: ring 0.2 has :body in the request which returns the InputStream

12:57 carkh: axactly

12:57 exactly*

12:57 god my typing is terrible today =/

12:58 jlb: cemerick: slurp wants a filename... would be nice if it wrapped a function which just wants an input stream... but anyway, I can use StringBuilder the same way it does. thanks!

12:59 carkh: you don't need slurp ...wrap the inputstream in a stream reader

12:59 and you're all set

13:01 cemerick: jlb: not slurp, clojure.contrib.io/slurp* (or c.c.duck-streams/slurp*); it takes its argument and returns a Reader.

13:01 accepts strings as paths, files, urls, InputStreams, etc.

13:02 hiredman: 1d2

13:02 clojurebot: 1

13:02 chouser: 2r1

13:02 ,2r1

13:02 clojurebot: 1

13:03 remleduff: pKb4

13:03 hiredman: needed a coin toss

13:03 remleduff: I thought it was a chess game :(

13:04 hiredman: it's dice rolls, 1d2 is a two sided dice, or a coin

13:05 Raynes: $coin

13:05 sexpbot: Raynes: Tails.

13:05 jlb: cemerick: perfect, thanks!

13:05 hiredman: 2d6

13:05 clojurebot: 6

13:05 remleduff: 2d7

13:05 clojurebot: 6

13:05 remleduff: That would be an odd-looking die

13:06 cemerick: jlb: er, actually, slurp* returns the string, you want duck-streams/reader if you're looking for a Reader return

13:08 hiredman: remleduff: what you do for odd sided dice is double the number of sides then pair up the numbers

15:00 tomoj: so, if I'm using (polyglot) maven, should I lay out my clj source files differently than with lein?

15:00 src/main/clojure/foo/bar.clj or something? :(

15:02 bsteuber: tomoj: yes, this is the maven default

15:02 tomoj: thanks

15:02 bsteuber: you can customize paths if you want to stay lein-compatible, though

15:02 tomoj: meh

15:03 I'm just bothered by more cd'ing, but not enough to do extra work

15:03 bsteuber: :)

15:17 AWizzArd: I just saw that rhickey "committed #e660e46778: new perf for protocols". When he says "perf" which of these 18 abbreviations did he use? http://www.abbreviations.com/PERF

15:17 stuartsierra: performance, I expect

15:17 AWizzArd: I thougt so, but wasn’t sure.

15:18 tomoj: hmm, anyone happen to know what to replace 'lein uberjar' with when using maven?

15:19 remleduff: maven-assembly-plugin, blood, sweat and tears

15:19 tomoj: ah, thanks

15:20 elarson: coming from python and not being well versed in java, I was wondering if there is more interop with a lein package and running the development server

15:21 sorry, this is a compojure question btw

15:21 * elarson might be in the wrong channel for that...

15:21 cemerick: elarson: there's a #compojure channel, but it's lightly used

15:21 what do you mean by interop?

15:21 elarson: just noticed that in fact

15:21 AWizzArd: à propos compojure.. that drastically changed

15:21 where is compojure.encoding gone?

15:22 cemerick: virtually all of compojure is in ring now AFAIK

15:22 elarson: cemerick: well I saw lein let you run tests (at least I think it did) and didn't know if you could also do things like lein server and define how start up your app

15:22 AWizzArd: I hope I can convince the author to offer a .zip file for download.

15:23 cemerick: elarson: I believe that would require writing a lein plugin at this point.

15:23 AWizzArd: Now Compojure depends on Lein, which means I will need maven too and access to the net when I want to build it. Before it was easy, just download a .zip from github, locally ant it, done. (okay, downloading the deps too)

15:23 elarson: I see

15:24 cemerick: elarson: There may already be one. I think there's a #lein channel as well. You're looking to run integration tests, etc.?

15:24 AWizzArd: cemerick: did much else change too? Or just some namespaces renamed? Because it seems tomorrow I will have to adpot my server code to use this new Compojure (that is, after I found someone to build it *lol*)

15:24 elarson: conceptually it all makes tons of sense to me as it feels pretty much like python, but then the whole java side fo things throws me for a loop

15:25 cemerick: AWizzArd: I know next to nothing about 0.4.0. I'm sticking with 0.3.x for some time.

15:25 AWizzArd: cemerick: does 0.3.x already support Clojure (and Contrib) 1.2 with defrecord?

15:25 cemerick: AWizzArd: Not "officially". There are a couple of forks on github that do, though (including mine).

15:26 elarson: cemerick: I'm no where close to doing anything fancy with lein or clojure at all, just learning and since I'm coming from web dev with python, I figured compojure might be a good avenue to learn clojure

15:26 cemerick: elarson: it is.

15:26 elarson: maybe I should try 0.3.x

15:27 tomoj: every compojure example I've seen wasn't good for me :/

15:27 xeqi: AWizzArd: http://groups.google.com/group/compojure/browse_thread/thread/4da66a70254671a3

15:27 cemerick: elarson: FWIW, if you're used to deploying eggs and such, you should find .war deployment straightforward. The benefit to that is that you get drop-in compatibility with essentially any java webapp container.

15:27 xeqi: discusses some changes from 3.2->4.0

15:28 elarson: cemerick: yeah, my impression from .war is that it is pretty different from eggs in so far as there isn't really a python web app system that lets you point it at a module

15:29 cemerick: right, I was just relating to the notion of packaged deployment units

15:29 elarson: mainly b/c there is no main() to assume

15:29 technomancy: I would be suprised if nobody's put together a plugin for launching compojure apps yet

15:29 elarson: yeah that makes sense

15:30 technomancy: my path of thinking is relating it to something like paver or paste where you have one application to help do most dev/build sorts of things for an app

15:30 technomancy: not sure what those are, but it sounds about right

15:31 tomoj: maven doesn't download deps into lib/ like leiningen, I guess? :(

15:32 technomancy: tomoj: you can get it to do that with mvn dependencies:copy-dependencies

15:32 or rather dependency:copy-dependencies

15:32 remleduff: Nope, maven deps are in ~/.m2/repository/<deep directory structure> by default

15:32 technomancy: some mix of singular and plural

15:32 tomoj: technomancy: ah, thanks

15:32 elarson: technomancy: like rake in the ruby world

15:32 technomancy: tomoj: that'll toss them in target/dependency; not sure how to get them in lib/

15:32 tomoj: hrmm

15:32 technomancy: but M-x swank-clojure-project will find them either way

15:32 * elarson noticed technomancy's ruby focus on his site last night

15:32 tomoj: I'm beginning to think I'm doing something wrong

15:32 technomancy: elarson: rake does a lot less than leiningen

15:33 lein is more like rake+hoe+gem

15:33 tomoj: trying to take the solr example and plug clojure into it by replacing the main class of start.jar with something that launches a swank server

15:34 remleduff: I think something like mvn dependency:copy-dependencies -DoutputDirectory=lib

15:34 cemerick: If I may ask: why would you want dependencies in lib to begin with?

15:34 tomoj: solr will be looking for them there

15:35 cemerick: ah, it's probably got an ant build system?

15:35 tomoj: hmm, well, I think I can probably tell it to look wherever

15:36 not actually building solr, it's just the standard example puts deps and plugins in lib/

15:37 I wish #solr was as helpful as #clojure :)

15:38 elarson: technomancy: yeah, I just meant paste/paver both are like rake + other command line tools that do things like scaffold and run tests

15:38 of course since lein is dfferent then that is helpful for me to know that :)

15:39 cemerick: one of these days, I'll finish my clojure and compojure maven archetypes :-/

15:40 tomoj: maybe it's time to break down and finally learn maven

15:48 sattvik: tomoj: What is it you are trying to do with Solr?

16:00 reburg: can anyone help me with building enclojure from source?

16:04 it looks like it's trying to download itself as the first step in building...

16:05 AWizzArd: Did you try it in #Enclojure already?

16:05 reburg: AWizzArd: i did not know, or think to look, for #enclojure. thanks.

16:06 AWizzArd: reburg: often Eric sits around in that channel.

16:19 tomoj: sattvik: I want to write clojure plugins for it

16:19 and I want a repl so I can develop those plugins

16:20 and then I want to deploy it just like you normally solr, by 'java -jar start.jar' which kicks of jetty to find webapps/solr.war

16:20 or, deploy it some other cool way with maven, maybe

16:20 hey yeah, maybe I can use maven to deploy it, since it's just a war and start.jar just starts jetty

16:21 hurrah

16:25 sattvik: tomoj: You shouldn't need maven to deploy solr.war, unless you want to deploy it into some other server. Solr itself is built with Ant. You could try programmatically deploying Jetty in a clojure app, or use Embedded Solr.

16:26 tomoj: embedded solr isn't an option

16:26 since the solr needs to act just like a regular old http solar

16:26 deploying solr using jetty directly from clojure sounds interesting

16:26 that's what I would have done for a compojure app

16:27 but for some reason I didn't think it was an option for solr

16:28 I'm using maven anyway, though, so hmm

16:28 and it says it can auto-detect changes and redeploy solr

16:28 (the maven jetty plugin, I mean)

16:29 sattvik: tomoj: Pretty much everything that is in jetty.xml can be done programmatically. There's an example burried in 'http://www.deepbluelambda.org/programming/clojure/generate-your-class-and-proxy-it-too', look for the section 'Using the proxy with Jetty 7'.

16:30 tomoj: Although, once you have Jetty with Solr started with a REPL, unless you are adding/removing methods that require AOT recompilation, you shouldn't need to redeploy.

16:31 tomoj: sattvik: good point

16:32 sattvik: You can always redefine, add, and remove Clojure functions on the fly. That's one of the cool things about Clojure: no more edit/build/redeploy/test cycles.

16:32 tomoj: I noticed that compojure apps dealt with changes loaded by swank just fine

16:33 sattvik: thanks very much

16:34 sattvik: tomoj: No problem. I've been working on a project using Solr, though I have not yet tried to extend it. I've only been using it as a client.

16:35 tomoj: I was, up till now

16:35 did you write a client library?

16:35 I started on one but am going to start from scratch now

16:35 the stuff I did was awesomely simple

16:36 https://gist.github.com/addee4abcf949e445093

16:36 that's my solr wrapper

16:37 sattvik: tomoj: Yes, I started writing one. I've been considering publishing it even though it's far from being a complete Solr client. Right now it only helps with submitting queries and extracting the results into maps using clojure keywords as keys. It also has some highlighting support.

16:37 kylesmith: http://paste.lisp.org/display/98012 Could someone take a look at this? The c vector isn't being calculated correctly.

16:38 tomoj: highlighting?

16:39 sattvik: tomoj: Well, when you perform a query with term highlighting on, I have a method that helps extract that information into nested maps. My current application needs to highlight search terms in the results.

16:39 tomoj: I am imagining a project called 'parasol' that has a client library you can depend on in your project, and an example repo you can check out which has stuff set up for deployment

16:40 oh, I don't know anything about term highlighting yet

16:40 I've just done stuffing docs into the index and getting basic search results through json over http

16:41 if the clojure code is in the same jvm as solr, I bet you can do better than json over http, right?

16:41 sattvik: tomoj: If my client decides to move forward with this project, then I will finish writing my library to include support for doing things like faceting and the like.

16:41 tomoj: Well, even if it's in a different JVM, you can wrap SolrJ (which is what I did), which supports a more efficient binary stream.

16:42 tomoj: oh, cool

16:43 I thought solrj was only for when you didn't want the http interface at all

16:43 i.e. no http-accessible solr running at all

16:44 remleduff: kylesmith: Does it make any difference if you use StrictMath instead of Math?

16:44 tomoj: if I start jetty from clojure like those gen-class/proxy examples, I should wrap SolrJ to interact with the contained solr?

16:45 remleduff: I wouldn't expect that big a difference from using Math instead of StrictMath though, so probably not

16:45 sattvik: No, SolrJ supports both Embedded and regular Solr servers. Once you have a server object, it's completely transparent. My library supports both, as I use the separate Solr in development, but I use an embedded Solr in a memory-constrained environment.

16:46 kylesmith: remleduff: I don't know, let me try it.

16:46 sattvik: tomoj: It should be fairly simple, give me chance to check the docs. I am pretty sure that the WebAppContext has some sort of (.setWar …) method.

16:48 kylesmith: remleduff: Nope, it's still wrong with StrictMath

16:48 sattvik: tomoj: Yes, I think you can just (.setWar "/path/to/solr.war"), and it should do most everything else automatically. Check out http://wiki.eclipse.org/Jetty/Tutorial/Embedding_Jetty#Web_Application_Context

16:48 tomoj: sattvik: and the embedded solr can act like a normal solr, accessible by http?

16:49 kylesmith: remleduff: Interestingly, the formula for volume on the wikipedia page and the formula in reference 4 are slightly different.

16:49 sattvik: tomoj: I don't think so. The normal Solr depends on being in a web app to be accessible by http. That's not to say you couldn't deploy a Compojure app to the same Jetty server, though.

16:50 tomoj: I don't need to deploy a compojure app as well

16:50 kylesmith: remleduff: I've tried both ways, and the answer is still exactly right half the time, and wrong half the time.

16:51 remleduff: Hmm, weird

16:51 tomoj: I just want to have my clojure stuff accessible as solr plugins, and have a running solr which other components can access over the standard http interface

16:52 remleduff: Why do you constraint alpha beta gamma to pi/2, shouldn't they be able to be a full 180 degrees? Not that that would solve your problem either

16:53 sattvik: Well, you can try either maven-jetty or my embedded Jetty route. The main thing is to get that instance to support a REPL or interact with your editor. I can't really help you with the Emacs side of thing.

16:53 tomoj: no problem with the emacs side

16:55 cemerick: +1 for maven-jetty-plugin. I've found embedded jetty to be more of a pain than it's worth, except in actual embedded use cases.

16:56 sattvik: cemerick: Last time I used maven, I did a 'maven clean'. The result? It downloaded dozens of Jars to my machine. Maven has a rather peculiar understanding of 'clean'.

16:57 kylesmith: remleduff: the sum of all angles must be <= 360 degrees. I'm not entirely sure I have the correct angles constrained, but that shouldn't cause problems.

16:57 sattvik: I meant 'mvn clean' not 'maven clean'.

16:57 tomoj: well, it doesn't download them into the project, does it?


16:58 stuartsierra: sattvik: mvn clean means delete generated files in the current project

16:58 tomoj: just into your local maven repo so that maven can function

16:58 cemerick: tomoj: no, it downloaded the plugins necessary to support the phase he invoked

16:58 tomoj: yeah, but where did it put them?

16:58 cemerick: into ~/.m2/repository, as you'd expect

16:58 tomoj: isn't that what I said?

16:59 cemerick: yeah, sorry, I hit return before I saw your msg

16:59 tomoj: oh, I get it

16:59 sattvik: Yes, I it was downloading it into the repository, but it was just so counterintuitive that it needed so many jars just to deleete a few files.

16:59 tomoj: yeah, but, if it works :)

17:00 cemerick: sattvik: it's modularity, taken to its logical maxima.

17:00 stuartsierra: it doesn't, it automatically updates the standard plugins once a day

17:00 jlb: defrecord + AOT question... do I import or use? :) (at the moment, use seems to fail)

17:01 cemerick: import + use the defined ctor corresponding to the fields you specified

17:02 remleduff: kylesmith: Can you print out the values of the params when it's wrong?

17:03 Nevermind, right there isn't it

17:03 kylesmith: remleduff: I already do. The inputs are on the first line, and the outputs are on the second line.

17:03 remleduff: Yeah, I was being dumb, sorry

17:05 How is 3.0637036614407926 between 0 and pi/2 ?

17:07 jlb: cemerick: thanks

17:08 kylesmith: remleduff: Sorry, I actually had the constraints as pi2 pi and pi2 when I ran those repl examples. Regardless, it still doesn't work.

17:10 remleduff: I don't see how I could have a numerical instability with something this simple. I must have a problem somewhere in the math, probably in the calculation of the c vector.

17:10 tomoj: holy shit

17:10 google has already indexed your paste, kylesmith

17:11 remleduff: Yeah, sorry, I read through your math and didn't see a problem

17:11 kylesmith: lol

17:21 jlb: more dumb defrecord/deftype questions... what's the new/right constructor for a deftype? e.g. (deftype Foo [stuff] SomeProtocol ...)

17:21 how do I construct one now?

17:22 (I was using deftype prior to defrecord, now moving things in one direction or the other)

17:25 raek: hrm, seems like clojure-test-mode doesn't treat hyphens in namespace names correctly when using C-c t

17:26 in (ns foo.bar-quux), it looks for foo/test/bar-quux.clj and not foo/test/bar_quux.clj

17:27 jlb: Oh nevermind, I forgot to append a .

17:35 slyphon: how do i get the 'length' of a vector?

17:35 dakrone: ,(count [1 2 3])

17:35 clojurebot: 3

17:35 slyphon: gah

17:36 ty

17:36 dakrone: np

17:50 slyphon: is there ever a time where doall returns a lazy seq?

17:51 chouser: slyphon: it usually does.

17:51 ,(class (doall (range 5)))

17:51 clojurebot: clojure.lang.LazySeq

17:51 chouser: but it "realizes" it first

17:51 slyphon: oh

17:51 i thought it was supposed to return the realized seq

17:51 chouser: well, it does

17:52 slyphon: i mean, not wrapped in a lazy seq

17:53 i'm just trying to print out what's in the seq

17:53 chouser: a LazySeq doesn't change it's type when it becomes realized. Instead, each link in the chain switches from holding a thunk describing the link to holding the actual value of the link.

17:53 slyphon: ah

17:55 (printf "blah: %s\n" (vec s)) does basically what i want

17:55 (this is just for debugging purposes)

18:03 tomoj: where can I learn more about the polyglot maven clojure dsl?

18:03 e.g. how to translate <foo bar="baz"><bing>bang</bing></foo>

18:04 I wonder if automatic translation is possible

18:04 for clojure it seems more likely since we are homoiconic

18:07 chouser: slyphon: I'd expect (println "blah:" s) to work as well

18:26 tomoj: oh, I guess it's called jetty-maven-plugin now?

18:26 oh, no, I'm using jetty 6

18:28 cemerick: tomoj: transparent round-tripping of xml poms to/from non-XML pom dsl's is built in to polyglot maven

18:30 tomoj: oh, cool

18:30 unfortunately I don't have a real pom.xml handy

18:30 cemerick: there are some plugins that are incompatible with pmaven, but those are being fixed as they're found AFAIK

18:31 tomoj: I wonder if maven-jetty-plugin is

18:32 cemerick: the ones that have trouble are the ones that expect concrete XML configuration, rather than targeting the object model

18:32 IIRC, the release plugin is the most prominent offender

18:41 tomoj: https://gist.github.com/64228e1c6998136348f7 https://gist.github.com/bfffbdf678274b07090f

18:42 I guess this means maven-jetty-plugin is incompatible

19:23 defn: good evening all

19:23 abedra: good evening

19:52 ndimiduk: i have a functional data structure kind of question.

19:52 i need to implement a priority queue with a maximum capacity

19:52 the imperative implementation is pretty straight forward. ugly, but straightforward

19:53 but i'm puzzling through a functional approach

19:54 i essentially have a list of lists, each of which contains ranked items. I need to reduce these items into a single list, the top N results, according to the ordering.

19:55 round-about way of asking: is there anything out there i should be building on top of? something in contrib perhaps?

20:02 tomoj: ndimiduk: http://www.eecs.usma.edu/webs/people/okasaki/pubs.html#jfp96

20:02 might be an interesting read

20:04 ndimiduk: oh, this is the "Purely Functional Data Structures" guy, right?

20:04 tomoj: yeah

20:07 slyphon: what's the best way to get [0..-2] from a vector?

20:08 oh, wait, i think i know

20:12 defn: slyphon: subvec?

20:13 slyphon: oh, i used (take (dec (count blah)) blah)

20:13 it's not necessarily a vector

20:13 defn: slyphon: did you mean to get literally [0 -1 -2]? or were you talking like indices?

20:13 slyphon: oh, i meant as a range

20:13 the zeroth to the penultimate items

20:14 * technomancy wishes you could count from the end with negative numbers

20:14 defn: yeah im kind of surprised you cant

20:14 slyphon: yeah, like every other dynamic language...

20:15 defn: i suppose you could just take the range and then map - across it

20:15 ,(map - (range 0 10))

20:15 clojurebot: (0 -1 -2 -3 -4 -5 -6 -7 -8 -9)

20:16 slyphon: no, like if i have an array of [\a \b \c \d \e] i wanted [\a \b \c \d]

20:16 defn: sorry, i was using the ruby syntax for describing a range

20:16 defn: ohhh, my bad

20:16 slyphon: ah yes i see that now -- im a former rubyist, technomany > me in that department as well

20:16 * defn shakes his fist at technomancy for being so damned prolific

20:17 slyphon: hahahaha

20:17 sattvik: ,(butlast [\a \b \c \d \e])

20:17 clojurebot: (\a \b \c \d)

20:17 defn: sattvik: neat

20:17 slyphon: heh heh, you said "but"

20:17 </beavis>

20:17 defn: huhuhuhuhuh

20:17 slyphon: :D

20:17 tomoj: ,(drop-last [\a \b \c \d \e])

20:17 clojurebot: (\a \b \c \d)

20:18 defn: so what's the difference between butlast and drop-last...

20:18 ah, one is lazy, one is not

20:18 i think you want drop-last

20:18 sattvik: drop-last is lazy, it also supports a count

20:18 ,(drop-last 2 [\a \b \c \d \e])

20:18 clojurebot: (\a \b \c)

20:18 sattvik: That's the one you want.

20:19 * defn high fives everyone

20:19 slyphon: :)

20:19 "We're terrific"

20:20 tomoj: ,(take 1 (butlast (lazy-cat [1 2 3] [(println "foo")])))

20:20 clojurebot: (1)

20:20 foo

20:20 slyphon: the one thing i find really difficult in this particular bit of code is porting the ruby pack/unpack method

20:20 tomoj: ,(take 1 (drop-last (lazy-cat [1 2 3] [(println "foo")])))

20:20 clojurebot: (1)

20:20 slyphon: b/c bit twiddling is something i don't do very often

20:22 defn: i dont even know pack/unpack

20:22 slyphon: it lets you do byte-level stuff

20:23 defn: oh slyphon -- i think i could help maybe, iirc just converting \c to an ASCII rep is something ive done -- is there something specific you're trying to do

20:23 slyphon: yeah, it's kind of involved

20:24 unfortunately, there's an obfuscation method we use that i'm trying to port to clojure

20:26 defn: i knew it!

20:26 slyphon: :)

20:26 defn: slyphon: i was thinking about why's chunky bacon

20:26 i think he used unpack in that

20:26 slyphon: it's not a very good obfuscation, then

20:26 oh yeah?

20:26 * slyphon wonders when _why is gonna grow up

20:27 defn: i wonder where the heck he went

20:27 slyphon: he probably got caught up making some deeply unfunny comic

20:27 defn: he was such a role model to me when i finally realized i wanted to do development professionally and forever

20:27 slyphon: hah

20:27 defn: i always felt like i was kind of the odd man out in the hacking community -- im sort of artsy and eccentric

20:28 slyphon: i always kind of wished he'd stop being such a clown

20:28 defn: studied music in college, etc.

20:28 slyphon: yeah, me too

20:28 defn: so it was nice to see "hey! im not alone! someone else who isn't a math major!"

20:28 slyphon: defn: heh, well, there are a lot of fuckups in the dev community

20:28 in fact, a lot of the CS majors i've met can't hack worth a shit

20:28 defn: oh? how do you mean?

20:29 oh....lol...dont get me started man

20:29 slyphon: i went to 4 colleges, studied mech engineering, psych, jazz, and then finally CS

20:29 defn: i do this for fun and i have a few friends who are CS majors and dont do anything outside of their school

20:29 slyphon: jazz! woo! what instrument?

20:29 slyphon: guitar & drums

20:29 i wasn't very good

20:29 :)

20:29 i can't play over changes

20:29 i'm a blues man

20:30 defn: i did guitar performance -- and i can play over giant steps

20:30 slyphon: see

20:30 i hate guys like you

20:30 ;)

20:30 * defn slaps you around with his chops

20:30 slyphon: :D

20:30 defn: haha -- but unfortunately ive fallen out of practice

20:30 slyphon: i can't deal with the earth moving under me

20:30 i'm like zappa, i need a vamp

20:30 defn: so now i pick up the guitar and noodle, but mostly im hacking

20:31 * slyphon nods

20:31 defn: slyphon: haha1

20:31 slyphon: and that's probably the closest similarity between myself and zappa

20:31 * slyphon can't touch that

20:31 defn: slyphon: you're cool. not that you need my approval, but well-- you're cool, man.

20:31 slyphon: hahahha

20:31 defn: :)

20:31 * slyphon bows

20:32 defn: now, get back to that obfuscation method port and quit messing around!

20:32 slyphon: hahaha

20:32 indeed!

20:35 cemerick: ndimiduk: unless it's a personal project, it's far better to use the priority queue in java.util.concurrent

20:37 ndimiduk: cemerick: and then externally enforce the limit count?

20:51 cemerick: ndimiduk: that, or depending on the nature of the usage, seque might be a good option

20:51 ndimiduk: theoretically, all of my items should be unique, so i'm looking into the sorted-set

21:16 cemerick: ndimiduk: did we bump into each other in #jclouds last week?

21:16 ndimiduk: cemerick: could be :)

21:16 cemerick: I was in PA harassing adrian on thursday

21:17 cemerick: I oddly have a hard time tracking people across channels.

21:17 chessguy: stupid question time. what's the idiomatic way to have an 'else' condition in a cond?

21:17 hiredman: :else

21:18 chessguy: thanks. i was gonna do true

21:18 ndimiduk: cemerick: same here. #jclouds or #cloudhackers, don't recall which

21:18 chessguy: ,(:else)

21:18 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :else

21:18 chessguy: ,:else

21:18 clojurebot: :else

21:19 hiredman: :else is not nil or false, so for clojure boolean logic it is true

21:20 cemerick: ,(boolean :any-keyword)

21:20 clojurebot: true

21:20 hiredman: anything not nil or false would work, but :else is idiomatic

21:24 chessguy: cool

21:25 working on a clojure-version of the general simplifier they built in the SICP video lectures, if anyone cares

21:43 boredomist: potentially stupid quick question: is the function some lazy? I feel like it should be, but just want to make sure

21:47 chouser: well, it consumes only as much of the input seq as needed to return a value, but it does it immediately.

21:50 boredomist: alright, thanks

22:03 chessguy: hrm. if i have two functions that recursively call each other, how do i write that down in clojure, without it complaining that the second one's not in scope?

22:05 hiredman: declare or letfn

22:05 chessguy: thanks, i knew it was something like that

22:41 jweiss: jsanda: can you hear me now

22:41 jsanda: yeah, thx

22:41 chessguy: is there an equivalent to mapcar in clojure?

22:43 danlarkin: just map

22:43 clojure is a lisp-1

22:43 chessguy: err, i'm not sure what that means

22:44 i know what map is, and i'm not grokking the difference between map and mapcar

22:44 slyphon: there is no mapcar in clojure

22:44 map applies a function to each element in a collection

22:44 and returns a collection of the results

22:45 chessguy: what's the difference between map and mapcar in a different lisp?

22:45 * slyphon shrugs

22:45 chessguy: (like i said, i know what map is)

22:45 slyphon: ok, so ask in #lisp ?

22:45 * slyphon is pretty sure sbcl has mapcar

22:45 chessguy: oh, yeah, clearly lisp is off-topic in here....

22:46 slyphon: i'm just sayin' they might know the answer

22:49 hiredman: http://lispdoc.com/?q=mapcar vs. http://lispdoc.com/?q=map

22:51 chouser: I'm useless at CL. How do I get a reference to the + function?

22:51 oh, #'+ weird.

22:51 Raynes: I just noticed that my bot isn't scraping any links. o.o bugs, oh how I love my bugs.

22:51 slyphon: :)

22:52 gah

22:52 chouser: CL: (mapcar #'+ '(1 2 3) '(4 5 6)) ==> (5 7 9)

22:52 slyphon: oh, odd

22:53 Intensity: Hi. I'm using counterclockwise in Eclipse (both for the first time) in an existing Java project, and I'd like to get the Java code to call Clojure code. Is anyone acquainted with Eclipse and/or CCW enough to help me with this?

22:54 slyphon: damn

22:54 chouser: MAP in common lisp requires a "type specifier", which I know nothing about.

22:54 slyphon: no clojure-http-client in clojars?

22:54 booo!

22:54 carkh: slyphon: you want to use mapcar which it the same as clojure's map

22:54 slyphon: uhh

22:55 not me chessguy

22:55 carkh: map is for CL sequences

22:55 slyphon: sorry, there should have been a comma in there

22:56 chessguy: it's ok, i already ditched mapcar for map, like 10 minutes ago :)

22:56 chouser: CL: (map 'vector #'+ '(1 2 3) '(4 5 6)) ==> #(5 7 9)

22:57 carkh: where is our clbot !?

22:58 chouser: so, CL's MAPCAR is most like Clojure map, and CL's MAP has no Clojure equiv.

22:58 carkh: ,(into [] (map inc [1 2 3]))

22:58 clojurebot: [2 3 4]

22:58 carkh: that's our equivalent

22:59 (i guess)

22:59 Raynes: Alright. sexpbot should continue annoying people with titles now. <3

22:59 hiredman: ,((comp vec map) + (range 3) (range 3))

22:59 clojurebot: [0 2 4]

23:00 carkh: ah better =)

23:01 hiredman: ,(((partial partial apply) vector) '(1 2))

23:01 clojurebot: [1 2]

23:01 chouser: carkh: right

23:02 hiredman: wrong. so very very wrong.

23:02 ;-)

23:02 g'night!

23:02 hiredman: :)

23:13 Raynes: From walton's most recent commit: "... been brought up to date officially. I added a basic irc bot using raynes excellent irclj ..." <3 defn. :>

23:14 My IRC library: taking over the world, one basic waltonbot at a time.

23:14 eyeris: I am getting started with lein. The lein repl command used to work. Then I wanted to incorporate some java source, so I made src/clj and src/java and the added :source-path "src/clj/" to project.clj and now when I use the lein repl command, a subsequent (use 'my-namespace) fails with a NO_SOURCE_FILE err

23:31 Does anyone here have leiningen working with a custom :source-path value?

23:33 dnolen: eyeris: I believe this may be resolved on master, but I think still affects lein 1.1.0

23:35 eyeris: I just downloaded the lein script from master

23:35 It says it's only for developing lein itself

23:36 "Leiningen is a build tool for Clojure designed to not set your hair on fire."

23:36 Total failure to live up to that, I must say

Logging service provided by n01se.net