#clojure log - Sep 24 2010

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

0:07 technomancy: grrr... using ant as a library is like building a castle out of sand

0:07 ninjudd: tell me about it

0:08 technomancy: apparently it just plain ignores the spawn option on the subprocess launching

0:08 ninjudd: which task? Javac.

0:08 technomancy: "Look ant, I need you to fork a subprocess that outlasts the parent." / "Cool story bro. Listen, I'm gonna do my own thing over here..."

0:08 just plain Java

0:10 ninjudd: hmm

0:11 isn't that what you use to fork your project jvm?

0:11 technomancy: well normally I don't want the forked process to outlast the parent

0:12 but I realized it wouldn't be hard to have it start a background server

0:12 err--it wouldn't be hard if ant behaved as advertised

0:12 ninjudd: are you writing a persistent jvm.

0:13 technomancy: I'm expanding the repl server to work in the background

0:13 I guess so?

0:13 ninjudd: you have fork=true and spawn=true, right?

0:13 technomancy: right

0:13 but the parent JVM just quits and takes the child with it

0:14 ninjudd: and you aren't using any of the other opts that aren't compatible with spawn?

0:15 technomancy: right; I had failOnError set, but I turned that off when it complained

0:16 ninjudd: i could swear I got that working before I decided to launch both jvms from ruby

0:17 technomancy: maybe it's fixed in a newer ant

0:17 Bahman: Hi all!

0:17 ninjudd: perhaps. docs say it doesn't work with input, output, error, result and timeout...

0:21 could you use Runtime.exec directly?

0:22 technomancy: according to the ant mailing list they had to work around a hell of a lot of edge cases in Runtime.exec

0:23 of course, apparently they missed at least one

0:23 ninjudd: hehe

0:24 I use ant 1.8.1. you may want to try that

0:27 technomancy: oh, I thought 1.7.1 was the latest... will try that

0:28 ninjudd: I think there is 1.8.2

0:28 not sure why I'm not using it though

0:34 TheBusby: I've actually had a lot of trouble with Java process spawning recently. Final solution ended up being using JNI.

0:56 technomancy: at least with smalltalk you could forgive it for pretending like Unix didn't exist because it was so old

0:57 that excuse really doesn't work for the JVM

1:04 sandGorgon: hi guys... wanted to prototype a document store like functionality in clojure. basically a clojure server would be running on a remote machine, I request for a (guaranteed) unique filename and it returns a one-time URL that I can retrieve the files from. Later I'm gonna bolt on authentication and all that stuff

1:04 I'm confused on the first step - to build the clojure "server" would I have to use a web framework like compojure ?

1:06 amalloy: sandGorgon: i'm not an expert here (so don't take my advice!), but you certainly don't have to. if you wanted, you could instantiate the java.net.ServerSocket yourself

1:07 sandGorgon: amalloy, true - I was kinda hoping one layer of abstraction above it. my first thought was compojure, then I thought of ring, now I'm thinking of something using Aleph/Netty. But wanted to get idead

1:07 s/idead/ideas/

1:07 sexpbot: <sandGorgon> amalloy, true - I was kinda hoping one layer of abstraction above it. my first thought was compojure, then I thought of ring, now I'm thinking of something using Aleph/Netty. But wanted to get ideas

1:09 amalloy: somewhere around here i have a copy of my first clojure program, which was a simple chat server. compojure or ring or something is almost certainly better, but i don't have experience with any of them

1:09 TheBusby: technomancy: I fought with the JVM's processing spawning for quite a bit before going JNI. The worst part is what works for one platform doesn't work for another, hence the JNI route...

1:10 technomancy: TheBusby: yeah... honestly I only bothered because it looked like it would be really easy

1:11 I'm not sure it's worth the hassle at this point just to be able to do TDD outside swank

1:11 sandGorgon: amalloy, actually the reason why it might be a bit different is that it might well be a multi-gigabyte file. So you dont want to drop down to socket level and have to deal with fillng up of posix buffers and all that.

1:11 technomancy: maybe someone who doesn't use swank could implement it. =)

1:13 TheBusby: I think it took me about 20 minutes to implement what I needed, but I had some skeleton code (using fork and execvp) to work with.

1:15 amalloy: github gist

1:15 argh. wrong window :P

1:18 sandGorgon: anyway http://gist.github.com/594895 if you want to use it as a comparison vs ring or some other tool

1:19 sandGorgon: amalloy, hey thanks!!

1:20 technomancy: (re-pattern (format "(?:^|/)%s/" pat)) <= what's all that punctuation about?

1:23 amalloy: technomancy: ^ indicates start of line, and / is a literal. they're separated by |, which is OR; those are wrapped in (?:) to get proper grouping - the ?: prevents it from stomping on your capturing groups

1:24 technomancy: amalloy: ah, thanks. I hadn't seen ?: before; handy.

1:24 amalloy: so it looks to be matching "foo/" or "anything/foo", but not "myfoo"

1:25 nroot7: clojure documentation mentions many functions to be side effect free. How does the compiler verify that ? Is it just a convention ?

1:25 amalloy: technomancy: http://www.regular-expressions.info/tutorial.html is a superb resource for learning both basics and nuances, if you're getting into a lot of regexes

1:25 nroot7: just convention. the compiler has no idea

1:25 sandGorgon: amalloy, ah.. I was thinking that the ? was for a non-greedy match

1:27 amalloy: heh. ? means about a hundred things depending on where in the regex it is

2:07 Bahman: Hi all!

3:07 LauJensen: Good morning all

3:10 amalloy: silly europeans, claiming it's morning

3:12 LauJensen: clojurebot: UGT?

3:12 clojurebot: ugt is Universal Greeting Time: http://www.total-knowledge.com/~ilya/mips/ugt.html

3:12 LauJensen: silly uneducated americans, thinking I was referring to time

3:14 nlogax: also, there's no timezone exclusive to europe

3:24 Raynes: It's morning in the USA.

3:24 At least, my clock says AM.

5:18 fliebel: morning

5:18 mrBliss: morning fliebel

5:19 fliebel: What is the usual path to follow when lein deps is missing something?

5:19 (junit 4.7 in this case I believe)

5:20 mrBliss: make sure your dependency vector is correct: http://jarvana.com/jarvana/archive-details/junit/junit/4.7/junit-4.7.jar

5:22 fliebel: It's not exactly my vector, rather the Overtone one. And even then, it is a dependency of a dependency, because Overtone itself does not depend on junit.

5:23 mrBliss: fliebel: good luck :)

5:24 fliebel: mrBliss: Thanks :( I guess I'll just ask on the Overtone mailing list, after I tried some more.

5:59 mrBliss: Deleting .m2 fixed it for some reason :-|

6:11 Hoornet: Hello

6:12 Raynes: Hi.

6:14 esj: wotcha

6:21 was it something I said ? :(

7:53 LauJensen: Anybody here living in London ?

7:58 mccraig: LauJensen: i work there

8:08 esj: I live up the way in Cambridge

8:13 LauJensen: esj: Im in priv with mccraig trying to extract some information :)

8:13 esj: All you need to know is that London is big and smell :)

8:14 LauJensen: I don't remember any specific smell, just that its huge and difficult to get around in

8:18 esj: yes, I served a two year term there, happily I am now paroled.

8:25 bobo_: is there any good tutorial on testing your java code with clojure? setting up the project and so on?

9:11 fliebel: Hey, what are naming conventions in Clojure? I figured out dashed-style is preferred and question-mark? is used for booleans, but how about *stars and -dashes?

9:12 esj: fliebel: I think *ear-muffs* are often for dynamic vars, and -dashes for private functions

9:13 fliebel: esj: -main has a dash, and in java that's public static void main IIRC.

9:13 chouser: never seen a leading star. trailing star is like a "prime tick" in math -- foo is something, foo* is related but different. sometimes a macro vs. a function that does something similar

9:13 fliebel: chouser: Yea, I meant things like fn*

9:13 chouser: yes, *ear-muffs* are for vars -- things that are meant to be rebound using (binding ...)

9:14 leading dash is for functions that are acting as methods for genclass. Note (defn- foo ...) is for a private foo which is different than (defn -foo ...) which is likely a public method of a class.

9:15 fliebel: yeah fn* is the real special operator, related to fn which is a macro

9:16 fliebel: okay… so, recap: *changable-var* low-level-stuff* -java-method bollean?

9:16 esj: -dashes.... yes I'm confusing myself with defn-. Apologies.

9:17 AndChat-: .

9:17 esj: or rather: predicate?

9:17 fliebel: esj: Yea, nicer word :)

9:17 chouser: I use ? for boolean locals too. I think that's ok.

9:18 as in (let [inside? (< low x high)] ... (if inside? ...))

9:18 fliebel: Talking about private functions, why would you want to do that? Except for keeping the ns clean and for "setters"

9:19 esj: chouser: cool.

9:21 chouser: fliebel: I think "ns clean" is too dismissive. A public API carries weight -- it should be clean yes but also documented, slow to change, conceptually aligned with how users are supposed to think about the problem space, free of implementation-specific details, etc.

9:21 private functions don't need to meet any of those criteria, so it's worth being clear about which is which.

9:22 fliebel: chouser: Right… I'll think about making my bad ass macro a bit more friendly.

9:22 chouser: note they're not even as private as Java private methods -- you can always get at a private var from another ns if you know its name.

9:22 actually, you can discover it's name easily too.

9:23 fliebel: chouser: I did that to Ring the other day… I needed something in their lower levels.

9:23 chouser: fliebel: right, good, and you're aware of the risks involved.

9:23 fliebel: chouser: Probably not… Only thing I can think of is that they change it becasue it's private anyway.

9:24 chouser: fliebel: right, that's it.

9:24 it's behavior, name, interface may change without notice

9:25 if you think your use of it is legit I'd recommend asking for it to be made public.

9:25 fliebel: I'm not using it anymore

9:26 My use was completely unrelated to Ring, it just happend to contain the exact thing I needed.

9:28 Huh, am I allowed to do this? (defn a [] (defn b []))

9:29 That'd mean I don't need to make a macro at all to define some crazy function.

9:30 I'm trying to do this badd ass macro in a proper way: http://github.com/pepijndevos/utterson/blob/develop/src/utterson/compile.clj#L55

9:34 lpetit: fliebel: I really don't understand your problem with (defn a [] (defn b [])) which could be solved by a macro.

9:34 can you repeat slowly for me please ? :-)

9:34 chouser: def-anything inside a fn is generally not a "proper way"

9:34 fliebel: lpetit: The point is that I though one wa supposed to use a macro for this, but evaluating that just yieald b

9:35 chouser: Right...

9:35 chouser: fliebel: you won't be able to give the name of 'b' from an argument of 'a'

9:35 lpetit: I can't see why (defn a [] (defn b [])) could be useful at all

9:35 fliebel: chouser: I also realized that...

9:35 chouser: you could try using intern, though.

9:36 fliebel: I'll just do it the normal way and break it up in fns and a macro for defining it.

9:36 chouser: (defn a [tname] (intern *ns* tname (fn ...)))

9:37 but .. looking at your defgen I doubt that'll work for you either.

9:39 fliebel: chouser: So what do you suggest, if anything?

9:43 I think I'll split it up in 3 functions and one macro

9:44 chouser: yeah, I'd try to have the macro emit as little code as possible.

9:45 pjstadig: ,36r16

9:45 clojurebot: 42

9:45 chouser: looks like it'll need markdown# to redefine your template# a couple times

9:45 pjstadig: 1r2

9:45 ,1r2

9:45 clojurebot: Radix out of range

9:45 pjstadig: ,3r16

9:45 clojurebot: For input string: "16"

9:45 pjstadig: :-(

9:46 ,2r1

9:46 clojurebot: 1

9:46 fliebel: chouser: Yea, I need to come up with a decent plan to spread the data to the right places across those fns

9:46 chouser: and maybe put your template of ~@others in a local fn.

9:46 pjstadig: hmm i guess the radix comes first?

9:47 ,3r12

9:47 clojurebot: 5

9:47 chouser: so then the body of the let you emit can just be (gen* markdown# template# othersfn#)

9:56 fliebel: chouser: Would it be good style to define some fo those functions in a lot, so they can access common data?

9:56 *let

9:57 chouser: fliebel: not sure exactly what you mean, but it doesn't sound bad. :-)

9:57 fliebel: chouser (let [common data] (defn a []) (defn b[]))

9:58 chouser: that'll only work if common data is entirely global

9:58 fliebel: true

10:08 * esj just discovered that if you don't put the a <resources> section in the right part of your pom.xml, when you package it up, there is no source code in the jar. Oops.

10:15 chouser: would it be dumb to have a pom.xml editor? perhaps an emacs mode or a little command-line utility that wraps up common configurations?

10:15 technomancy: lein includes a sexp->pom.xml translator, in essence

10:16 chouser: yeah, I guess I'm thinking something two-way

10:16 hugod: it would be great not to maintain seperate project.clj and pom files

10:16 chouser: in case you use an IDE to adjust the pom.xml or something.

10:16 technomancy: hugod: if you need something in pom.xml that project.clj currently doesn't support it should be easy to add

10:17 I've been thinking about adding a maven plugins section so you can do "lein pom && mvn myplugin:action" easily

10:17 chouser: lein is happy to depend on projects that provide pom.xml but not project.clj, right?

10:17 technomancy: chouser: definitely

10:18 once something is on clojars, project.clj is not even taken into account; the pom is the only thing that matters

10:18 hugod: technomancy: there is rather a lot I fear http://github.com/hugoduncan/pallet/blob/master/pom.xml

10:18 technomancy: hugod: eh; it wouldn't be too much work to add

10:19 hugod: technomancy: good to hear :)

10:19 technomancy: profiles, plugins, and developer lists; it's all just a matter of adding the appropriate .addProfile etc. calls to the maven java API

10:19 Raynes: My eyes!

10:20 technomancy: though I'm really not sure of the purpose of the latter

10:20 chouser: btw, lein cake and maven all feel less superfluous to me since I've started thinking of them as classpath management tools rather than "build" tools

10:21 hugod: technomancy: I tend to agree with you on that

10:21 chouser: superfluous isn't quite the right word

10:22 shoover: chouser: I'm curious how you manage dependencies without those tools. Do you download jars the old fashioned way and stash them somewhere?

10:23 Or write everything from scratch depending only on clojure.jar? ;)

10:23 chouser: shoover: essentially yes. Well, I've got two different "systems", neither very impressive.

10:23 technomancy: chouser: indeed; "building" a jar is the trivial part

10:23 classpath management is the #1 faq for newbies coming in

10:24 chouser: for work we already have an extensive build system using cmake (do not recommend), so I plugged clojure into that. The generated makefiles fetch dependencies and then we have a shell script that sets up the classpath and launches the appropriate Java class.

10:24 raek: http://clojure.github.com/clojure/ <-- what happened to clojure.test and friends?

10:25 chouser: for my own hacking around, I had started working up a system of jar directories, one per clojure major version plus a "common" one. So to start using a jar I'd just download it into the appropriate dir, launch the appropriate clojure repl version, and go.

10:26 of course this is both too complex and too simplistic.

10:26 Raynes: chouser: Insanity.

10:26 shoover: chouser: I see

10:27 chouser: shoover: but you're right -- I tend to depend on few libs in practice. java core, clojure core, and contrib covers 90% of what I play with.

10:27 dabbling with ring was painful with my setup. I definitely need to use one of these dep management things.

10:27 anonymouse89: j git

10:27 oops

10:27 shoover: chouser: oh yeah, lots of little jars in the http world

10:28 chouser: so maybe after finger trees...

10:29 but see after that I'm likely to be messing around with clojure-in-clojure stuff, and then maybe clojurescript, etc. None of these have deps outside of clojure.

10:29 technomancy: chouser: so right after I give my lein talk at the conj then? nice timing =)

10:29 chouser: technomancy: yep. and maybe I'll look at eclipse right after lpetit is done talking...

10:29 clojure-conj fascilitates my laziness

10:30 AWizzArd: When I have a :gen-class'ed namespace, and :state s, and want somewhere in that file/NS to access .s then I get a reflection warning. Exists there a way to type-hint it?

10:30 chouser: AWizzArd: sure, just hint it to the class you're gen'ing

10:31 shoover: chouser: I can't imagine doing anything not involving a couch and a tv after writing a book

10:31 AWizzArd: chouser: that would be the NS itself.

10:31 chouser: AWizzArd: no, the namespace is not a class

10:32 though they are generally named similarly, yes.

10:32 AWizzArd: chouser: to AOT that class I used a (:gen-class ...) in the (ns my-ns) form.

10:35 chouser: one sec, I will post an example

10:36 cemerick: man, there was a nasty little locals-clearing bug in 1.1.0 :-/

10:37 AWizzArd: http://paste.lisp.org/display/114852

10:37 When I try to compile this I get a ClassNotFoundException: bar.Foos

10:37 without the type hint I get two reflection warnings

10:40 chouser: AWizzArd: you have to compile for :gen-class to work

10:41 also, why are you using gen-class to implement intefraces instead of deftype or reify?

10:41 interfaces

10:41 AWizzArd: This is just a demo

10:41 chouser: ok

10:41 so yeah, you have to use compile. when I (compile 'bar.Foos) it works fine

10:41 giving only a reflection warning for the .s you didn't hint.

10:44 AWizzArd: okay good

10:44 I was confused because I got those warnings in Emacs, when loading this NS.

10:45 chouser: yes, I understand emacs can be confusing.

10:45 sorry, couldn't resist. bad chouser!

10:46 AWizzArd: chouser: *g*

10:47 rfgpfeiffer_: can a deftype type have static methods?

10:49 chouser: rfgpfeiffer: no, just use regular clojure functions for that

10:58 technomancy: hmmm... might be time to drop test-is support in the next leiningen release. =)

10:58 fliebel: Given the fact that Clojure-in-Clojure is possible, it is thus possible to define lazy seqs. Would it also be possible to define a lazy seq where the 0th element is actually in the middle of an infinite lazy seq extending in both ways? so like (iterate inc) with negative number included :)

10:59 technomancy: you can't rebind a dynamically-referenced var, can you?

10:59 I mean, without evaling a binding call

11:00 chouser: fliebel: ISeq only provides an API for walking forwards. You'd need a different interface for walking the other direction.

11:02 fliebel: chouser: Hrm :( that means I'll be unable to use with with existing functions, right?

11:04 chouser: fliebel: well, what existing function do you intend to call to get item before 'first'?

11:04 fliebel: chouser: Dunno… I mean, if I'm not using ISeq, I can;t even use first, right?

11:05 chouser: well, your theoretical bidirectional lazy seq could implement ISeq for going forward

11:05 fliebel: chouser: Oh wait, Java, so I can implement ISeq and add my own interface and fns for going the other way.

11:07 chouser: How about this… you define a lazy seq like iterate but with 2 fns, for going in either direction. then you call spin on it to change which direction you're seqing over :)

11:08 so spin = reverse for lazy seqs

11:08 chouser: hm, interesting.

11:09 I don't see why not.

11:09 fliebel: chouser: So, what Clojure bits do I need to implement that?

11:10 chouser: a deftype and ... a function?

11:10 fliebel: *looks up deftype*

11:17 chouser: actually, just a deftype would do, though it's not quite as pretty.

11:17 fliebel: chouser: I don't think I get it.

11:18 chouser: (rseq (rest (drop 10 (IterBi. 0 inc dec)))) ;=> (5 4 3 2 1 0 -1 -2 -3 -4 -5 ...)

11:18 anonymouse89: I'm having trouble with this:

11:18 ,(let [add '(+)] (apply (first add) (range 10)))

11:18 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (10) passed to: Symbol

11:18 anonymouse89: I would like it to be equivalent to (apply + (range 10))

11:18 chouser: anonymouse89: try (list +) instead of '(+)

11:19 anonymouse89: chouser: nice

11:19 chouser: ,(class (first '(+)))

11:19 clojurebot: clojure.lang.Symbol

11:19 chouser: ,(fn? (first '(+)))

11:19 clojurebot: false

11:19 chouser: ,(fn? (first (list +)))

11:19 clojurebot: true

11:20 anonymouse89: I thought '(0 1 2) could be thought of as an unevaluated sequence not as a symbol

11:20 chouser: it is an unevaluated sequence, but the contents are unevaluated as well

11:20 so + in that case is just a symbol.

11:21 anonymouse89: chouser: that makes sense, thanks

11:21 chouser: if you want to look up what function + refers to, you have to evaluate the symbol

11:22 fliebel: so that's what you wanted, right? intersting idea.

11:22 fliebel: chouser: I understand how I can do without the fn, but I don't understand deftype.

11:22 chouser: actually, you don't need deftype either. you could use reify or proxy if you prefer, and a normal function.

11:23 fliebel: chouser: I never worked with those 1.2 things before. So it's going to be a lot of learning… :)

11:24 chouser: fliebel: so... how shall we proceed? You want to see my code or should I try to drop hints or ask leading questions?

11:24 fliebel: the later one :) extended with my guessing and reading

11:25 chouser: So I basically need to look up the ISeq interface and overwrite a few methods?

11:25 chouser: ok, so how would you use deftype or reify to implement an ISeq that just repeats the same value over and over

11:25 ?

11:26 fliebel: Where can I find the ISeq interface?

11:26 chouser: I do (show clojure.lang.ISeq)

11:26 fliebel: Unable to resolve symbol: show in this context

11:26 edw: I'm a longtime Emacs user and Scheme programmer and I'm trying to get Emacs set up to play nice with Clojure (1.2) and I the best guide I can find is a mailing list message from Constantine Vetoshev and I get an error when following along with that. Is there a definitive SLIME/Clojure guide out there somewhere?

11:26 chouser: fliebel: :-( rhickey took my 'source' fn, but not my 'show'

11:27 fliebel: show is clojure.contrib.repl-utils/show

11:27 fliebel: chouser: Ah, I use source quite often, but that doesn't work on Java stuff I guess.

11:27 dnolen: edw: http://www.assembla.com/wiki/show/clojure/Getting_Started_with_Emacs

11:27 edw: dnolen: Thank you!

11:28 chouser: fliebel: http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq.java

11:28 edw: Oh gawd, it uses ELPA?! I didn't have good luck with that!

11:28 dnolen: edw: the trick is that you only need to install swank-clojure

11:29 Raynes: ELPA is the standard way of setting this stuff up to work for Clojure. It's all tested and known to work.

11:29 dnolen: edw: the main trouble you might run into is if you have existing Lisp configurations

11:29 edw: dnolen: Ah. I was getting all sorts of dependency errors when installing slime using it. Should I clean out any existing SLIME installations?

11:30 dnolen: edw: I would. Don't bother installing anything but swank-clojure, ignore slime, slime-repl, clojure-mode. There's a bug in the install process. installing swank-clojure will grab everything you need.

11:31 fliebel: chouser: I guess it'd be (reify clojure.lang.ISeq (first [this] 1)) but that fails

11:31 dnolen: edw: you will need to wipe anything clojure related from your .emacs.d/elpa before installing swank-clojure

11:31 fliebel: ah wait

11:31 edw: dnolen: Thanks again. Cleaning out my .emacs (and .emacs.d) right now.

11:32 fliebel: chouser: Do I need to implement all of them? Or can I just use a concrete subclass of ISeq?

11:33 dnolen: edw: np

11:33 chouser: fliebel: just implment the ones you need for now. What happens when you call 'first' on your reify there?

11:33 Then when happens when you call 'next'?

11:34 fliebel: chouser: I get java.lang.AbstractMethodError when defining it, because ISeq is an abstract interface.

11:34 (i think)

11:34 chouser: fliebel: are you sure that's why?

11:34 did you try (first (reify ...)) ?

11:35 * _fogus_ really wishes this would magically work: (defn foo [k v & {:keys [a b] :as m :or {k v}}] [a b]) :-(

11:35 fliebel: chouser: Hm, that works, but just defining it fails.

11:35 chouser: Ah, repl evaluates

11:36 chouser: yep, and after E is P

11:36 fliebel: ?

11:36 chouser: REPL

11:36 fliebel: ah

11:36 chouser: and printing a seq means walking it an printing each of the items. we're not ready for that.

11:37 fliebel: I see

11:37 chouser: so, (first ...) works. what about (next ...)?

11:37 fliebel: let me try..

11:39 (next [this] this)

11:39 Okay, but I have no idea what more and cons are about.

11:40 chouser: fliebel: ignore them for now.

11:40 so, (first ...) and (first (next ...)) work now, right?

11:40 fliebel: yea, but not doing second on it still gives me the error.

11:41 chouser: it's a shame it doesn't tell you the specific method it's trying to call that fails.

11:41 you can discover it by looking up the line of source code it mentions and seeing what method it's calling.

11:42 fliebel: It doesn't even give a line or file:

11:42 java.lang.AbstractMethodError

11:42 (

11:42 that's all

11:42 chouser: yeah

11:42 oh, (.printStackTrace *e) or (pst) on clojure 1.3.0 alpha 1 will show you more

11:42 but not enough.

11:42 fliebel: I'm not on the alpha

11:43 chouser: right, so use (.printStackTrace *e)

11:43 so I'll just tell you -- the REPL calls your .seq method during printing.

11:44 seq must return an ISeq ... can implement that?

11:44 fliebel: But seq isn't in ISeq, or is that up in IPersistentCollection?

11:44 chouser: fliebel: IPersistentCollection

11:45 fliebel: No, Sequential I guess

11:45 chouser: but you can put it under ISeq in your reify

11:46 fliebel: I know, but I need to know it's… how do you call that...

11:47 chouser: http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Seqable.java#L16

11:47 fliebel: right… Now I made it return a list. It prints that and *then* gives the same error.

11:48 chouser: yeah. so that final error is it calling equiv. not sure why

11:49 fliebel: hm…. Do we need to fix that?

11:49 chouser: probably not

11:49 so, what do you have so far?

11:49 fliebel: A ISeq that returns 1s

11:50 (reify clojure.lang.ISeq (first [this] 1) (next [this] this) (seq [this] (list 1 2 3)))

11:50 Maybe I could make seq return a cons of first and rest, but then I'd need to define that as well

11:50 chouser: ,(reify clojure.lang.ISeq (first [this] 1) (next [this] this) (seq [this] (list 1 2 3)))

11:50 clojurebot: (1 2 3)

11:50 technomancy: there's no zeroconf stack for the JVM, is there?

11:51 that would be great for conj shenanigans...

11:51 chouser: fliebel: do you have an ISeq handy already for your 'seq' to return?

11:52 fliebel: this?

11:52 clojurebot: this is not a bug

11:52 chouser: fliebel: what happens when you try it?

11:53 fliebel: I guess it'll get stuck

11:53 mrBliss: there's (quote ..) for ', what's the function for `?

11:53 chouser: mrBliss: doesn't exist. ` is implemented differently

11:54 fliebel: chouser: It does get stuck, but doing take 10 gives java.lang.AbstractMethodError again

11:54 chouser: ,(read-string "1(foo)")

11:54 clojurebot: 1

11:54 mrBliss: chouser: too bad, now I have to wrap it in (fn [] ..)

11:54 chouser: ,(read-string "`(foo)")

11:54 clojurebot: (clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/foo))))

11:55 jashmenn: hey, one more question to add to the mix: if i compile and import a gen-class from the repl, is there a way to reload the gen'd class without restarting the jvm?

11:55 chouser: fliebel: you're in a plain REPL or in slime or what?

11:55 jashmenn: (my code: http://gist.github.com/595569)

11:55 fliebel: cake

11:55 chouser: fliebel: cake and a terminal?

11:56 fliebel: okay, just the terminal prints a lot of 1 :)

11:56 chouser: good job!

11:56 fliebel: but take 10 doesn't work yet

11:56 chouser: take is calling your (unimplemented) rest method

11:57 er, 'more', rather

11:57 fliebel: I keep forgetting the difference between next and rest...

11:57 and I don't know more at all :P

11:57 ubii: looking to get back into clojure after a 9 month hiatus and have the following questions

11:58 fliebel: chouser: There arn't any docstrings on ISeq :(

11:58 ubii: 1) I am still very much a newbie and am wondering if I should stick with 1.2 or go ahead and check out 1.3

11:58 chouser: the difference between more (called by clojure.core/rest) and next only matters when being very careful about nearly vs. complete laziness.

11:58 ohpauleez: fliebel: new rest is almost always what you want, except when you don't

11:59 chouser: that is, we don't really care much. So what happens if youre 'more' is the same as your 'next'?

11:59 esj: ubii: i'd stick with 1.2, its still pretty new :)

11:59 andyfingerhut: ubil: You'll likely have less confusion with 1.2. More tested with other add-ons

11:59 fliebel: chouser: Works :)

11:59 ubii: 2) should I install clojure via the zip files, source(github), or use Leiningen?

12:00 chouser: fliebel: congrats!

12:00 mrBliss: ubii: leiningen or cake

12:00 ohpauleez: ubii: I agree with 1.2, but if you want to play with some of the new stuff, and can deal with some exceptions now and then, 1.3 has been fine for me

12:00 mrBliss: ubii: or cljr for a standalone repl to play with

12:00 fliebel: chouser: I know how to reverse it :D

12:00 ohpauleez: ubii: what mrBliss said

12:00 chouser: fliebel: :-{

12:00 fliebel: :-P

12:01 fliebel: ok, but you want to apply a function instead of just repeating, right? how would you do that?

12:02 fliebel: chouser: Hey, my ISeq doesn't implement clojure.lang.Reversible

12:02 chouser: fliebel: hm, what are going to do about that?

12:02 ubii: 3) which editor (emacs, vi) or IDE do most of you use and what would you recommend?

12:03 Raynes: Emacs is the most used, followed by vi and the IDE plugins.

12:03 I did a poll a while back, which was further confirmed by cemerick's poll not too long ago.

12:03 fliebel: chouser: I don't think reify allows me to define multiple ancestors :(

12:03 chouser: there are about as many emacs users as non-emacs users

12:03 fliebel: I would not have led you astray

12:04 fliebel: chouser: Can I nest reifies? :P

12:04 Raynes: Wasn't it like 62% of Clojurians using Emacs?

12:04 chouser: fliebel: yes, but that's not what you want here.

12:04 fliebel: Nope :(

12:05 chouser: fliebel: according to the deftype docs, "Each spec consists of..."?

12:05 andyfingerhut: Emacs is free as in beer, free as in libre, but if you are new to it, it costs some time :-) It was new for me a long time ago...

12:05 fliebel: ah...

12:06 chouser: Raynes: oh, you're right. 70%

12:08 andyfingerhut: chouser: So did you understand Haskell somewhat well before reading the published paper on finger trees?

12:08 fliebel: chouser: I added clojure.lang.Reversible (rev [this] this) but it still says Can't define method not in interfaces: rev

12:09 huh…. I need to define rseq, but rseq calls rev

12:09 ,(source rseq)

12:09 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

12:10 fliebel: no. wait...

12:10 chouser: fliebel: yeah, I did that first too.

12:11 fliebel: chouser: (. rev (rseq)) what is this?

12:11 Why the parens abround rseq?

12:12 chouser: fliebel: ancient syntax. the same as (.rseq rev)

12:12 fliebel: lol

12:12 Okay, so now for the real thing :)

12:15 chouser: Can we go somewhat more down the inheritacne tree to find something that covers the basics? Or do we need everything customized anyway?

12:19 chouser: fliebel: reify doesn't let you inherit from anything but pure methods.

12:22 anonymouse89: ,(quote (first '(0 1 2)))

12:22 clojurebot: (first (quote (0 1 2)))

12:22 fliebel: you mean interfaces?

12:23 anonymouse89: why does this happen?

12:24 fliebel: chouser: So what is next?

12:24 andyfingerhut: anonymous89: If you mean "why does the ' change to (quote ...)?" it is because that is what ' is defined to mean.

12:25 anonymouse89: andyfingerhut: oh, duh the repl is just taking the outside quote off

12:29 mrBliss: I've written a lazy-let macro which doesn't evaluate any of its bindings until they are needed, handy when you're dealing with many conditional bindings. http://gist.github.com/595634

12:30 s/written/hacked together ;-)

12:30 chouser: fliebel: sorry, distracted.

12:30 fliebel: nvm

12:31 ohpauleez: mrBliss: I like that substitute

12:32 fliebel: chouser: Did you mean present or past?

12:33 chouser: fliebel: I'm on the phone at work.

12:33 fliebel: work? oh right… timezones, I'm sorry

12:34 stuartsierra: 1.3.0-alpha1 artifacts deployed... let the carping commence!

12:35 ohpauleez: stuartsierra: haha

12:35 stuartsierra: btw, really loving lazytest stuff

12:35 stuartsierra: awesome

12:35 Speaking of Lazytest

12:35 I'm thinking of releasing 1.0.0 final today.

12:35 ohpauleez: yes!

12:35 please do

12:36 stuartsierra: Anybody have any bug reports before that goes out?

12:36 andyfingerhut: carping: Why wasn't this ready when Rich asked us to try out 1.3? Why is it alpha1? Why am I losing my hair?

12:36 stuartsierra: andyfingerhut: What?

12:37 technomancy: consult your healthcare provider if you experience hair loss in conjunction with upgrading to Clojure 1.3

12:37 andyfingerhut: Sorry, just wanted to commence the carping in a silly fashion. Should have added :-)

12:37 stuartsierra: As I understand from Stu Halloway & Rich, the plan is to release more frequent alphas to get more people to test out new features without having to depend on SNAPSHOT versions.

12:37 esj: stuartsierra: quick question - is there any intent to add a test coverage tool ?

12:37 stuartsierra: esj: Sure, want to write one? :)

12:38 technomancy: esj: do you know about radagast?

12:38 ubii: thx for the answers

12:38 esj: stuartsierra: would love to - unsure you would though. Care to supervise ?

12:38 technomancy: googling.

12:38 ubii: sorry, got tied up with dealing with a client request

12:39 esj: technomancy: now I do ! I'll go play with it, thanks.

12:39 stuartsierra: esj: It doesn't interest me a great deal. I think doing it "properly" would require instrumenting the JVM.

12:40 ubii: regarding Emacs, which is the preferred method for installing/configuring clojure-mode, slime, and swank-clojure?

12:40 technomancy: stuartsierra: radagast offers coarse-grained test coverage, but for branch-level you'd have to hack the compiler

12:40 andyfingerhut: If you haven't done it before, ELPA

12:40 stuartsierra: ubii: Sacrifices of fattened animals generally help.

12:40 esj: ubii: ELPA, as per technomancy's guide.

12:40 stuartsierra: technomancy: Yeah, that's what I meant.

12:41 esj: technomancy: 35 lines...

12:41 stuartsierra: It would be an interesting dive into the Clojure compiler, but I think the effort would far outweigh the reward.

12:41 technomancy: stuartsierra: especially when coarse-grained coverage is trivial to implement

12:41 stuartsierra: yeah

12:42 So if anybody wants to play with integrating radagast with Lazytest, I'll try to help out.

12:42 ohpauleez: stuartsierra: I might be into that

12:42 stuartsierra: cool

12:42 ohpauleez: If I get anywhere, I'll ping you

12:43 stuartsierra: ok

12:43 fliebel: chouser: I need to prepare dinner. I'll talk to you about reify later. Thanks for helping me. I'm now struggling with where to keep state and how to modify things withouy an endless recursion.

12:43 chouser: fliebel: yep. hint: fn args are state

12:44 ubii: http://technomancy.us/126 - is this the correct url to the guide?

12:44 technomancy: ubii: try "getting started with Emacs" on the official Assembla wiki

12:45 ubii: cool, thx all

12:49 andyfingerhut: Are there "inner deftypes" that are analogous to Java inner classes?

12:49 stuartsierra: Ack!

12:50 chouser: andyfingerhut: there's reify

12:51 andyfingerhut: chouser: I ask because I was thinking of how one could modify your finger trees without having a meter-obj in every deftype'd object in a whole tree.

12:51 chouser: andyfingerhut: yeah, I mentioned an alternative in a recent email

12:52 ...passing in the meter as an arg to methods that use it, and relying on some outter context to provide the correct one every time.

12:52 I didn't have outer contexts before, but my most recent commit adds a couple examples

12:54 andyfingerhut: ok. It is just that so many of the methods need it. I'm not advocating for inner deftypes, but they look like they would kinda-sorta help in this kind of case. I'm sure there are other ways.

12:55 chouser: it would still have to be stored somewhere that all the node methods could find it, wouldn't it?

12:55 andyfingerhut: Yes. So you make all the node deftypes inside the main one.

12:56 Maybe a crazy idea, and maybe problems with it I haven't thought of. But if the feature were there, I would have been crazy enough to try it out :-)

12:57 chouser: :-)

12:57 gotta go. bbl.

12:57 stuartsierra: Even nested classes aren't really contained in Java.

12:57 It's just a namespacing convenience.

12:57 With some funny rules about public/private visibility.

12:58 andyfingerhut: Inner classes do not get access to per-instance fields of the class in which they are nested?

12:58 stuartsierra: I can never remember the rules.

12:58 andyfingerhut: That's OK. Some rules, only the writer of the rules can keep in their head at one time.

13:02 amalloy: inner classes have access to instance fields of the outer class. the one that always gets me is method-local classes

13:12 proyal: howdy! question: i have two seq's, one of fn's, the other of values. in order, i want to map each item of my value seq with the corresponding (nth-wise) fn from my seq of fn's. is there a handy way to do that?

13:12 stuartsierra: (map (fn [f v] (f v)) fns values)

13:13 chouser: or #(%1 %2)

13:13 proyal: stuartsierra: ah, awesome. docs weren't clear that's how it worked

13:13 stuartsierra: what chouser said

13:13 proyal: i tried 'for', but that gave me a cartesian product

13:13 ohpauleez: proyal: I'd do what chouser said, typically

13:14 proyal: yah, anon-fn's preferred indeed. worked like a charm, thanks gents!

13:16 amalloy: chouser: wow, i didn't know that worked. i sorta assumed #() needed something it could resolve at the call site

13:17 ohpauleez: amalloy: the beauty of first-class of functions

13:17 amalloy: yeah. when i look at the expansion of #() into (fn []) it's clear that there's no reason the latter should work but not the former; but the first one just looks mind-boggling

13:18 dnolen: somebody who is able want to open up a ticket for even? in 1.3.0-alpha1 (I really need to send in my CA :P) http://groups.google.com/group/clojure/browse_thread/thread/f46fc7389ecdf1f8#

13:21 birdspider: hi, anyone familiar with penumbra(clj wrapper for lwjgl)? can't get the examples to work

13:24 dnolen: birdspider: what's the problem?

13:27 birdspider: dnolen, well first I'd like to know if the examples are bundled in the penubra.jar ? or if I have to pull them seperatly

13:28 dnolen: birdspider: the jar? did you d/l the git repo?

13:29 birdspider: dnolen, nope I just downloaded the clojar via lein deps

13:29 dnolen: birdspider: that won't work I think as you need something to set the classpath to the native libs.

13:30 birdspider: it's simpler to just checkout the repo, and run 'lein repl' and run the examples from the REPL

13:30 birdspider: dnolen, well yes, my current status is that I downloaded a single example and tried to (require) it

13:30 dnolen, native libs via native-deps in place afaik

13:31 dnolen, which I link via -Djava.library.path=pathToSo

13:31 dnolen: birdspider: do you have a paste somewhere of the error?

13:31 birdspider: but it gives me java.lang.ClassNotFoundException: org.lwjgl.opengl.GL11 (core.clj:9)

13:31 dnolen, do I have to link each *.so specifically

13:32 dnolen, or just the path

13:32 dnolen: birdspider: no, what do you set the library path to?

13:32 birdspider: dnolen, -Djava.library.path=native/linux/x86/

13:32 dnolen, which contains: libjinput-linux.so liblwjgl.so libopenal.so

13:34 cemerick: I'd like to invoke a fn a no-arg function within the context of comp or ->, but for the life of me, I don't see a clean way to do so.

13:34 ,(-> str .invoke count)

13:34 clojurebot: 0

13:34 cemerick: is the best I've come up with, which sucks.

13:34 Someone tell me I'm nuts.

13:35 dnolen: birdspider: hmm that should work yes... and yr classpath is set as well I assume? You do need to include each jar individually.

13:36 birdspider: dnolen, well there is a bunch of stuff in lib, but i tried: java -cp lib/clojure-contrib-1.2.0-20100813.160219-142.jar:lib/clojure-1.2.0-master-20100813.160144-94.jar:lib/penumbra-0.6.0-20100502.112537-3.jar:src/ -Djava.library.path=native/linux/x86/liblwjgl.so clojure.main

13:36 dnolen, clojure, clojure-contrib, and penumbra

13:36 dnolen, ah

13:36 dnolen, there are the lwjgl jars

13:36 dnolen, :)

13:36 stuartsierra: cemerick: You're nuts (-> (str) count)

13:36 dnolen: birdspider: yup

13:37 birdspider: those get unpacked by native-deps so it's a bit weird

13:37 cemerick: stuartsierra: right, but assume the fn I want to invoke is the result of a prior invocation in -> or comp

13:37 birdspider: dnolen, thats what I got wrong, I looked there after calling deps

13:37 dnolen, ok thx for now

13:37 dnolen: birdspider: np

13:38 stuartsierra: cemerick: with comp, easy, just wrap in #()

13:38 With ->, you're still nuts :)

13:38 hiredman: ,(str (apply nil) count)

13:38 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$apply

13:38 stuartsierra: well, not #() but (fn [_] foo...)

13:38 hiredman: ,(-> str (apply nil) count)

13:38 clojurebot: 0

13:39 * cemerick grumbles

13:39 cemerick: My real trouble is that I"m actually using comp and partial with equal frequency as -> and #() these days.

13:39 momos: Hello :-)

13:45 andyfingerhut: With 1.3.0, is someone already planning a web page or something similar that people can go to in order to assist in upgrading their code base from 1.2.0? As a minor example, I had some calls to re-gsub that worked on 1.2.0, but the name changed so it took some time to find in 1.3

13:45 stuartsierra: re-gsub was already deprecated in 1.3

13:45 I mean 1.2

13:53 andyfingerhut: Is there a way to enable warnings of using deprecated things in 1.2?

14:09 duncanm: anyone working on incanter here?

14:09 is there a reason why the API page is broken? it only shows the package names, but none of the functions

14:09 fliebel: chouser: I have a full stomach now. Do you have time to explain me a few key things about reify? I'm thinking in circles now. :(

14:10 duncanm: hmm, liebke is not around

14:13 ohpauleez: ~seen liebke

14:13 clojurebot: liebke was last seen quiting IRC, 2561 minutes ago

14:17 fliebel: ~seen chouser

14:17 clojurebot: chouser was last seen in #clojure, 64 minutes ago saying: or #(%1 %2)

14:47 chouser: fliebel: back in a sec

14:48 fliebel: sure :) I nearly got it working :)

14:50 chouser: ok, back. That's great. what have you got?

14:50 fliebel: http://gist.github.com/595835

14:51 chouser: nice!

14:52 fliebel: thanks :) You're a good teacher :)

14:52 chouser: I think that's the same as what I have. but you said "nearly"?

14:52 fliebel: The problem I had was that first was defined as the first of this, but I couldn't do (first this) of course.

14:53 The same goes for next, that should return this with first replaced, but I can't just do (assoc this)

14:53 So then I figured I needed the fn.

14:54 chouser: if you want to "check" your answer: http://gist.github.com/595663

14:54 fliebel: this is your version?

14:54 chouser: yep

14:56 fliebel: very close :) Only you have equiv defined and next uses more. Does it matter if you use .more(method call) or rest?

14:57 chouser: not really. yours is probably faster

14:57 but duplicates half a line of code. :-)

14:57 fliebel: yea… :(

14:57 chouser: so take your pick. what you've got is good.

14:58 better arg names than mine

14:58 fliebel: One problem I have is that drop 5 returns a lazy seq which I can't reverse.

14:58 chouser: yeah, you see how I work around that in my example?

14:59 fliebel: rest, I used seq to do the job

14:59 chouser: oh! smart!

14:59 interesting -- I hadn't considered that, and wouldn't have been sure it would work. nicely done.

14:59 fliebel: One thing I haven't figured out yet is how to make a seq that goes 1 2 3 4 5 4 3 2 1, so changes direction in the middle.

15:00 chouser: I wasn;t sure it would work, but seq is magic you know..

15:02 chouser: (let [[prefix the-rest] (split-at 5 (iter-bi 0 inc dec))] (concat prefix (rseq (seq the-rest))))

15:04 fliebel: yea, so much trickery… :(

15:05 chouser: hm

15:05 fliebel: It'd be awesome if there was a clean way to do that as an infinit seq.

15:06 I've been thinking about reduce and recur, but immutable stuff makes it hard t say "hay, rseq the rest" in the middle of a loop.

15:07 chouser: fliebel: right, the problem is applying a different function partway through a seq. split-at is one way to do that. reduce and loop/recur would be others, but aren't lazy.

15:09 fogus_: I am perplexed by the contrib modules.

15:12 chouser: fliebel: ((fn f [s] (lazy-seq (cons (first s) (f (rest (if (zero? (rem (first s) 5)) (rseq (seq s)) s)))))) (iter-bi 1 inc dec))

15:14 fliebel: chouser: I'm going to try and understand :)

15:15 it works, but I'm not yet sure how :P

15:17 chouser: BTW, I wanted to call attention to my comment on rseq. I think we're abusing it here and probably ought to define a new protocol instead. (defprotocol Spinnable (spin [_])) or something.

15:19 fliebel: Okay… you use defprotocol for that?

15:19 chouser: yep

15:20 hmm...

15:22 fliebel: So now in reify I replace reversible with spinnable?

15:24 chouser: oh, wait -- does reify not work on protocols?

15:24 nm, dumb mistake

15:25 there, now you don't have to call seq manually on lazy-seqs: http://gist.github.com/595663

15:26 briancarper: Is anyone here actually able to pull 1.3.0-alpha1 contrib via Maven or Lein?

15:27 raek: anyone know why the clojure.github.org/clojure docs for 1.2 seems to have been reverted to 1.1-ish?

15:27 fliebel: chouser: What? You can just add behavior to existing types? Am I in #ruby?

15:27 raek: all the clojure.java.* and clojure.test namespaces are gone

15:28 chouser: fliebel: nope. in clojure we do it without monkey patching or adapter classes. :-)

15:28 AWizzArd: why was it named clojure.java?

15:28 chouser: fliebel: I mean "nope" you're not in #ruby. Of course you can write new functions that take existing classes as args that then do their own thing with them.

15:28 AWizzArd: It could have been more platform neutral, instead of clojure.dotnet/java

15:29 raek: probably because those are very host-specific

15:29 AWizzArd: you find?

15:30 raek: feels like those are mostly wrapper libs for certain java feauters

15:30 AWizzArd: those libs are also present in .net

15:30 fliebel: chouser: But you just added extra behavior to LazySeq, right?

15:30 raek: ok, maybe they are more similar than I thought

15:30 AWizzArd: it means that if I want to use typical IO stuff, we will have funny java names in my .net code

15:31 raek: does .net have input/ouput streams and readers/writers in the same way java does

15:31 dnolen: fliebel: it's a properly namespaced extension tho. It's not visible to other namespaces.

15:31 chouser: fliebel: it certainly looks like I did. In this case we could have written spin like: (defn spin [x] (if (instance? LazySeq x) ...))) right?

15:32 fliebel: I think so...

15:32 chouser: it's our function, we just defined it with defprotocol which allows us to add new cases on the fly

15:32 fliebel: yay

15:32 replaca: Has anyone else seen a stack overflow out of clojure.lang.Keyword?

15:32 in the intern method

15:32 chouser: essentially. Except then rhickey sprinkled it with magic dust to make it very fast.

15:33 fliebel: :)

15:33 chouser: fliebel: it's good to know not everyone knows about this yet -- it's my topic at Strange Loop

15:33 bhenry: from the moustache docs:

15:33 (app ["foo" name] my-handler)

15:33 ; will route requests to "/foo/", "/foo/bar" to my-handler and bind @name@ (a local) to the matched segment (eg "" or "bar")

15:33 how do i access the name where (= name "bar")

15:33 fliebel: oh, I feel special now :)

15:34 chouser: fliebel: good I'm glad! But... why?

15:34 dnolen: bhenryy: you need to create a handler fn, 'name' will be visible to it - (fn [req] (my-handler name)), moustache also has a delegate fn to make this less tedious

15:35 fliebel: Because I know something not everyone knows ;)

15:35 chouser: ah, good!

15:36 bhenry: dnolen: i had that and it didsn't work

15:36 fliebel: Except that I'm not o sure yet what exactly you just said. Only that it's magic and fast. Two things I like especially.

15:36 bhenry: *gisting*

15:39 chouser: fliebel: not coming to Strang Loop I suppose? Or Clojure-Conj?

15:40 fliebel: I'm located in the Netherlands, so I'm afraid not :( :(

15:41 I'd love to though

15:42 chouser: fliebel: Here are the basics: http://clojure.org/datatypes

15:42 or perhaps "raw details" is a better description.

15:42 fliebel: chouser: I tried to read that this morning, but maybe with my new knowledge I can understand it.

15:43 chouser: "Joy of Clojure" and "Practical Clojure" I believe both cover protocols and reify.

15:43 fliebel: I never read programming books, except when I did Java.

15:44 chouser: I do sparingly. Learned Pascal and Lisp from books, but not perl or ruby

15:46 in both cases the paradigm shift from what I knew to what I was trying to learn warranted the kind of wholistic coverage a book does better than random web postings.

15:46 and official docs

15:47 fliebel: That would have been true when I started with Clojure, but now I'd get bored by the stuff I already know, and lose myself in side projects based on hte book.

15:48 ohpauleez: Joy of Clojure has an awesome section on proxy, reify, defprotocol, and defrecord

15:48 I reference it often to judge if I'm abusing something

15:48 fliebel: Man, I turned 100-bootles-of-beer-song-generators from a book into webapps and such, to find out they'd do that a couple of chapters later.

15:49 Yea, maybe I should get a book anyway…

15:49 ohpauleez: fliebel: At the point you're at in Clojure (based on what I follow in here), you'd get a lot of mileage out of it

15:50 chouser: ohpauleez: thanks. didn't want to say it myself. :-)

15:50 ohpauleez: very well organized and telling you when and why, instead of how and a little why

15:50 chouser: :) it's all good

15:51 chouser: real talk, it's one of the best books I've read. Works great as a story, examples are intelligent and easy to follow, but advanced enough to be adapted, Easy to use a reference.

15:52 fliebel: ohpauleez: I think I agree with you.

15:52 ohpauleez: and the biggest problem I had in clojure was deciding, "when"

15:52 fliebel: ohpauleez: ?

15:52 ohpauleez: it helped me a lot with that

15:52 fliebel: when?

15:52 ohpauleez: fliebel: In clojure, you have this whole array of functionality. Take concurrency

15:52 we all have that little chart burned in our brains by now

15:53 we know vars and atoms and agents

15:53 but when should I be using promises over futures, or when am I abusing a future and should really be using an agent

15:53 when should I use protocols and not some other small hack

15:53 fliebel: right… I have that problem a lot indeed

15:54 chouser: ohpauleez: that's very encourging, thanks.

15:54 ohpauleez: Joy of Clojure is structured by answering when, and for me, that pulled it all together

15:55 chouser: np, thank you!

15:55 fliebel: muhahaha, under 10 there is a whole set of "when to use … "

15:56 bhenry: dnolen: can you give an example of delegate?

15:57 ohpauleez: chouser: Out of curiosity, how did you and fogus assemble the book

15:57 dnolen: bhenry: lemme look

15:57 ohpauleez: LaTeX?

15:57 fliebel: ohpauleez: How comes you have already read it when it's not out yet? You do the MeAP ebook thing?

15:57 chouser: ohpauleez: heh. you don't want to know.

15:57 ohpauleez: sausage-making and all that.

15:57 ohpauleez: chouser: haha, fair enough

15:58 chouser: ohpauleez: nah, I kid. We wrote it in markdown, augmented with our own various extensions.

15:58 ohpauleez: fliebel: Yeah, I got the MEAP when the first chapter was finished, and read the chapters as they were released

15:58 chouser: ohpauleez: then wrote tools to generate Manning's docbook-like XML from that, which they use to generate PDFs, etc.

15:59 ohpauleez: ahh, cool

15:59 fliebel: nice

15:59 dnolen: bhenry: http://github.com/cgrand/moustache/blob/master/src/net/cgrand/moustache.clj#L159

16:00 bhenry: (delegate foo name) -> (fn [req] (foo req name))

16:00 fliebel: chouser: Is there a release date, or is it a "don't ask, it's read when it's ready" thing?

16:01 chouser: fliebel: fogus_ and I are essentially done, as far as I understand. It's going through final editing revisions now and should be on dead trees by Nov or Dec.

16:02 fliebel: Cool :) I prefer a real book over an electronic one, except for searching :)

16:02 bhenry: dnolen, i had just read that and gotten it to work when you posted. thanks for the help.

16:02 ohpauleez: fliebel: I don't know if you can still do it, but you can get a package deal

16:03 ebook and physical one, for a great price

16:03 fliebel: "MEAP + Print book (includes Ebook) when available"

16:03 ohpauleez: right, you get the ebook now

16:03 and the print book is shipped

16:03 fliebel: nice :)

16:04 dnolen: anybody know who the intro is written by yet?

16:04 ohpauleez: dnolen: The Stu's

16:04 chouser: fliebel: there are often coupon codes listed at joyofclojure.com

16:04 ohpauleez: dnolen: nah, I'm just making it up

16:05 chouser: dnolen: not yet announced, afaik. :-)

16:05 dnolen: arg

16:06 fliebel: chouser: ?

16:06 Where do I look for?

16:06 chouser: fliebel: we're very excited about who we've got to write the foreward for us, but for some reason are keeping it a secret for now.

16:06 oh, what are you asking?

16:07 fogus_: chouser: BTW, got an email. Things are back on track WRT to the foreword. :-)

16:07 chouser: fogus_: ah, great news. I wasn't really worried.

16:07 fliebel: chouser: I was asking about the coupon codes. What do you mean by listed?

16:07 fogus_: yeah really.

16:07 chouser: fogus_: not as if this person has shown difficulty producing large amounts of text in the past.

16:08 fliebel: oh, sorry. It would be right by the "Buy it" link if there were one running right now.

16:08 fliebel: chouser: Ah, okay, I'll keep any eye on it, or probably not actually, but anyway.

16:08 lpetit: hello all

16:09 chouser: fliebel: if you use twitter you can follow fogus or me -- we generally tweet when we hear about coupon codes.

16:09 lpetit: hi!

16:10 fliebel: chouser: I was about to do that anyway :) My Twitter is becomming full of awesome Clojure people :)

16:10 lpetit: chouser: you lose. I need somebody's help, you answered to me, you're the one ! :)

16:11 chouser: more seriously, is it a time where I can talk about a problem, do you have enough bandwidth currently ?

16:12 alpheus: How do you specify that a Var is bound in a function's :pre condition?

16:13 fogus_: The Clojure Maven repos are busted. Should be fixed... eventually.

16:13 wwmorgan1: alpheus: can you call the java method isBound on it?

16:13 chouser: lpetit: hm, it's nearly time for TF2, so perhaps not.

16:14 lpetit: I have questions related to clojure and its use of classloaders. We're trying, with cgrand, to see what could be done better in our way to embed in OSGi.

16:14 alpheus: I think I'm really just asking what is the argument for bound? supposed to be?

16:14 lpetit: What's TF2 ?

16:14 ohpauleez: TeamFortress 2, I'm guessing

16:14 chouser: lpetit: way off topic. ohpauleez is correct.

16:16 alpheus: I would have thought (bound? 'foo) but clojure.lang.Symbol cannot be cast to clojure.lang.Var

16:16 lpetit: First question: is there a way for me to initiate the Clojure environment, or very quickly after its initialization, with a parent classloader of my own. So that clojure always tries to find a classpath resource (bytecode on disk, clojure file on disk) via my classloader before "giving up" ?

16:16 MayDaniel: alpheus: (bound #'foo)

16:16 bound?*

16:17 lpetit: >(doc bound?)

16:17 ,(doc bound?)

16:17 clojurebot: "([& vars]); Returns true if all of the vars provided as arguments have any bound value, root or thread-local. Implies that deref'ing the provided vars will succeed. Returns true if no vars are provided."

16:17 ninjudd: lpetit: not sure i am qualified to answer, but i spent many hours a few months back trying to do something similar

16:17 alpheus: (bound? #'foo) raises Unable to resolve var: foo in this context

16:18 hiredman: -Djava.system.class.loader

16:18 lpetit: ninjudd: interesting. If you have a clearer "vision" of how things work

16:18 hiredman: but if the classloader you specify references clojure clojure will be loaded

16:18 wwmorgan1: alpheus: do (declare foo) first. then bound? on #'foo will return false

16:19 lpetit: hiredman: I can not tweak things at this level. I cannot force every user of ccw to tweak its loading script for eclipse

16:19 MayDaniel: alpheus: What are you trying to do? Are you sure bound? is what you need?

16:19 hiredman: so you need to either write the classloader in java or use ASM to generate byte code that doesn't reference clojure

16:19 lpetit: *shrug*

16:19 ninjudd: lpetit: my solution was to use setContextClassLoader, but i ran into what i think is a bug in how clojure handles *use-context-classloader*

16:20 lpetit: my travails are detailed in this thread: http://groups.google.com/group/clojure-dev/browse_thread/thread/f61b550abf7f9c52/da25ba7e31b9431c

16:20 lpetit: ninjudd: you tried your tests for which kind of environment ? OSGi ? WebApp ?

16:20 stuartsierra: Bwahaha, I broke Contrib.

16:20 Trying to fix now.

16:20 lpetit: ninjudd: thx I'll consult it

16:22 alpheus: I am not sure bound? is what I need. I am writing a function that relies on something that I expect will be set up by def/defvar or in a binding form and I wanted to assert that in the pre part of a condition-map for the function. Please feel free to tell me I'm going about that all wrong and point me toward the right documentation.

16:22 lpetit: hiredman: no problem. I can write the classloader in java. But I can not "insert it" in the classloader hierarchy in the classical way. It's "constrained" by OSGi. Rather, I would like to create my own classloader, which will leverage the OSGi classloader as its parent one, and then inject mine (which will have some goodies such as being able to consult all classloaders of all bundles that...

16:22 ...depend on the clojure bundle) as the "reference" classloader for clojure

16:22 hiredman: at this particular moment, I don't even know if what I just described makes sense

16:23 ninjudd: before even reading your post, reacting to your explanation: my fear is that I do not have control over the context class loader in the long run. I'm thinking about entering by the backdoor room :)

16:24 wwmorgan1: alpheus: I think that what you want to know is whether the namespace has the symbol you need. In this case you want ns-resolve

16:24 hiredman: lpetit: that is a complex issue

16:24 and surprisingly oracle or ibm have some patents related to it

16:24 (ugh)

16:24 lpetit: hiredman: oooh yes ! took us awake veeerry late yesterday !

16:24 patents ?

16:25 hiredman: ninjudd: I haven't look at clojure's use of classloaders much, but the use of dynamic classloaders the way they are may be what allows the redefinition of records at a repl

16:25 lpetit: I know right? crazy

16:25 lpetit: hiredman: probably not an issue, everybody knows those people work for science, not profit ;-)

16:26 hiredman: filtering classloaders and such

16:26 http://www.faqs.org/patents/app/20080271002

16:27 duncanm: la la la

16:27 lpetit: hiredman: it really is totally crazy to place patterns on such trivial "thoughts" !

16:28 and even more crazy to accept those as patterns !

16:29 hiredman: I haven't played with records that much. There's still a restriction on their redefinition ? Due to the fact that a real class is generated, right ?

16:30 ninjudd: hiredman: my change didn't affect the repl. it still had DynamicClassLoader as the parent of NativeClassLoader. plus i only change the classloader temporarily in my import-native method

16:31 lpetit: hiredman, ninjudd: reading ninjudd's link and others related to OSGi/context class loader. Will come back to you within 15 minutes

16:32 ninjudd: hiredman: but i'm past NativeClassloader anyway. cake handles native libs perfectly without having to muck with the classloader

16:32 my point was just that i think there is still a bug in how clojure handles *use-context-classloader*

16:33 hiredman: as I said, I have not really looked at it, but classloading is very complicated, and is definitely tricky in the case of redefining classes

16:34 * hiredman needs to write a jar classloader some day

16:36 ninjudd: hiredman: agreed, it is very complicated. which is probably why cemerick was the only person brave enough to respond to my message

16:37 cemerick: which message was that?

16:37 * cemerick has chronic altheimer's

16:37 ninjudd: that classloader message from way back when

16:42 hiredman: the complexity is also likely why nobody wanted to touch a patch from some kid they'd never heard of to fix a bug that nobody else had noticed ;-)

16:42 but that doesn't mean it isn't a bug

16:44 hiredman: I will with hold judgement on bugness until it's been reviewed elsewhere

16:45 ninjudd: hiredman: probably won't ever happen. it's over four months old.

16:46 hiredman: *shrug*

16:46 ninjudd: unless someone with more clout has the same problem. then i shall be vindicated!

16:47 cemerick: ninjudd: is there a bug opened on assembla?

16:48 ninjudd: good question

16:48 looks like i never opened one. i think this was back before i had access

16:49 dnolen: ninjudd: do it!

16:50 * ninjudd and dnolen both use native libraries.

16:50 lpetit: ninjudd, cemerick, hiredman: just read an article or two on the subject of OSGi and its affinities with context class path. It's just a no man's land in the spec. Every container has its own way to use it. Some expose every exported package by every bundle in this classloader, some do not guarantee that it is set, some by the use of proxies at bundle boundaries try hard to always set it...

16:50 ...correctly (but I guess that you need to always use OSGi services then, not directly call classes exported by another bundle ...

16:51 ninjudd: you scared him off

16:54 lpetit: sounds painful

16:55 lpetit: ninjudd: ooh yes. That's why I somehow give up on trying to cheat with OSGi, and now I'm trying to cheat with clojure :-). I can even consider hacking it a little bit in the corners. But right now I just need to understand how it works.

16:57 ninjudd: so how do you plan to cheat with clojure? replace DynamicClassloader?

17:00 lpetit: ninjudd: first step = find a summary of how the parts that use classloaders work, or someone with the ability to do this summary "live" for me. Then I'll see if this "DynamicClassloader" should be extended, composed, replaced, etc. (I don't even know exactly what I'm talking about, concerning Clojure and classloaders. And this kind of subject does not suffer to be imprecise)

17:01 * lpetit is currently reading this http://blog.springsource.com/2008/05/02/running-spring-applications-on-osgi-with-the-springsource-application-platform/

17:02 ninjudd: lpetit: i would start by trying to write your own classloader that users DynamicClassLoader as it's parent, which means that resources that are not found by your classloader will be loaded using dynamic classloader.

17:02 s/users/uses/

17:02 sexpbot: <ninjudd> lpetit: i would start by trying to write your own classloader that uses DynamicClassLoader as it's parent, which means that resources that are not found by your classloader will be loaded using dynamic classloader.

17:03 ninjudd: lpetit: then you can use setContextClassLoader to change clojure to use your classloader instead of DynamicClassLoader.

17:04 lpetit: what you are doing sounds very similar to what i was doing. NativeClassLoader and my import-native function are good examples

17:04 lpetit: ninjudd: it's more that I don't know in which ways I can direct clojure to use my classloader. I remember vaguely having seen various places where a modif can be made (some *use-context-classloader*, some CLASS_LOADER static attributes of RT / Compiler, BASE_CLASSLOADER, etc). I'm lost between those "alternatives"

17:06 ninjudd: but *when* to call setContextClassLoader() ? I cannot do this once and for all, or I'll not play well with OSGi (that's what I understand). By doing so I may expose to few or to many things to all other following users of the thread. And I have no guarantee that it will not be changed by somebody else in the future.

17:06 Instead of telling clojure "use the context classloader", I would rather have a way to tell him: please also try to always use as a last resort this classloader I'm handing you

17:06 once and for all

17:09 ninjudd: well, clojure does that with the parent of DynamicClassLoader, which should be whichever classloader loaded clojure.lang.Compiler

17:09 lpetit: Oh and I also just thought about this one: the context classloader, by definition, is for one thread. I'm not sure at all in OSGi that I have any guarantee that it will always be this thread that will be used when accessing e.g. RT ?

17:09 ninjudd: IIRC

17:09 lpetit: good point

17:13 lpetit: this part of clojure seems like a total mess to me. if you can convince someone (i.e. stuarthalloway) to clean it up, that would be a very good thing

17:15 lpetit: ninjudd: a real world example of the problem. An AOT class is declared in a bundle A, via the plugin.xml. At some point the eclipse frameworks wants to load the class. I don't know when, I have no control, the class will automatically call clojure in another bundle to initialize its implementation namespace. I have no way to take control in this workflow by superimposing my "classloader-which-will

17:15 -call-back-to-the-calling-bundle-loader" so that clojure will even be able to find the implementation namespace's ".clj" resource

17:16 ninjudd: I'll try, as soon as I seem to know what I'm talking about :)

17:16 ninjudd: http://books.google.com/books?id=CvvdZtzxnAEC&lpg=PP1&ots=3G5cW4y2NJ&dq=stuart%20halloway%20Component%20Development%20java&pg=PA11#v=onepage&q&f=false

17:17 written by stuarthalloway

17:19 lpetit: yeah, i think changing the classloader used by clojure can't be done without a patch

17:19 unless you can control which classloader is used to load clojure.lang.Compile

17:20 lpetit: ninjudd: I can live with such a (probably) tiny patch for the needs of ccw.

17:20 ninjudd: lpetit: but then every user of ccw must use a forked version of clojure

17:22 AWizzArd: ninjudd: were you the guy who implemented a Set that keeps the order of insertion?

17:22 lpetit: ninjudd: no we thought about 2 scenarios with cgrand: one where we totally bypass OSGi and indeed create and wire "on the fly" clojure environments. In this scenario we control which classloader is used to load clojure.lang.Compile. But this scenario does not play well with OSGi when you add AOT compiled classes to the dance. They just never will be able to get a the proper clojure classes,since t

17:22 hey are isolated from OSGi.

17:22 ninjudd: AWizzArd: yes

17:22 lpetit: ninjudd: thanks god no.

17:23 ninjudd: it's been months (if not years) since ccw does not mistake its own clojure environment with each of the user's projects environments :)

17:23 ninjudd: i see. like lein and cake

17:23 AWizzArd: ninjudd: please look into your priv messages

17:24 lpetit: ninjudd: but it's fair to say that users whose job is writing Eclipse plugins could benefit from this new approach (and the patched clojure) if they want the greater repl experience in their own development cycle

17:24 ninjudd: yes, they now do like ccw :-p

17:53 erikcw1: 5

17:54 amalloy: erikcw1: 11

17:55 erikcw1: I have a string that contains some html. I'm trying to process it with enlive, but I can't figure out how to get started. Any ideas?

17:58 raek: I suspect that you could pass an instance of java.io.StringReader ot html-resource (note: I have not tested this)

17:58 erikcw1: raek: thanks -- I'll try that. I still have a heck of a lot more Python in my head than Java

17:59 raek: hrm, maybe you need to pass an java.io.StringInputStream instead...

18:01 here's the multimethod that handles how a resource is made from the argument: http://github.com/cgrand/enlive/blob/master/src/net/cgrand/enlive_html.clj#L49

18:01 erikcw1: I was just looking at that, looks like it takes both a java.io.Read and an InputStream

18:02 raek: ah, didn't see the Reader part...

18:02 erikcw1: what's the difference between a Reader and a Stream?

18:02 raek: using a Reader would be preferred

18:02 lpetit: best resource on the subject I've found: http://www.infoq.com/articles/code-generation-with-osgi

18:02 raek: they do characters and bytes, respectively

18:03 strings are character-based, so using a reader avoid any redundant encoding to and decoding from bytes

18:03 erikcw1: ok, makes sense

18:04 you wouldn't happen to know off the top of your head how to render the enlive object back into a string after it has been processed would you?

18:05 raek: I have barely begun using elive :-)

18:05 erikcw1: :)

18:05 raek: iirc, it makes lazy sequences so that the whole document doesn't need to be in memory at once

18:08 erikcw1: raek: (apply str (html/emit* ENLIVE_OBJECT)) does the trick

18:12 raek: ok, neat

18:13 I think Ring accepts sequences of strings as reponse bodys

18:14 (in case you were coding web with some Ring-based framework)

18:20 erikcw1: not using Ring yet. thanks for the info though

18:22 amalloy: raek, erikcw1: Ring does indeed accept seqs of strings. i was reading through the APIs just last night to get my feet wet

18:24 duncanm: i want (contains? [10 20 30 40 50] 50) to return true, which call should i be using instead?

18:25 raek: hrm, I think that new fn was added recently

18:25 it scanned the sequence for the element in linear time

18:26 anyway, using sets are often a better solution

18:26 ,(contains? #{10 20 30 40 50} 50)

18:26 clojurebot: true

18:26 scottj: it was discussed or possibly temporarily introduced but I don't think it made it

18:27 iGNOSaurus: Hi!

18:27 raek: ,(some #{50} [10 20 30 40 50])

18:27 clojurebot: 50

18:27 iGNOSaurus: How do I turn a seq of characters into a string? Sorry for being a noob!

18:27 raek: ,(some #(= % 50) [10 20 30 40 50]) ; if you really need a bool

18:27 clojurebot: true

18:28 duncanm: iGNOSaurus: (apply str s)

18:28 raek: iGNOSaurus: not very obvious, but (apply str [\f \o \o])

18:28 iGNOSaurus: duncanm: Thanks!

18:29 It makes a lot of sense if you know how stuff works. :)

18:29 wwmorgan1: ,(clojure.contrib.seq-utils/includes? [10 20 30 40 50] 50)

18:29 clojurebot: true

18:33 amalloy: duncanm: you probably don't want true anyway, just something non-false; in which case raek's first two examples are perfect depending on whether you can store your stuff as a set or not

18:54 lpetit: ,(some #{false true} false)

18:54 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Boolean

18:54 lpetit: ,(some #{false true} [false])

18:54 clojurebot: nil

18:55 lpetit: I love this one :)

18:55 amalloy: ,(some false? [false])

18:55 clojurebot: true

18:56 lpetit: of course. But for example cannot be used in a generic way (not controlling the set :-))

19:02 abedra: does anyone know how to read a raw device from java?

19:02 i'm trying to capture input from /dev/input/js0

19:02 which I know is spitting out information

19:02 because I can cat /dev/input/js0

19:04 alsocasey: I was wondering whether anyone could offer some insight concerning this aquamacs/SLIME/swank-clojure setup issue I'm struggling with over here?

19:05 specifically, while I can run a standalone REPL just fine, initiating a swank session and connecting to it in Aquamacs leads the REPL to freeze on any but the simplest inputs

19:09 scottj: does it work in normal emacs?

19:11 alsocasey: Haven't tried with standard emacs yet - I was hoping someone might have experienced similar and could provide a quick solution

19:12 amalloy: abedra: it's the same as reading any file, isn't it?

19:12 iGNOSaurus: Is there a really simple way to add a list of characters to a set? That is, the individual characters. :) Thanks again!

19:13 amalloy: (,into #{\a \b} [\n \6])

19:13 iGNOSaurus: I've been watching 5 hours of video, and it seems so simple when other people are doing it. When I type myself most things fail miserably.

19:13 amalloy: ,(into #{\a \b} [\n \6])

19:13 clojurebot: #{\a \b \n \6}

19:14 iGNOSaurus: ,(into #{\a \b} '(\n \6))

19:14 clojurebot: #{\a \b \n \6}

19:14 iGNOSaurus: Thanks! OMG. That is simple. :)

19:14 amalloy: it always is, eventually :)

19:14 iGNOSaurus: Yeah. :)

19:18 amalloy: (use 'clojure.java.io)

19:18 (->> (file "/dev/urandom") reader line-seq (take 2))

19:18 abedra: ^^

19:21 technomancy: alsocasey: aquamacs is not very well supported since it's not cross-platform

19:21 alsocasey: I suppose I'll try again with regular emacs

19:22 abedra: amalloy: i guess it is

19:23 technomancy: alsocasey: could also be an issue with clojure 1.3 if you're using that; swank hasn't been updated for it yet

19:23 ninjudd: alsocasey: i know lancepantz uses aquamacs with swank all the time with no problem.

19:23 but he talks about switching off aquamacs all the time

19:23 alsocasey: technomancy: no, this is using clojure 1.2

19:24 ninjajudd: yes I figured it was something I was missing since Aquamacs seems to be used by others without problems - also "switching off"?

19:25 ninjudd: to plain-old-emacs

19:25 alsocasey: ah - well I'll try that then

19:31 iGNOSaurus: Like, dudes. I'm amazed, my first program. :) Thanks for the help.

19:35 amalloy: what's it do, iGNOSaurus?

19:41 iGNOSaurus: Not much. It reads in a Norwegian dictionary from file, and it picks out the words that uses "allowed" letters.

19:41 A friend of mine, who's a teacher for young children, wanted it. They only know four letters, and she wants to know which words they can learn to spell. :)

19:44 alsocasey: technomancy: sure enough it works fine under regular emacs

19:46 lpetit: if somebody can explain how RT.USE_CONTEXT_CLASSLOADER works, please explain

19:46 ninjudd: not very well ;-)

19:48 lpetit: seems convoluted, and I don't fully grasp why so

19:48 ninjudd: ,(clojure.lang.RT/baseLoader)

19:48 clojurebot: #<DynamicClassLoader clojure.lang.DynamicClassLoader@1fd523d>

19:48 ninjudd: ,(.getParent (clojure.lang.RT/baseLoader))

19:48 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader)

19:48 ninjudd: meh

19:49 ,(println "#<DynamicClassLoader clojure.lang.DynamicClassLoader@169c6f2>")

19:49 clojurebot: #<DynamicClassLoader clojure.lang.DynamicClassLoader@169c6f2>

19:49 ninjudd: that's better ;)

19:49 try it for yourself. the baseLoader is a dynamic classloader, as is it's parent

19:50 which is not right

19:51 lpetit: no, its parent is a FactoryURLClassLoader for me, with cljr and

19:51 ...

19:52 some probably not so old (.getParent (clojure.lang.RT/baseLoader))

19:52 iGNOSaurus: What's the best framework for doing web with Clojure?

19:52 lpetit: 1.2.0-master-SNAPSHOT

19:53 ninjudd: hmm, running clojure from the jar directly i get: DynamicClassLoader -> DynamicClassLoader -> AppClassLoader

19:53 iGNOSaurus: i'm fond of compojure

19:53 iGNOSaurus: Cool, thanks. I'll look at it.

19:54 ninjudd: not quite a framework though. you'll still need a few more pieces for html, javascript, ORM?

19:54 lpetit: anyway, I want to interpose something between DynamicClassLoader and AppClassLoader. If I could make it "generic" or "pluggable", it *could* be an acceptable patch

19:55 ninjudd: lpetit: here is my patch to RT to fix *use-context-classloader*: http://github.com/ninjudd/clojure/commit/4dac03fb2b47a33c77704c00fc9086f4c9b9dc3a

19:55 that's how i think it should work

19:56 lpetit: ninjudd: I' look at it. Please not that I absolutely want to avoid using *use-context-classloader*, though :). Is this "var" intended to be used from outside clojure core ?

19:56 (ok I must really read your post)

19:58 ninjudd: i assume so, but at one point they changed the root binding from false to true to fix a bug. now it is kind of pointless. i believe the right fix would have been changing baseLoader as i have done

20:01 http://github.com/clojure/clojure/commit/b045a379215d1f48e6a2e6cedcdb41526cd5bb25

20:01 i believe that change was prompted by the netbeans problem cemerick mentioned in the thread

20:15 amalloy: iGNOSaurus: http://gist.github.com/596278 is my go at it. probably not as legible as yours, but you might get some neat ideas from it about how expressive clojure is

20:25 lpetit: ninjudd: all this *use-context-classloader* remains opaque to me. Looks like a hack,

20:25 s/remains/stuff remains/

20:25 sexpbot: <lpetit> ninjudd: all this *use-context-classloader* stuff remains opaque to me. Looks like a hack,

20:26 lpetit: ninjudd: in your patch, shouldn't you try to position it to true from within the main.clj ?

20:26 ninjudd: lpetit: agreed seems that it would be better to have a *classloader* var that you can modify the root of

20:28 lpetit: not sure what you mean about main.clj

20:29 oh, you mean to wrap the call to setContextClassLoader with a binding of *use-context-classloader*?

20:30 lpetit: ninjudd: in the changeset of Rich you pointed, there was a conjunction of several changes: on in main.clj to try hard to set the context classloader to a meaningful value, and one to change the value of *u-c-c* so that what has been done in main.clj has a chance to be used

20:30 no

20:30 I mean, in main.clj, set the value of *use-context-classloader* to true, for the REPL thread

20:31 ninjudd: lpetit: that's what i meant when i said "wrap the call to setContextClassloader"

20:31 i wasn't all that clear. should have qualified it with: in the repl function

20:32 lpetit: ninjudd: sorry I dindn't understand that. I thought you hoped that just calling binding for the duration of the setContextClassloader() method call

20:33 ninjudd: oh, right. you would have to bind it for longer than that. good point

20:34 lpetit: i don't think the setContextClassLoader is necessary with the the fix to baseLoader. that is what is causing the double-parent problem i pointed out

20:35 (which may be why you didn't see it in cljr)

20:35 lpetit: guess we'll have to block rich hickey in some corner at the clojure conj to know the final word about all this :)

20:36 ninjudd: hehe. and stuarthalloway since he "wrote the chapter" on classloaders ;-)

20:37 lpetit: huh ?

20:37 ninjudd: i sent the link before

20:37 http://books.google.com/books?id=CvvdZtzxnAEC&lpg=PP1&ots=3G5cW4y2NJ&dq=stuart%20halloway%20Component%20Development%20java&pg=PA11#v=onepage&q&f=false

20:39 lpetit: oh ok ;)

20:40 ninjudd: lpetit: yep. cljr does its own classloader magic: http://github.com/liebke/cljr/blob/master/src/main/resources/cljr/main.clj#L95

20:42 lpetit: ninjudd: why does he store previous-classloader but not use it ?

20:43 Again an example of use of the context class loader as if it were in full control of the whole world :-(

20:44 works for the REPL, from a Request thread in a webapp, but, again, not in an OSGi context :-( :-(

20:44 anyway thanks for the link !

20:51 ninjudd: lpetit: no problem

20:52 lpetit: for your case, would *classloader* be sufficient? assuming you could alter the root to be your modified classloader

20:53 lpetit: I guess so

20:55 I am in control of the first invocation of a clojure class. e.g. I call Class.forName("clojure.lang.RT"). If just after that I set the root of *classloader* to be my own, then it's ok

20:57 but isn't this a problem that for its core initialization, clojure would have used as its root a "temporary" classloader. I should ensure that the "old" *classloader* of clojure is the root classloader of my own, right ?

21:00 ninjudd: if we don't want to break anything, we must keep it in place, though

21:00 ok, must go to bed (3am here !)

21:00 cu later !

22:25 nroot7: In my program I represent each user as a agent maintaining its own state. This works fine w.r.t. to concurrency but what if I want to persist this state in a non-volatile way. Is this a common pattern in clojure world ? How is it implemented ?

22:30 technomancy: nroot7: if 100% absolute consistency is not a requirement, you can have a watcher on your agent that serializes to disk

22:31 nroot7: technomancy: thanks

23:36 bhenry: how can i make this happen?

23:36 [:option {:value "123"} "Item" ] => [:option {:value "123" :selected true} "Item" ]

23:38 wwmorgan1: ,(assoc-in [:option {:value "123"} "Item" ] [1 :selected] true) ;If you can guarantee that your data structure will be a vector

23:38 clojurebot: [:option {:selected true, :value "123"} "Item"]

23:40 bhenry: oh duh. i was looking right at assoc-in and forgot the key didn't already have to exist.

23:41 wwmorgan1: ,(assoc-in {} [:a :b] :c) ; :-) You can do multiple levels of nesting too

23:41 clojurebot: {:a {:b :c}}

23:47 technomancy: it looks like in some situations clojure.walk treats MapEntries as distinct items, while sometimes it doesn't

23:47 I don't suppose that's intentional?

Logging service provided by n01se.net