#clojure log - Sep 28 2010

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

0:06 amalloy: technomancy: neat. have you thought about allowing more than one mock setting? then the user could, say, mock out either the URL-fetch module or the disk I/O module to test the other one

0:06 obviously i haven't thought that through for more than a minute or so, but it doesn't sound like a totally crazy idea

0:36 technomancy: amalloy: that could work, but I think it would be easier to do outside the hook

0:37 you have to bend over backwards to get stuff to work in a hook since everything has to be serializable; you end up wrapping functions that construct forms rather than just wrapping the actual calls

0:39 (I mean when you hook eval-in-project; it's not bending over backwards to hook normal functions)

0:46 TheBusby: technomancy: sorry to change subjects, but is there any interest in replacing ant for process control with a posix JNI library? I'm looking at potentially open sourcing a library and wonder if it would have any value.

0:50 technomancy: TheBusby: I think I'd be interested, but I would be very interested if you could help with integrating it.

0:51 ant is basically a disaster when it comes to unix process management, but I know nothing about JNI and very little about process management APIs (just enough to recognize when things are broken beyond repair)

0:52 TheBusby: my alternative is to create a custom classloader, which hiredman has been bugging me to do for a while now

0:52 TheBusby: In terms of leiningen I'm certain it would be very helpful, but may have issues with portability on non-posix systems (windows, linux, mac are currently supported)

0:53 from what I've read, Ant just does the best it can and that the JVM is a disaster in regards to process management...

0:53 slyrus_: a clojure port to a symbolics lisp machine, for instance?

0:53 technomancy: I have heard of one guy running it on Solaris, but as far as I'm concerned if it makes it work better on the big 3 it's absolutely worth the sacrifice

0:53 TheBusby: right; that's probably more accurate

0:53 TheBusby: no promises yet, I need to get a sign off first; but I wanted to see if you'd be interested before pursuing it.

0:54 technomancy: sounds good

0:54 amalloy: nooooo, technomancy, you can't cut off my precious VAX-11!

0:54 slyrus_: technomancy: the big three are linux, freebsd and macos?

0:54 :)

0:55 technomancy: slyrus_: close enough =)

1:23 msf_: technomancy: is there any way to get lein to install mutliple binaries when using :shell-wrapper ?

1:30 technomancy: msf_: not yet; if you'd like to suggest some ideas for how that would work could you start a thread on the leiningen mailing list?

1:31 I didn't want to complicate the API up front; I am just glad people are actually using the feature. =)

1:31 but it's definitely on the table for the next release

1:38 amalloy: what's this shell-wrapper feature? it builds a .sh (or .bat?) file that invokes java -jar with the right options?

1:39 msf: technomancy: well I'm not sure that I am the right person to suggest how it would work :-)

1:39 but I definitely have a need right now to have a bunch of different "binaries" in one project

1:42 amalloy: msf: is there a reason not to make multiple packages which depend on each other and each have a single binary?

1:42 msf: yes

1:42 I suppose I could split everything out into multiple projects

1:43 amalloy: i mean, granted, that's just working around your build tool, if it's all conceptually one project

1:44 msf: it's all conceptually one project unfortunately

1:45 I have a bunch of different components that each could use it's own wrapper

1:45 a worker daemon, a simple command line client, and eventually a web ui

1:45 amalloy: and i assume it would also look weird to have one binary that takes options?

1:45 ./myproj --mode=1

2:06 technomancy: there's a separate plugin to make init.d scripts that might be more appropriate for the daemon

2:06 http://github.com/zkim/leiningen-init-script

2:10 scottj: there's also lein-daemon

2:11 amalloy: guys those sounds awesome

2:13 by the way, technomancy/ninjudd, how compatible are lein/cake? i know cake supports most of the commands that lein does out of the box, but eg do they use the same plugin framework so that plugins are compatible?

2:14 (as they say on radio shows, i'll take my answer off the air - gonna be afk a bit)

2:14 technomancy: amalloy: no, leiningen plugins are clojure functions, while cake created its own task mechanism

2:16 there are compatibilities between the two project.clj formats, but they are mostly superficial beyond the dependency specifiers IIUC

2:18 andyfingerhut: technomancy: Have you noticed that one of the top Google hits for leiningen is "Leiningen versus the Ants", a 1938 short story? I thought the name was pretty funny. Coincidence?

2:18 technomancy: andyfingerhut: no coincidence at all

2:18 that story is the inspiration behind the software

2:19 andyfingerhut: That seemed more likely than coincidence.

2:19 technomancy: the story of one man using his quick wit to defeat the chaotic forces of nature

2:42 amalloy: i notice that emacs's M-x shell allows you to overwrite the shell-written stuff like prompts. i know it has support for read-only portions of buffers; is there an easy way to make that stuff non-editable?

3:18 LauJensen: Good morning all

3:19 amalloy: morning lau

3:20 (PS did you get a highlight this time?)

3:23 LauJensen: hmm, no - I'll go to .emacs

3:24 can you try again?

3:25 amalloy ^^

3:25 amalloy: morning lau

3:25 LauJensen: And it works!, thanks :)

3:25 amalloy: what was wrong?

3:25 LauJensen: I think I had tried to avoid being highlighted on "launch", but went too far

3:25 lypanov: is there a "lein run" or something?

3:26 LauJensen: lypanov: "cake run"

3:26 amalloy: LauJensen: using a regex or something?

3:26 LauJensen: amalloy: no

3:26 "lau "

3:26 amalloy: i see

3:27 cake run! that is just the best thing ever. "Hey computer, I'm gonna go on a cake run, do you want anything?"

3:29 lypanov: LauJensen: stable?

3:29 LauJensen: as in, you using & enjoying?

3:29 LauJensen: yes, yes and yes!

3:29 * lypanov likes the sound of the persistent jvm feature

3:29 lypanov: cool. switching. thx LauJensen

3:30 LauJensen: np

3:31 amalloy: LauJensen: could you use a regex if you wanted to? eg /\b(?iLau(Jensen)?|Jensen)\b/ is kinda hacky but simple and ought to be pretty good

3:32 LauJensen: I didn't know erc-keywords accepted regexes.. Does that handle case as well ? (upper/lower)

3:32 amalloy: i don't know if it does accept regexes; i was asking you

3:32 LauJensen: ah right, my mind swapped "could you"

3:33 amalloy: but if it does, then yes, a PCRE engine will treat that case-insensitively (the (?i) modifier)

3:33 LauJensen: Documentation:

3:33 List of keywords to highlight in all incoming messages.

3:33 Each entry in the list is either a regexp, or a cons cell with the

3:33 regexp in the car and the face to use in the cdr. If no face is

3:33 specified, `erc-keyword-face' is used.


3:33 Cool :)

3:34 Its installed now, could you try highlighting me amalloy ?

3:34 amalloy: LauJensen: fair warning, though, not all regex engines are perl-compatible; the one grep uses by default is awful unless you switch on -e or -P

3:35 (highlighting lau in case the other message was too soon)

3:35 LauJensen: hmmm

3:35 please repeat

3:36 amalloy: LauJensen: you mean your name, or clarify about PCRE?

3:36 LauJensen: <amalloy> (highlighting lau in case the other message was too soon)

3:36 Just write that again please

3:36 amalloy: (highlighting lau in case the other message was too soon)

3:36 LauJensen: hmm, its not working, but I know where to go, thanks for the input amalloy

3:37 Good morning rberger

3:38 rberger: Good Morning!

3:38 amalloy: oh. just tried it out in perl; i was using the wrong syntax for ?i. try thiis instead, LauJensen: /\b((?i)Lau(Jensen)?|Jensen)\b/

3:40 AWizzArd: ~max people

3:40 clojurebot: max people is 313

3:41 LauJensen: amalloy: Could you step into #conjlabs for a second?

3:47 yayitswei: are there any Clojure http libraries that use the java.net.URLConnection class? reason I ask is because that's the only accepted way of doing http connections on Google App Engine, according to these docs (http://code.google.com/appengine/docs/java/urlfetch/usingjavanet.html)

3:47 LauJensen: yayitswei: did you check out clojure.contrib.http.agent?

3:49 yayitswei: LauJensen: will try it now, thanks. was previously using com.twinql.clojure.http, which gave me an java.security.AccessControlException running on GAE

3:57 amalloy: g'night folks

4:12 tobiasraeder: Hey :)

4:13 Is there any way in clojure to create a clojure object that represents an interface? For example that i can call (.isInterface object) and it returns true? (I need it for java interop and can't touch the java code)

4:24 Chousuke: tobiasraeder: you can use reify

4:24 or hm

4:25 do you mean actually creating an interface?

4:25 for that there's definterface

4:25 tobiasraeder: ah okay

4:25 yeah i mean actually creating the interface

4:26 ty seems like it is exactly what i was looking for.

5:04 kjeldahl: I've managed to connect to postgresql through clojure.contrib.sql, but the clj-record stuff isn't cooperating. Anybody on who've used clj-record?

5:17 Sometimes when I run "lein deps" I get a NullPointerException. Immediately running it again then works fine. Can anybody explain why?

5:32 LauJensen: kjeldahl: you mispelled 'cake' and wrote 'lein' instead

5:33 kjeldahl: Is that a not-so-subtle hint again that I'm using the wrong tool?

5:34 Anyway, my clojure.contrib.sql / clj-record trouble was solved by upgrading lein-swank to 1.2.0-SNAPSHOT. Found the thread that discussed the bug (something about printing inside the sql module).

5:35 tobiasraeder: Anybody ever used a macro to generate an interface using definterface and provided typehints for the generated interface functions?

5:35 kjeldahl: I'll try to install cake. Is this the right repo: http://github.com/ninjudd/cake

5:37 bobo_: kjeldahl: yes

5:37 tobiasraeder: Anybody can give me a quick downrun on the advantages of cake over leiningen?

5:38 kjeldahl: bobo_: Thanks.

5:40 Chousuke: tobiasraeder: are you having trouble doing that? :)

5:41 tobiasraeder: when you generate code in a macro, you can't always use the reader metadata syntax. You can however attach metadata to the symbols manually, using with-meta

5:41 bobo_: tobiasraeder: persistent vm, ruby hoock instead of bash, you wont have LauJensen nagging you to change and so on :-)

5:41 tobiasraeder: @Chousuke what im trying to generate is (definterface interf# (^String getName[]) (^Void setName[name]))

5:42 kjeldahl: Since there is no cake-swank to put in project.clj, I'll assume lein-swank is ok? ;-)

5:42 Eh, if I can get it running that is.

5:42 Chousuke: tobiasraeder: why are you generating an anonymous interface? what use is that? :/

5:42 LauJensen: kjeldahl: yea, lein-swank is fine, cake is a drop-in replacement

5:42 Chousuke: tobiasraeder: anyway, that should work just fine

5:43 zmila: ,(doc map-indexed)

5:43 clojurebot: "([f coll]); Returns a lazy sequence consisting of the result of applying f to 0 and the first item of coll, followed by applying f to 1 and the second item in coll, etc, until coll is exhausted. Thus function f should accept 2 arguments, index and item."

5:43 tobiasraeder: @Chousuke its some really stupid java code which i have to interop with where i have to supply an interface and a class that implements said interface which then generates some objects via reflection

5:43 kjeldahl: Nice, thanks. Works fine.

5:43 Chousuke: maybe ^void instead of ^Void?

5:43 tobiasraeder: urgh.

5:43 tobiasraeder: @Chousuke yeah and cant change the java side :/

5:43 @Chousuke and i got no idea where to attach the return value typehints to :s

5:44 Chousuke: I think you have them in the right place. though I'm not sure

5:45 tobiasraeder: @Chousuke yeah that definterface works fine but if i try to create that from a macro i cant seem to place the typehints for the return values

5:45 Chousuke: hmh

5:46 try ~'^String foo

5:46 tobiasraeder: ill try, ty

5:46 Chousuke: maybe the namespace resolution in ` is messing up the metadata somehow

5:47 I'm not sure if that works either but it's the only thing I can think of :P

5:47 until someone who knows definterface better comes and saves the day

5:47 tobiasraeder: alright, thank you for the input. ill let you know if i get it to work

5:50 Chousuke: it seems definterface has no documentation. :|

5:51 but it's probably similar to reify

5:51 ie. return type hint goes on method name

5:52 tobiasraeder: maybe it would be easier to use a protocol or something

5:52 tobiasraeder: since a protocol generates a matching interface

5:53 tobiasraeder: @Chosuke tried that but i need to pass an object to the java code and that object has to be the class of the interface which is then checked with .isInterface etc to make sure it is an interface and that the supplied object implements the interface

5:53 Chousuke: so you can create a protocol, then a deftype/reify object/defrecord that implements the protocol, and pass the interface and that object to the java code

5:53 tobiasraeder: how do i get the interface classname?

5:53 Chousuke: it's the same as the protocol I think

5:54 ie your.namespace.here.Protocol (instead of your.namespace.here/Protocol which gives you the protocol object.)

5:54 tobiasraeder: ah

5:54 ill try that

5:56 Chousuke: see the documentation for protocols for more hints. http://clojure.org/protocols

5:56 tobiasraeder: yeah that seems to do the job. thank you very much.

5:57 is there a way to get namespace.protocol automaticly if i just have the protocol var at hand?

5:57 Chousuke: I'm not sure.

5:58 tobiasraeder: alright

5:59 esj: 11

6:04 kjeldahl: Am I right concluding that clj-record assumes the primary key on all tables is named "id"?

6:05 Must be, with code like this: (sql/delete-rows (table-name model-name) ["id = ?" (:id record)])

6:11 tobiasraeder: yeah

6:12 kjeldahl: Ding! Clojure, through clj-record, managed to put in a row in my postgresql database. Baby steps, I know. :-)

6:12 tobiasraeder: Still nice! :)

6:12 * kjeldahl deserves lunch. Thanks all.

6:13 tobiasraeder: enjoy.

6:13 pomyk: when I run cake I get: Exception in thread "main" java.io.FileNotFoundException: Could not locate clojure/java/io__init.class or clojure/java/io.clj on classpath: (io.clj:1)

6:16 kjeldahl: Is the book "Programming Clojure" free? While bughunting search for clj-record stuff I found it downloadable as a pdf on the net. If it's not free the author may want to know. Looks like a chinese site.

6:17 Chousuke: It's not free.

6:18 kjeldahl: Ok, I'll alert the author directly (assuming I can find his email address).

6:22 esj: that didn't take long

6:23 kjeldahl: Alerted support@pragprog.com (found it in the book... ;-)

6:25 LauJensen: esj: and its not the first time either

6:26 esj: sucks

6:26 LauJensen: Everybody (not me) loves piracy, except when it happens to someone you know

6:33 tomoj: hmm, my macro does (loop [count# ~count] ..), where in this case count contains the symbol 'count, which refers back to a different let binding (let [count ...])

6:33 I think this is not going so well

6:37 Chousuke: :P

6:41 esj: ouch

6:51 tomoj: how many counts can a count macro count if a count macro could count counts ?

6:59 tobiasraeder: It's probably i really dumb question but how do i defince a protocol inside a macro and use it properly? i tried

6:59 (defmacro mymacro [] `(defprotocol myprotocol) `(str *ns* "." myprotocol))

7:00 which tell's me that user/myprotocol isn't defined

7:00 *define

7:00 the error occurs when i (macroexpand (mymacro))

7:04 arbscht: tobiasraeder: (macroexpand (mymacro)) evaluates (mymacro). instead try (macroexpand '(mymacro))

7:05 tobiasraeder: @arbscht ah, thank you. i somehow always forget the leading '

7:07 tomoj: hmm, is there a simple way to create a tcp proxy in clojure? I just want to forward all the bytes that come in to some remote host, and forward all bytes from the remote host back, but also run processing on them

7:07 now I've got 2 inputstreams and 2 outputstreams and don't know what to do

7:16 bmh: Is it possible to do upper_bound and lower_bound queries on sorted maps?

7:17 (log time queries, that is)

7:20 LauJensen: ,(filter #(< 5 % 10) (apply sorted-set (range 20)))

7:20 clojurebot: (6 7 8 9)

7:20 LauJensen: bmh: You mean that kind of thing?

7:22 tobiasraeder: Is there a way to get the Class object based on a string with the class name within clojure? (the same as would be returned by (class object)

7:23 bmh: LauJensen: more like...

7:23 http://www.cplusplus.com/reference/stl/map/upper_bound/

7:25 LauJensen: bmh: exchange filter for drop-while and you'll effectively have a seq starting where you want

7:26 bmh: LauJensen: Sure. I know how to write the linear time version. Won't calling drop-while on a sorted-map just walk the elements?

7:26 LauJensen: bmh: yea, but sorted sets dont support access on index

7:27 bmh: %s/sorted-set/sorte-map/

7:28 LauJensen: same story

7:29 mrBliss: ,(Class/forName "java.lang.String")

7:29 clojurebot: java.lang.String

7:29 mrBliss: tobiasraeder: ^^

7:29 bmh: none of this hinges on index access. The idea is to get the first entry that is strictly greater than the search key, or the last entry that is <= to the search key

7:31 tobiasraeder: @mrBliss thank you.

7:43 bmh: hey dnolen

7:43 dnolen: bmh: hullo

7:47 LauJensen: bmh: You could try asking your question again for dnolen, he might have a good idea

7:48 bmh: alright

7:48 dnolen: are you familiar with the STL?

7:50 dnolen: bmh: heh, not particularly no. but reading the back log if you're using a sorted set why not just use first, last ?

7:50 ,(first (apply sorted-set [100 1 50]))

7:50 clojurebot: 1

7:50 dnolen: ,(last (apply sorted-set [100 1 50]))

7:50 clojurebot: 100

7:51 dnolen: ,(last (conj (apply sorted-set [100 1 50]) 20))

7:51 clojurebot: 100

7:51 bmh: [1 2 3 4 6 7 8 9], give me the first element greater than 5 in log time

7:56 rhickey: Are there plans to expose PersistentQueue?

7:58 rhickey: bmh: perhaps - enough people seem to use it

8:02 Raynes: Why aren't there docs for the clojure.java namespaces here? http://clojure.github.com/clojure/

8:02 lpetit: Hello

8:03 LauJensen: lpetit: Howdy

8:03 lpetit: rhickey: I managed to make things fit together. We may be close to a happy end to *some* "story" between clojure and OSGi

8:03 rhickey: lpetit: great! what worked?

8:03 lpetit: I had to patch clojure in several areas, though. 3 areas, to be precise

8:04 dnolen: bmh: yeah, no way to do that I can see. Though the tools are there to build such a data structure I think.

8:04 lpetit: 1. your suggestion was necessary. Placing an additional pushLOADER() right after pushNS() in the bytecode of AOTed classes load()

8:04 bmh: dnolen: ah-ha. subseq and rsubseq seem to do the right thing

8:05 cemerick: lpetit: Neil Bartlett and aav were in here yesterday afternoon kibitzing on the osgi issues. There's a google doc where they've started lining up requirements; maybe you can throw in with them, as they have a pile of osgi expertise (but probably less Clojure know-how than you?).

8:05 LauJensen: kibitzing?

8:05 cemerick: indeed :-)

8:06 lpetit: http://bit.ly/clojureosgi

8:06 dnolen: bmh: nice, did not know that, my Clojure-fu is still at a fledgling level :)

8:07 Raynes: $dict kibitz

8:07 sexpbot: Raynes: verb: make unwanted and intrusive comments

8:07 Raynes: Interesting. Never heard that one before.

8:07 cemerick: that's not right

8:07 according to google: 2. Speak informally; chat.

8:08 Raynes: I believe Wordnik and Google use some of the same sources.

8:08 So, that's odd.

8:08 cemerick: Oh, it had one of the definitions, just not the one I was using.

8:08 lpetit: 2. ninjudd reported, a while back, and among other things, a problem in Compiler$ImportExpr. Initial emit: gen.invokeStatic(CLASS_TYPE, Method.getMethod("Class forName(String)")). Patched emit: gen.invokeStatic(RT_TYPE, Method.getMethod("Class classForName(String)"))

8:09 cemerick: so s/right/what I meant :-)

8:09 lpetit: But then there was still a problem.

8:09 rhickey: and here's where I made the third patch, and were I need your help to see whether it makes sense in all cases (I'm pretty confident with patch 2, but maybe you have also something to say 'bout it ?)

8:10 rhickey: maybe we could verify that patch 2. makes sense before I speak about patch 3, to keep things simple

8:11 cemerick: interesting. I have also created a google doc summarizing what I've found, and what is explained here (though it's more personal notes than meant to be shared with others)

8:11 LauJensen: lpetit: link? :)

8:12 lpetit: LauJensen: when it's cleaned up, yes. If everything is accepted by Rich, I do not totally exclude writing a blog post on the subject (would be my first one !)

8:12 LauJensen: Cant I get a preview?

8:13 cemerick: lpetit: Sounds like a good start. I figure the three of you will be able to cover all the necessary ground. FWIW, they didn't actually think that patching clojure was necessary at this point, so I suspect some cross-pollination would be a net gain.

8:13 lpetit: LauJensen: I prefer focusing on potential issues, one by one, here first, then update my document (if it still makes sense). No need to present everything at once if there's crap inside

8:13 LauJensen: (-> lpetit kibitzing cross-pollination) = net gain

8:15 lpetit: Hopefully Rich will have some time accepting / rejecting my point 2. Then I'll talk about point 3. If both seem valid, then yes, it will become interesting that more eyes look at what I did. If not, it would just waste the time of others :-)

8:16 cemerick: I'll look at the doc. I must first verify that we're on the same "story".

8:16 cemerick: (not to say that one "story" would be better than the other, though)

8:17 cemerick: the patches for clojure are really this: bug patches. Not additional features. So they are somehow "right". "debugged" clojure should work with OSGi without architectural change.

8:17 cemerick: lpetit: Presumably, the ideal would be for a generalized set of solutions to be explored. I'm sure there are a number of use cases crossed with however many container implementations exist.

8:18 lpetit: cemerick: in my "story", the only difference between containers is on how they use the context class loader for greater good, and things may change on how bundle creators leverage those OSGi-imple context classloader specificities.

8:19 cemerick: but I also have locally a solution which is fully implementation agnostic.

8:20 cemerick: the solution leverages the existing public OSGi APIs to create a custom ClassLoader injected into Compiler.LOADER's root.

8:21 cemerick: lpetit: sounds like a winner to me, but then I know fairly little about OSGi at this point. :-)

8:22 lpetit: cemerick: started to read the doc. Seems we are not totally on the same "story".

8:23 cemerick: lpetit: well, you have edit on it now -- by all means, contribute as you see fit :-)

8:23 lpetit: cemerick: thanks

8:29 cemerick: the "story" in the document is unclear to me. Here is mine: if the clojure bundle is named "clojure", if bundles "b1" and "b2" must use clojure, then they will have bundle "clojure" as their dependency. Sharing the same "clojure" bundle implies sharing the same clojure "world". So b1 and b2 can require/use namespaces from each other. There is a "web" of interconnected bundles : all the bundles that depend on the clojure b

8:30 cemerick: with this vision, if there are several "applications" loaded in the same OSGi environment, if you want to separarate them, then each of them must provide its own clojure bundle.

8:31 cemerick: lpetit: I *think* that that's what they're aiming for as well. Best way to check is to add that scenario/perspective to the doc and see if they agree.

8:31 lpetit: cemerick: this simplifies things well, while not over-simplifying them, IMHO. As a result, using clojure correctly in e.g. Eclipse/Equinox is just a matter of applying the 3 patches I've gathered to clojure code (because currently in some areas the context classloader is not used), and using one of the "buddy" policies of Eclipse, the simplest being the "dependent" policy.

8:31 aav: cemerick: it's nothing wrong with this scenario

8:31 lpetit: aav: hello

8:32 aav: lpetit, cemerick: hi!

8:32 cemerick: aav: hi again :-D

8:32 * cemerick steps away so the experts can kibitz more ;-)

8:32 lpetit: aav: it's this requirement which alerted me : "4. Clojure source SHOULD NOT have visibility of other clojure sources, that are not available to the hosting bundle"

8:33 aav: lpetit: added by me :)

8:33 lpetit: the point was to be as close as possible to osgi behaviour with regards to package visibility

8:34 lpetit: aav: and contradictory with the story I described and you just acknowledged to be yours too. With my "story", clojure source of bundles b1 and b2 share the same clojure env, so they have 'visibility' on each other

8:36 aav: lpetit: they share, but nothing prevents us from "artificial failing" of attempts to requre/use/etc from packages that are not available

8:36 * rhickey had to step away, reading...

8:37 aav: otherwise it will get very confusing, i'm afraid

8:37 lpetit: aav: IMHO, such fine grained separation will not be easy (if feasible at all) with clojure until modularization concerns are taken into account at the core of clojure (ns n1 depends on version 2 of ns n2 ; possibility to have several "sets/worlds" of ns handled by the same clojure environment, etc.). And even when clojure's state of affair reaches this modularity level at clojure code level, things will be complicated with all AOT

8:39 aav: lpetit: proper separation will not be easy. but i see a possible compromise.

8:40 lpetit: aav: Above all, I'm questioning not the technical feasibility, but rather the goal one wants to achieve, the use cases one wants to support. I'm unclear about yours. I hope mine (as described above) is clear and without shadow ;-)

8:41 aav: lpetit: i would like to have consistent (as far as possible) behaviour for clojure and native java part of a system

8:43 i.e. I have a project, that contains a lot of java code and clojure code at the same time. i want to have more or less same rules when it comes to visibility and loading of anything

8:43 lpetit: aav: will get confusing if some bundles "hijack" your bundle, indeed. But what we're mainly talking about is bundles sharing code via classloaders, not leveraging OSGi services (that's another story, will be interesting to provide a layer above OSGi API to ease the write of such services, as has been done recently by somebody for google AppEngine with appengine-magic)

8:43 aav: my story may be "too simple" for you (and I can hear that), but it is consistent.

8:44 aav: I understand

8:44 rhickey: lpetit: #2 is a definite problem. In fact, ImportExpr specifically exists to better support modularity. One thing all of the module systems leverage are calls to Class.forName. But Class.forName walks the stack (to find the invoker class and it's loader) and thus can't be proxied or nested. For this reason, prior to import being a macro, it could never do the right thing. Now it does and you want to change it back :(

8:45 jjido: can you do multiple dispatch on more than just the first arg with a protocol function?

8:45 cemerick: jjido: nope; such cases call for multimethods

8:46 * lpetit just got his day ruined by rhickey :'-(

8:46 rhickey: lpetit: I predict changing import to use RT.classForName will break many things in OSGi

8:47 import was improved because of complaints about not playing well with modularity systems.

8:48 jjido: cemerick: so I should define my multimethod outside the protocol? I guess I will just do a instance? check for now

8:48 rhickey: if the modularity system has assigned a classloader for some ns X, then you want its imports to use that classloader

8:48 lpetit: rhickey: that's sad. What's even more sad is that I don't understand

8:49 cemerick: jjido: if you have a protocol, but you need some kind of dispatch / switch based on a condition besides the type of the first arg, then you need to fall back to a regular conditional

8:49 rhickey: lpetit: what I expected from that exercise yesterday was a request from you for a hook to allow you to root the dynamic classloader you create in static init

8:49 cemerick: or you might be able to map in a multimethod as the impl of a protocol for a particular type via extend, etc

8:49 jjido: cemerick : got it

8:51 lpetit: rhickey: but before I did point 2.'s change, I had this exact problem: no visibility from the clojure bundle to the class, because the clojure bundle does not depend on the using bundle (or there would be a circular dependency between the 2). Letting the context classloader 's OSGi impl do its magic allows the import to just work.

8:51 aav: rhickey: what i'm doing now is simply setting a context classloader to an appropriate one (related to the bundle, .clj file is loaded from)

8:53 lpetit: aav: are you able to do that without patching clojure ? (either a patch at the java source code level, or a patch leveraging the possibility of redefining in clojure some vars in clojure.core ?)

8:53 aav: yes

8:53 no clojure patches were needed

8:53 rhickey: lpetit: but it's not the clojure bundle doing the import. import is a macro that gens Class.forName with the scope and access of the caller

8:54 that was the whol;e point of the changes to import and making import a macro + special op

8:54 aav: the only dity trick i do - substitute clojure's load function

8:55 lpetit: rhickey: which caller ? are we able to know who the caller is ? are we able to take control of the context classloader before/after the call ?

8:55 rhickey: lpetit: caller is the code that has the word import or :import in it

8:55 lpetit: aav: and now if that's not patching clojure by leveraging the possibility to redefine some clojure.core vars, please tell me what it is ! :)

8:56 aav: (defn osgi-require [name]

8:56 (binding [load osgi-load]

8:56 (require name)

8:56 )

8:56 )

8:56 i'm not sure if this is very elegant. but it works...

8:56 lpetit: aav: interesting, though

8:57 rhickey: lpetit: but it seems you are trying to work around OSGi wather than with it. If OSGi had a loader it liked for the module, than that loader should work fine for its imports.

8:57 lpetit: rhickey: quite true.

8:58 rhickey: lpetit: I'm a bit confused as to how you are establishing deps between bundles. Are you trying to supplant OSGi in this area?

8:58 aav: lpetit: take a look at http://github.com/aav/clojure.osgi - it's very minimalistic, but it works

8:58 lpetit: Hmm, but my problems where real .... I did not add this patch upfront ...

8:58 rhickey: no

8:59 rhickey: but as said before, I leverage Equinox's "buddy" policy ("dependent" in my case) so that class/resource resolution is bidirectional when using the context class loader

9:01 rhickey: lpetit: to what did you bind Compiler.LOADER in the AOT class static init?

9:03 lpetit: rhickey: to RT.makeClassLoader()

9:04 fliebel: Does self have any special meaning in Clojure I'm unaware of?

9:05 lpetit: rhickey: but there's a missing implicit part in my story. My story is about getting "as dynamic" as possible when developing in an OSGi environement. That is as few AOT compilation as possible (just for the required parts when legacy java classes need to find the AOTed class, just for when the class will be loading from declarative settings).

9:05 jjido: fliebel: usually not

9:06 lpetit: rhickey: so no unnecessary AOT compiled namespaces. When you talked about the "caller", weren't you implying the caller was an AOT compiled namespace ?

9:06 rhickey: lpetit: that won't work, you need to root the dynamic classloader to the loader being used by OSGi to load the class being initialized

9:06 fliebel: jjido: Thanks. I'm having a weird error, and it wouldn't be the first time it was because of a var nam shadowing something else.

9:06 rhickey: lpetit: AOT or not, the class gets compiled and call import

9:07 but yes, I was talking about AOT with the static stuff, sinc ethat was your problem yesterday

9:08 lpetit: rhickey: ccw already works with OSGi with fully AOTed code for a while (so maybe I did not get rid of the transitively compiled namespaces from other bundles after the compilation, hmmm)

9:10 rhickey: lpetit: I'm confused

9:10 yesterday - lpetit: rhickey: how does an AOT compiled gen-class, when loaded from plain old java class (for example), initialize itself ?

9:10 * aav is also confused. and don't really understand what is the problem

9:12 AWizzArd: I may be the first developer who experienced a real code break through the change of primitives. But: this is most likely due to a bug. I create somewhere (Integer. "123") and this info gets lost, and I end up having a long.

9:13 As my code was working with byte streams I expected Ints and read 4 bytes. But what I wrote were Longs, so I should have read 8 bytes instead, with the new clojure.jar.

9:13 I assume that the issue that I filed yesterday will solve this.

9:14 It is probably the same thing as this Integer/valueOf thing.

9:17 lpetit: rhickey: In my real-world scenario, there will be some gen-classes, and a bunch of regular ns as .clj files.

9:18 rhickey: lpetit: I think you should look carefully at what aav posted

9:18 lpetit: rhickey: I will, though later, must go back to work :-/

9:18 rhickey: me too

9:18 lpetit: aav: thanks for sharing, hope to be able to look at this tonigh

9:18 rhickey: thanks again for your time, very much appreciated !

9:29 fliebel: What could be a case where I insert a symbol where I meant inserting a seq? I'm not doing (symbol x) and macroes are involved. "Don't know how to create ISeq from: clojure.lang.Symbol"

9:29 mrBliss: fliebel: can you show the line?

9:30 fliebel: mrBliss: (chain-template template self)but that calls this line: `(en/snippet* (en/html-resource ~rec) [~'headers ~'body] ~@expr))

9:33 mrBliss: fliebel: which functions on that line take seqs? expr is certainly a list? I mean code ;-)

9:34 fliebel: ?

9:35 jk_: does anyone here use eclipse w/counterclockwise plugin?

9:36 fliebel: mrBliss: chain-template is a macro that takes rec and expr as arguments. But I can't see how self/expr can be a symbol.

9:36 mrSpec: Hello!

9:37 I'd like to return result of sql query as a list. is it possible to do (with-connection db (with-query-results foo bar (map #(:user %) foo)) ? I can only do (dorun (map ...)) is it normal?

9:37 mrBliss: ,(let [expr 'self] `(list ~@expr))

9:37 clojurebot: Don't know how to create ISeq from: clojure.lang.Symbol

9:38 mrBliss: fliebel: are you sure self can be spliced?

9:38 (I'm just thinking out loud)

9:38 fliebel: mrBliss: Apparently not…

9:39 lpetit: jk_: yes

9:40 jk_: lpetit: i'm scratching my head over somethign that should be simple. i have 2 files in the project w/2 separate namespaces. i want to use the second file (via :use) in the first but the repl doesn't see the second namespace. what's the trick for getting both files loaded into the repl when it starts?

9:42 lpetit: jk_: I'm confused with your question

9:44 jk_: lpetit: i have a clojure project in counterclockwise. there are 2 source files, each with their own namespace. when I "run" the first file (that ":use"s the second), I can't use any functions from the second file since they aren't seen on the classpath.

9:44 lpetit: jk_: crazy :-/

9:45 jk_: lpetit: crazy??

9:45 lpetit: jk_: I meant "weird"

9:45 jk_: lpetit: have you ever developed on a project with more than a single file in it?

9:45 lpetit: in ccw i mean

9:46 lpetit: jk_: more and more parts of ccw are written in ccw. paredit.clj is written in ccw. The basic stuff you're describing should just work. Or it's a *serious* (critical !) regression.

9:46 jk_: what do you mean by "when I 'run'". What is "run" ?

9:47 LauJensen: jk_: For the serious stuff, lpetit uses Emacs :P

9:47 lpetit: LauJensen: ah ah

9:47 jk_: lpetit: like when you "right click/run" on a source file

9:47 clojurebot: amespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

9:47 jk_: LauJensen: :)

9:49 lpetit: that starts a repl and loads your file but i need that repl to see the other functions in the second file too. it would be nice if it just loaded all the files in your project since the idea of a project is to develop them all together

9:49 lpetit: the :use clause complains that it doesn't see that namespace on the classpath

9:53 lpetit: jk_: "lpetit: the :use clause complains that it doesn't see that namespace on the classpath": this is the weird part. This normally just works.

9:54 jk_: not all files are loaded on startup when invoking "run" on a specific ns file. Just the selected file will be loaded (and all its expressions evaluated, so of course some other namespaces may be loaded as a result of (:require) (:use) placed in the (ns) form

9:55 jk_: lpetit: and the second namespace (in :use) is in the second file in my same project, in the src directory

9:55 lpetit: jk_: if you specifically want *all* your project namespaces to be automatically loaded, don't invoke "run" from a specific file, but from the project's root node. This has the special behaviour you're after: ccw will then try to load every ns in turn

9:55 jk_: lpetit: i thought it would just get loaded automatically

9:55 lpetit: ahh!

9:56 lpetit: jk_: it should be loaded transitively if it's in the (ns) of your other file, though.

9:57 jk_: if file f1 contains "(ns f1 (:use f2))", if file f2.clj contains "(ns f2)", then in this particular case, invoking "run" either on file f1.clj or on the project's root should trigger the load of namespace f2.

9:58 jk_: lpetit: well that's what i thought but figured i must be doing something stupid

9:59 lpetit: jk_: can you share your project eg on github ?

9:59 jk_: lpetit: i need to get ready for work. thanks very much for the input. i'll come back to this and have another look later

9:59 lpetit: jk_: ok, cu

9:59 jk_: lpetit: sure, i can do that later but i'm already gonna be late for a meeting!

10:00 fliebel: mrBliss: Some more debugging reveals that I do put a seq into the function, but inside the macro, printing the arguments gives me just their symbols.

10:03 Well, actually it prints 4 lines, 2 of which I can't make sense and 2 that seem in the wrong order.

10:03 html (last page)

10:03 html (last page)

10:03 template self

10:03 index.html index.md []

10:04 That last line is printed in the fn that calls the macro that printed the first 3 lines.

10:04 Though there is only one print statement in the macro and it is called 2 times. Go figure...

10:07 jk_: lpetit: still there?

10:09 lpetit: i tried another couple of things quickly (i really need to go!) but the problem seems tied to the fact that i changed the namespace values and they didn't match the filename. i reverted to just using the filename for the namespace and it's all working normally

10:09 lpetit: seems like if i want to have a ns "x.y.z" it's tied to a java package x.y, filename z. i think... gotta look more later

10:10 chouser: rhickey: ha! what does it mean that "arbitrary functional destructuring" is now marked for Release.Next?

10:11 rhickey: chouser: you don't want it now?

10:11 scottj: Yeah for improved debugging!

10:12 _fogus_: ooooooo! arbitrary functional destructuring is my favorite.

10:12 chouser: rhickey: I'm not saying that, I just assumed it was dead.

10:15 rhickey: a lot of stuff was held until after 1.2, but then we had to first integrate all of the num/equiv. Now we are in a position to apply more patches

10:15 screening help welcome

10:17 _fogus_: @rhickey: screening?

10:18 cemerick: _fogus_: panning for gold in those assembla hills

10:18 _fogus_: cemerick: Gotcha

10:20 fliebel: Okay, I'm out of ideas. I've been fighting the same bug for days now. The only options I've left is that I'm overlooking something stupid, or a bug in Clojure. Usually it's the first though. I have a macro that should get called with a string and a seq. When I turn it into an fn that prints the args, it prints the expected result. When I have the real thing, it blows up at the splicing part, on a var that was a proper vector in the fn variant. It

10:22 cemerick: fliebel: paste and you shall receive

10:22 _fogus_: Anyone interesting in patches pertaining to any of my "Monkeying" posts? http://blog.fogus.me/tag/monkey/

10:23 fliebel: cemerick: http://github.com/pepijndevos/utterson/blob/develop/src/utterson/compile.clj

10:23 line 101

10:24 _fogus_: Where anyone == rhickey ;-)

10:24 rhickey: fliebel: write the expansion by hand, make sure it works, then macroexpand-1 the macro call and make sure it turns into that expansion

10:25 cemerick: fliebel: I was hoping for something sliced out of its context. The process of doing that often reveals bugs/misconceptions. Barring that, see rhickey ^^

10:25 or, rhickey's advice, I mean

10:25 fliebel: rhickey: I pasted the macor in the repl and called it with the expected arguments, and IIRC it worked.

10:26 cemerick: I'm going to work on that.

10:26 rhickey: fliebel: I am explicitly saying, don't do that

10:26 fliebel: rhickey: I expanded it as well of course, but I'll do some more of that.

10:27 rhickey: calling a macro is the worst way to test it, as two things are happening and you'll have much more difficulty determining where it is going wrong

10:28 tobiasraeder: one quick question, is it possible to construct an interface (using definterface) or a protocol with typehinted functions from a macro? i seem to fail

10:30 fliebel: rhickey: Expanded macro looks good and works.

10:30 rhickey: _fogus_: deftest and comp yes, anaphora, no

10:33 lpetit: rhickey: I've looked at what aav did, and it looks good. It just happen that I've worked too late on the subject the previous night, and I don't have all my cognitive abilities today. Will think about it in "off" mode, and come back later when my mind is clear and (hopefully) with the simplest example demonstrating the problem.

10:33 _fogus_: rhickey: OK great. Is it still anaphora when its explicitly named?

10:33 rhickey: _fogus_: nope

10:34 lpetit: sounds good

10:37 cemerick: rhickey: if you're spelunking in case, perhaps supporting dispatch on referenced static final fields and enums would be worth folding in (i.e. http://cemerick.com/2010/08/03/enhancing-clojures-case-to-evaluate-dispatch-values/)

10:37 The above is flawed, but only in some specifics AFAICT.

10:37 fliebel: When I print something in a macro before the body returned, what should that do?

10:40 In my case, that prints just the exact code inserted.

10:40 On the repl, that prints the values inserted.

10:40 Trying to reproduce.

10:41 that's it!

10:43 cemerick, rhickey: http://gist.github.com/601109

10:45 rhickey: cemerick: so, where's the patch? :)

10:45 fliebel: Removing the splice reveals that indeed just the symbol a is inserted, which can't be spliced.

10:46 cemerick: rhickey: ha! I'll be happy to produce one, though I figure I should wait until you've finished with #426

10:47 fliebel: yup, only seqable things can be spliced in

10:47 fliebel: cemerick: But… the value of c is very much a seq.

10:48 rhickey: cemerick: hrm, you don't want to do 426 as well?

10:48 cemerick: fliebel: the macro a is not splicing in the vector c, it's splicing in the symbol provided to it as argument b.

10:49 AWizzArd: rhickey: would it be possible, if your schedule allows it, to add a (possibly empty) marker Interface for defrecords and deftypes, so that (record? r) and (deftype? d) can be implemented, by simply checking for this Interface?

10:50 cemerick: rhickey: I could, but it won't be for a while; probably not until after the conj, anyway.

10:50 fliebel: cemerick: So what do I do? :(

10:51 cemerick: fliebel: well, that depends on what you *want* to do. Sorry if that sounds pedantic. :-|

10:51 macros operate on code, not runtime values

10:51 e.g. (println (a [1 2 3]))

10:52 you can *refer* to the existing var c, but that's bad practice

10:52 fliebel: cemerick: All I want is to call snippet* with a seq instead of with a ton of arguments directly.

10:53 cemerick: But snippet* is a macro, so I can't use apply.

10:53 rhickey: cemerick: I understand, just kidding. But could you please put a pointer to your case+ stuff into the comments on #426

10:53 cemerick: ha, sure

10:55 raek: fliebel: I recently started to read here, so I might be missing the point, but could you let the macro genererate a (apply ...)?

10:55 cemerick: fliebel: I don't understand where you're going wrong. e.g. http://gist.github.com/601109#comments

10:57 fliebel: cemerick: In my case the vector is in a let, so I put the symbol in the macro.

10:58 raek: Basically I have a seq of arguments stored somewhere, and a macro to apply them to. So I can't use apply on a macro and I can splice the /symbol/ to the seq.

10:58 *cant

10:59 raek: does it have to be a macro?

10:59 sorry, but I have to go again...

10:59 fliebel: raek: It;s in enlive.

11:02 cemerick: I'm not using a vector literal.

11:02 quizme: what's this called "->" ?

11:03 fliebel: quizme: Threading macro?

11:03 quizme: thnx

11:04 _fogus_: quizme: Zeno's arrow. ;-)

11:05 tobiasraeder: is there a way to do something like (defprotocol myprotocol (^String myfn [])) with a macro? (the main part is the ^String)

11:05 cemerick: fliebel: My point before was, you can't use macros with runtime data; the macro is being expanded by the compiler long before that data is bound in the let form.

11:05 You can get around this with eval, but that's sorta icky.

11:05 ,(eval (list 'and true false))

11:05 clojurebot: DENIED

11:06 cemerick: bah. anyway...

11:06 fliebel: all of enlive's macros are backed by functions (as is polite), so there's surely an appropriate fn for you to use instead

11:06 fliebel: cemerick: Right… So what are my options for applying a seq in a var to a macro?

11:06 cemerick: fliebel: eval, or find a macro that'll get the job done

11:07 fliebel: cemerick: It's all macros until deep down where I'd have a 20-line fn I could apply this to.

11:07 cemerick: sorry, or find a *function* that'll get the job done

11:09 fliebel: cemerick: The main ones all go through snippet* to transformation. making a fn out of that is going to be icky as well. I'll opt for the eval route :(

11:10 cemerick: fliebel: it happens, sometimes. I'd ping cgrand if you see him, and ask if there's a better way.

11:11 fliebel: cemerick: I will. Thanks :)

11:11 ~seen cgrand

11:11 clojurebot: cgrand was last seen quiting IRC, 224 minutes ago

11:12 cemerick: quizme: -> is known as the Thrush Combinator in haskelly, FP circles as well

11:12 They're *very* good at giving things fancy names, it turns out.

11:12 LauJensen: cemerick: IIRC thrush is a term which comes from math

11:14 fliebel: LauJensen: It's also a bird :)

11:20 esj: fliebel: as well as something that makes the young cry....

11:24 chouser: I believe the "Thrush combinator" is a function, right? -> is a macro, so it can't be the same thing, can it?

11:25 LauJensen: chouser: it can

11:26 chouser: ,(-> [i [1 2 3]] (for (* i i)))

11:26 clojurebot: (1 4 9)

11:26 chouser: can Thrush do that?

11:26 _fogus_: A very good article on Thrush is http://github.com/raganwald/homoiconic/blob/master/2008-10-30/thrush.markdown#readme, but mine is simpler http://blog.fogus.me/2009/09/04/understanding-the-clojure-macro/ even if the commas thing is controversial. ;-)

11:26 LauJensen: debashing wrote something on Thrush as well

11:26 (thrush being ->)

11:27 _fogus_: I like Braithwaite's better

11:27 LauJensen: why?

11:27 clojurebot: http://clojure.org/rationale

11:29 _fogus_: LauJensen: It makes more sense to me, plus it's very well written

11:29 quizme: http://pastie.org/1186727 <--- why?

11:30 chouser: quizme: that became (fn (sqr 5) [x] (+ 1 x)) ... which isn't valid clojure code

11:31 esj: i'm weirdly happy to able to give -> a name

11:31 thanks

11:31 chouser: If -> were the Thrush combinator (and clojure had haskell-like auto-currying) that would have worked.

11:31 octe: i want to generate a sequence from 0..inf, increasing by 1 each time

11:31 chouser: but since -> is not Thrush and clojure doesn't curry, that's just a syntax error.

11:31 octe: like this: (iterate (fn [x] (+ x 1)) 0)

11:31 but that feels awkward

11:32 quizme: thnx i'll chew on that

11:32 chouser: octe: (fn [x] (+ x 1)) can be written #(+ x 1) or just inc

11:32 octe: thanks

11:32 esj: dammit

11:33 chouser: octe: but actually range with no args does just what you want

11:33 ,(range)

11:33 clojurebot: Execution Timed Out

11:33 chouser: ,(take 100 (range))

11:33 clojurebot: (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99)

11:33 octe: range is what i wanted

11:33 esj: so we've cuckolded Thrush...

11:33 octe: ,(range 4)

11:33 clojurebot: (0 1 2 3)

11:35 chouser: esj: -> is just different than Thrush. Similar, but with its own behavior that is sometime nicer and sometimes not.

11:35 esj: chouser: I should probably have read the article, rather than jump to conclusions. Thanks for the warning.

11:35 chouser: :-)

11:36 thrush should be easy enough to write. I wonder if it would be useful...

11:38 (defn thrush [& args] (reduce #(%2 %1) args))

11:38 (thrush 5 inc inc inc) ;=> 8

11:38 (thrush 5 #(- % 2) #(* 2 %)) ;=> 6

11:40 (thrush 5 sqr (fn [x] (+ 1 x)) #(Math/sqrt %) int str) ;=> "5"

11:44 _fogus_: chouser: Or another way to "visualize" thrush is (defn thrush [a & args] ((apply comp (reverse args)) a))

11:46 chouser: _fogus_: ah, good.

11:54 _fogus_: chouser: I like yours better. Very elegant.

11:57 chouser: _fogus_: I was a bit surprised I didn't end up needing 'reverse'. Your use of comp probably indicates what I was thinking.

11:57 edw: I apologize for bringing this problem up again, but I'm trying to get rid of the "error in process filter: Wrong number of arguments" error that pops up when '0'ing out of the SLIME debugger. Anyone know the underlying cause?

11:58 _fogus_: chouser: Mine could be the comment for yours. ;-)

11:59 chouser: edw: You want a cause a bit less underlying than "because you're using emacs" I suppose? :-)

12:00 edw: Show me an alternative and I'll use it. :P

12:00 chouser: people make even more fun of my alternative.

12:01 edw: Pico?

12:01 Notepad?

12:01 Teachtext?

12:01 EDLIN?

12:02 Wordstar?

12:02 chouser: exactly

12:02 cemerick: You people are all nuts. ;-)

12:02 chouser: I had wordstar

12:03 on an 8" floppy for my CP/M

12:03 but I didn't write any Clojure with it

12:03 sproust: edw: I don't have that problem at all.

12:03 edw: I wrote papers for middle school in Supertext on my Apple ][+. It used inverse text to denote capital letters.

12:03 sproust: edw: I would recommend using bleeding edge SLIME & swank-clojure, works great right now with GNU Emacs.

12:04 edw: and don

12:04 edw: don?

12:04 sproust: 't mind the naysayers, they'll be switched to emacs within a few years anyway.

12:04 edw: Ah.

12:04 sproust: Esp. cemerick.

12:04 chouser: hehe

12:04 sproust: He's just dying to switch.

12:05 chouser: oh! cemerick ... I wanted to talk to you about nREPL

12:05 finally read the proposal in the readme last night

12:05 edw: sproust: I'm using SLIME from boinkor. Should I get it from the Savannah CVS repo?

12:05 Or SVN, or whatever the SLIME folks use?

12:06 chouser: cemerick: is the "nil" in the example telnet sessions "out" key intentional?

12:07 cemerick: chouser: yes -- that's the repl printing the result of the (println 5) expression

12:07 The intention is that for interactive use, one only ever needs to care about :out

12:07 chouser: cemerick: so "out" include *out*, *err* and repeats the "value"

12:08 cemerick: chouser: yes, though I don't view it as repeating the value, insomuch as :value is explicitly providing the printed value for use by tooling

12:09 I suppose I should make it so that :value is provided only if requested

12:09 chouser: cemerick: in my brief excursions into repl-writing I've enjoyed taking advantage of knowledge about whether text comes from *out*, vs *err* vs the return value of the expression

12:09 coloring each of them differently, for example

12:09 cemerick: sure

12:10 chouser: I think this can reduce confusion, and I would be sad if the nREPL spec made this implossible.

12:10 cemerick: having the return value split out is critical, of course

12:10 chouser: or even impossible

12:10 TeXnomancy: edw: it's better-supported to install slime via package.el; trunk frequently breaks

12:11 edw: TeXnomancy: Thanks.

12:11 cemerick: chouser: I'm not super-happy about the mingling of *out* and *err* myself, but it definitely simplified the spike.

12:12 pulling them apart will likely require emitting N response messages per request.

12:12 That will also resolve the issue of long-running evaluations.

12:12 chouser: cemerick: to color the return value differently as is, I would have to find and remove the "value" from the "out" ?

12:13 cemerick: as-is, yes. Never considered that one. Are there any other repls that color the return value specially?

12:14 chouser: cemerick: I have a nasty ANSI-terminal color codes repl that does, and texture does too.

12:14 I like it

12:14 cemerick: how do you find the scope of the printed value there?

12:15 or are you hooking into c.m/repl?

12:15 chouser: hooking c.m/repl

12:15 cemerick: ok

12:16 In that case, perhaps the next rev will split *out* and *err*, not print the final value to *out*, but still always include it in :value

12:16 chouser: I especially like not printing the value to *out*

12:16 splitting *out* from *err* while still mixing their chronology would add a fair amount of complexity to the spec

12:17 cemerick: That may become an option. I want to make quickie interactive clients as easy as possible to write.

12:17 edw: Yay! I can recover from (+ 1 'a) in SLIME!

12:17 chouser: though the code for creating/comsuming that may still not be too tricky.

12:17 cemerick: chouser: the chronology will be retained -- messages carrying portions of *out* and *err* will be delivered in order.

12:18 chouser: can I get you to outline your ideal in the design notes?

12:20 chouser: cemerick: for quickie clients, (println (str (:out msg) (:value msg))) doesn't seem too onerous

12:21 cemerick: chouser: 'twas but a bad rationalization :-)

12:23 chouser: cemerick: for *out* and *err* you're thinking of multiple messages per response, for a sort of "live, streaming" feel?

12:24 cemerick: yup

12:24 N responses per request is already on the todo list for other reasons

12:24 chouser: can you msg me your gdocs addy?

12:35 rickmode: I have a protocol method that takes two args like this (foo? [this x] (some test)) and I want to use it like a partial, except it's the second argument that's known, so I'm using a (let [f? #(foo? % a] ...). Is there some variation of partial I can use instead?

12:36 Sorry, that let should be: (let [f? #(foo? % a)] ...)

12:39 amalloy: rickmode: if it were an interface instead of a protocol you could use memfn, but i don't think protocols work that way

12:41 rickmode: amalloy: you mean a protocol method can't be used as first class function?

12:43 amalloy: rickmode: well, i confess i don't have a lot of experience with protocols. maybe you can, but i don't know how; i was suggesting you might find info on it somewhere near the documentation for memfn

12:43 rickmode: amalloy: oic... thanks

12:45 MayDaniel: rickmode: There's a partial function in c.c.str-utils2 for functions that take their primary argument first.

12:48 rickmode: MayDaniel: I see it... I think I'll just keep using #(foo % second) ... seems to be just as terse for my case (2 args)

12:48 chouser: memfn is not useful now that we have #()

12:48 protocol methods are first-class functions

12:52 amalloy: chouser: really? i mean, sure, you can write memfn with #(), but (a) memfn seems a little more self-documenting, and (b) you can't nest #()

12:52 chouser: you can nest memfn?

12:52 amalloy: no, but you can put a memfn inside a #()

12:52 chouser: heh. oh.

12:53 you can't type-hint the target of memfn

12:54 amalloy: i guess conceivably you could nest memfn, but it's hard to imagine. "This java method takes an argument of type IFn. Please create a memfn for it, passing (memfn x 10) as the IFn argument."

12:55 rickmode: amalloy / chouser: so a protocol *is* a first class fn, with the same performance? or does the run-time wrap the method when it's passed as an arg?

13:03 chouser: a protocol method really is a function, a clojure.lang.Fn

13:05 rickmode: chouser: thanks

13:05 chouser: the compiler does special things to make protocol fn calls as fast as possible, and I'm not sure if it can do that when they're passed as an arg or not

13:05 clojurebot: Why are you asking *him*

13:08 shoover: chouser: what about ->> as thrush? http://clojure.bighugh.com/thrush.html

13:09 _fogus_: if you prefer raganwald's version, then his ultimate conclusion is built into clojure: let

13:12 chouser: shoover: ->> is also a macro. are you asking for the function equivalent like I did with 'thrush'?

13:44 shoover: chouser: nah, just saying I found ->> to be more useful than -> for emulating the thrush combinator a la raganwald

13:45 chouser: ah

13:45 shoover: It's more in the spirit of making something close within a given language than making a pure implementation of the mathematics

13:45 chouser: still a macro though, not a combinator.

13:45 ,(->> (* i 2) (let [i 10]))

13:45 clojurebot: 20

13:46 chouser: I'm not arguing over what's useful, just about names and their meanings.

13:48 solussd: ,(* 7 7)

13:48 clojurebot: 49

13:49 kotarak: ,(->> 5 (* 2) (+1) (when false))

13:49 clojurebot: nil

13:53 chouser: kotarak: scary, isn't it?

13:53 ,(-> what the heck was I thinking? comment)

13:53 clojurebot: nil

13:54 kotarak: chouser: not really. This is basically the same effect as you get in C with #define STUFF(x) bla_blub(x); (<- note: ;)

13:54 chouser: just a different level

13:55 chouser: yeah, I guess. not recommended either place

13:56 kotarak: chouser: or the binding/recur thing which was on the group recently: sometimes the sewers under the shiny surface smell pretty bad. ;)

14:07 AWizzArd: ,(doc vlist)

14:07 clojurebot: Excuse me?

14:46 LauJensen: Gents, when I do a "dock center", the component does what its supposed to, but leaves about 3px on each side unpainted, is this some property of the JFrame or the component?

14:47 shoover: chouser: I'm letting amazing thrush FUNCTION sink in

14:47 chouser: er, your amazing...

14:48 chouser: heh

14:48 shoover: I think you should call it ..

14:48 amalloy: shoover: that's "you're amazing", when you're talking about chouser :)

14:48 chouser: ha ha

14:49 LauJensen: wow, you're still going on about thrush? :)

14:49 amalloy: LauJensen: worse than that, i just ordered the book with all the birds from amazon

14:50 LauJensen: oh man :(

14:50 Its when ordering stuff that it sucks to be the guy whos always right, on the second try

14:50 amalloy: LauJensen: er what?

14:50 LauJensen: didn't you describe yourself as such the other morning?

14:50 "im the guy whos always right on exactly the second try"

14:50 amalloy: yesssss, i think i did

14:51 not sure what that has to do with ordering

14:51 LauJensen: well, if you order the wrong thing on your first try, it costs you money and you have to do it again

14:51 amalloy: although, amusingly enough, i ordered some new RAM yesterday, and then realized it was the wrong kind. and that kinda sucked. so i guess i see what you mean

14:52 alpheus: Is there something like memoize that provides access to its cache?

14:58 tolsen: clojure.string seems to have disappeared from the API Overview at http://clojure.github.com/clojure/ . Anybody else notice?

15:00 * alpheus notices http://www.paullegato.com/blog/memoize-reset-clojure/

15:04 replaca_: tolsen: yeah, a few namespaces seem to be missing. I'll get it fixed up. Thanks for pointing it out.

15:06 LauJensen: chouser: Aren't you responsible for the API docs? ^^

15:09 tolsen: replaca_: Thanks

15:11 now's a good time for me to become more familiar with clojure's documentation tools so I don't have to rely on the website so much :-)

15:12 LauJensen: oh sorry replaca_, didn't see you there

15:12 replaca_: LauJensen: yup, I'm the responsible party :)

15:12 LauJensen: great :)

15:43 anonymouse89: easy way to list the classes in a jar from clojure?

15:44 _fogus_: shoover, chouser: http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/

15:45 KirinDave: _fogus_: so...

15:45 _fogus_: Good idea or terrible idea? http://idisk.me.com/dfayram/Public/Pictures/Skitch/current-status-20100928-124429.png

15:45 Webmachine port to clojure.

15:45 hiredman: anonymouse89: http://gist.github.com/601649

15:46 _fogus_: KirinDave: I don't know much about Webmachine, but I like REST so yes... good idea indeed

15:47 hiredman: anonymouse89: uh, that function expects the jar as a byte array which is a little odd

15:47 but, uh, thats what I had

15:47 KirinDave: _fogus_: Well, also the plan to use a protocol. But I guess you don't know how webmachine works, so time will tell.

15:47 nickik: is there a good enlive sample application

15:48 chouser: _fogus_: not only easier than writing my own blog post, but the results are better as well. Thanks!

15:48 _fogus_: slight correction: I'm only the co-author of JoC

15:48 _fogus_: chouser: My pleasure.

15:50 anonymouse89: hiredman: thanks!

15:50 _fogus_: KirinDave: One thing that I've always found lacking is the ability to take a "description" of a RESTful service that used to generate both server and client.

15:51 LauJensen: _fogus_: Good write-up! thanks

15:51 KirinDave: The client I wouldn't want to generate.

15:51 But I agree on the server part

15:52 bmh: Can I map over the values of a sorted-map and get a sorted-map back without having to rebuild the whole structure?

15:52 _fogus_: KirinDave: Why not client?

15:52 lancepantz: bmh: I don't think so

15:53 atleast, if you map over a hash, you have to wrap it back using into

15:53 KirinDave: _fogus_: I have other things to do. :)

15:53 lancepantz: so imagine it would be the same

15:53 _fogus_: LauJensen: Thanks. The -> as Thrush posts never quite sat well with me, but it finally crystalized today why that was. (thanks to #clojure)

15:53 KirinDave: But also because client usage of restful services tends to be really varied.

15:54 bmh: lancepantz: That's really too bad.

15:55 _fogus_: KirinDave: Fair enough. :-)

15:55 lancepantz: bmh: i'd bet there's good reason

15:56 KirinDave: _fogus_: Look, this is gonna be open source. :)

15:56 bmh: lancepantz: You're more generous than I. :-)

15:56 KirinDave: _fogus_: So once I've released, maybe we can move forward from there

15:56 I was trying to evaluate how to build a correctly-behaving series of API servers in clojure for BankSimple

15:56 And getting _correct_ behavior is actually really painful.

15:57 _fogus_: KirinDave: I don't agree on your Emacs theme however, that might be a show-stopper. ;-)

15:57 KirinDave: _fogus_: I actually changed it just for today to something bright

15:57 Light incidence

15:57 _fogus_: Whew!!

15:57 KirinDave: Usually I use Charcoal

15:59 _fogus_: KirinDave: If you make it to the Conj, then I'm in!

15:59 * _fogus_ (crossing fingers)

15:59 bmh: lancepantz: My best guess for an underlying reason is that map operates on keys and values. If you change the keys, uniqueness isn't guaranteed.

15:59 KirinDave: _fogus_: I can't.

15:59 My dog has cancer.

15:59 bmh: All this suggests is that there should be another map function that can't change keys

16:00 _fogus_: KirinDave: I'm sorry. That's terrible

16:00 KirinDave: Also banksimple and oreilly deal

16:00 It's just one of those deals.

16:01 _fogus_: KirinDave: I am excited about the book BTW, it looks to be the first O'Reilly book I've bought in ~3 years

16:01 hiredman: ~def fmap

16:01 LauJensen: Does anybody know of a library which would let me do fancy animations on regular swing interfaces?

16:02 KirinDave: _fogus_: Thank you, but I don't think you will find it very illuminating though.

16:02 _fogus_: KirinDave: I doubt that very much.

16:02 KirinDave: _fogus_: We're pretty much deliberately aiming at the ruby/python/perl/deep-java convesaion

16:02 We won't even have a chapter on macros.

16:02 LauJensen: KirinDave: You need to work on your sales skills, seriously :)

16:02 KirinDave: What have I given birth to.

16:02 LauJensen: Ohh man you're killing it

16:03 KirinDave: We'll have macros

16:03 but they're in case studies.

16:03 hiredman: that makes more sense to me

16:03 amalloy: LauJensen: maybe he's aiming for the self-loathing market

16:03 LauJensen: amalloy: more like charity :)

16:04 _fogus_: KirinDave: That's an interesting approach! I look forward to seeing how it pans out

16:05 KirinDave: LauJensen: Actually I just want to be honest. If you are in #clojure it'll be a curiosity for you.

16:05 It's for people in #ruby and #rails and #python. :)

16:05 LauJensen: KirinDave: Fair enough :)

16:05 KirinDave: “Look, you can do amazing shit with Clojure, and it has all the power of your favorite language (and them some).”

16:06 hiredman: I think macros are better shown as working constructs then a bunch of naval gazing form rewriting

16:07 chouser: I is inside ur navel, rewriting ur forms.

16:07 KirinDave: Well, and for clojure macros are WAY less part of the community culture than, say, common lisp.

16:08 LauJensen: only because Rich wont give us readermacros :(

16:08 (j/k)

16:08 Chousuke: user-definable reader macros* :P

16:08 KirinDave: So, advice time.

16:08 http://bitbucket.org/justin/webmachine/wiki/BigHTTPGraph

16:08 I need to implement this and I am torn.

16:08 I could use a functional approach

16:09 OR I could make the states actual objects. Both have merit.

16:09 The nice part about making them actual objects is that then they're introspect-able.

16:09 hiredman: ,(pl (↕map (replicate 3 (↕apply vector $ (↕map range $ 10 inc · inc · inc) call · ⌽* $ 10 · call · (⌽+ -2) map)) shuffle))

16:09 clojurebot: ([50 100 60 80 30 20 10 70 90 40] [20 30 80 70 10 40 50 60 90 100] [60 100 70 90 30 80 10 40 20 50])

16:10 chouser: KirinDave: ick. Really, nobody has implemented that with code you can just use?

16:11 KirinDave: Um

16:11 In scala?

16:11 In erlang?

16:11 It's not so bad once you get the epic responder informal-protocol tamed.

16:12 chouser: it just looks like the kind of code you want to have written and maintained in as few places as possible.

16:12 KirinDave: Yes.

16:12 chouser: So to start: https://gist.github.com/02254fca76c1435ce403

16:13 * chouser panicks

16:13 Chousuke: oh wtf

16:13 philjordan: christ, that looks pretty horrendous

16:14 KirinDave: Eh

16:14 That's how it's done.

16:14 Dont worry

16:14 Once I have a map with default impls and some friendly macros

16:14 philjordan: also, it seems like some of this stuff is a property of the HTTP request, whereas some of it depends on the resource being requested

16:14 KirinDave: It'll be like (html-responder [request] ...)

16:14 Yes.

16:15 It uses that protocol to plug into the graph

16:15 http://bitbucket.org/justin/webmachine/wiki/BigHTTPGraph

16:15 chouser: KirinDave: you're sure that should all be data instead of code?

16:15 shouldn't

16:15 KirinDave: ?

16:15 philjordan: yeah, I know the graph, I refer to it frequently :)

16:15 KirinDave: I think a protocol is probably the right choice here.

16:15 Unlike webmachine, i want dynamic responder updates and changes.

16:16 So it needs to be something tied to an object, not a module name

16:16 philjordan: to be honest, I'd try implementing that protocol for a specific not-quite-trivial resource

16:17 KirinDave: ?

16:17 philjordan: some of the code will naturally cluster or be similar in some way

16:17 hiredman: by object you mean something that the protocol is extended to?

16:17 KirinDave: Yes

16:17 philjordan: then refactor from there

16:17 KirinDave: yeah

16:17 that's the plan

16:17 this is prototype stage.

16:18 philjordan: but I have to say, I've been on Clojure hiatus for a couple months now, so I've missed most of the protocols/types stuff

16:18 (I know how it works in theory but have no practical experience)

16:19 KirinDave: philjordan: This is my inaugural big project with them, too.

16:20 hiredman: I like to use protocols to provide the minimum contract to be fulfilled to participate in a library, then have functions in the library build on the protocol to provide what is needed

16:20 because the protocol is small then it makes it easy to bring other things into the fold of the library

16:20 philjordan: I'd probably break that protocol up a bit

16:22 not quite sure how to structure it just yet, but I'd focus on grouping functionality by different types of resources - static/cacheable vs dynamic, add an authentication/authorisation layer, etc

16:24 but the first pass would definitely be a horrendously messy implementation that responds to exactly one kind of request, then add another and see what's common and what isn't, etc.

16:24 I think having it as one giant chunk of predicates is probably overwhelming, realistically

16:25 anyway.

16:26 I actually came here with a HTTP related question too.

16:26 AWizzArd: I would like to try out the new clojure.jar with the bugfix from rhickey about the Int/Long auto translation. In this jar I don't find clojure.set anymore. Is that correct? Were those set fns moved?

16:27 rhickey: AWizzArd: set is not auto-referred

16:27 AWizzArd: ah oki

16:28 DeusExPikachu: anyone use incanter here?

16:28 philjordan: been out of the clojure loop for a while (half a year?), and haven't done any webserver shenanigans in Clojure for even longer (2008?), so I was wondering what you guys like to use for webserver, dispatching, templating, persistence, etc.

16:29 I'm aware of Compojure, which looks pretty straightforward

16:29 kjeldahl: I have a project.clj file that only refers to clojure 1.2, but "cake deps" still seems to pull in 1.3 (the pom file). Is this correct, and if so why?

16:29 chouser: philjordan: I tend to prefer the cgrand stack: moustache for routing, enlive for templating

16:29 ninjudd: kjeldahl: does something you are depending on use 1.3?

16:29 philjordan: wait, I thought mustache was a templating engine

16:29 AWizzArd: It is no problem to (require '[clojure.set :as set]) and have the set/fns *and* the function set, right? This is working for me now, but I don't know if it is supposed to.

16:30 kjeldahl: ninjudd: Not that I am aware of, see http://gist.github.com/601716

16:31 amalloy: AWizzArd: seems like that should work fine. calling a namespace makes no sense, so it won't do that; and function/member doesn't make sense either, so it will resolve the namespace

16:32 philjordan: chouser: I've encountered enlive in my searches, it seems kind of trippy - what do you do in practice, give your placeholders ids in the HTML and then replace them with enlive queries?

16:32 Raynes: kjeldahl: It doesn't pull in the jar file?

16:32 kjeldahl: If not, it doesn't really matter.

16:33 kjeldahl: Raynes: Nope, no jar file. Thanks.

16:33 chouser: philjordan: yup. I think cemerick may have pushed it as far as anyone.

16:33 kjeldahl: I was just curious.

16:33 Raynes: Some of my projects do that. Not sure why, but it doesn't appear to have any effect on anything. I guess it's just because one of the projects depend on x version, but you depend on y version and your version trumps it's version.

16:33 AWizzArd: rhickey: very good, thanks for fixing that bug. Another problem with this automatic translation that I encountered was implicitly fixed by this. My old code that expects Ints now works correctly, when I explicitly specify that I want an Integer *handshaking*

16:33 Raynes: It only matters if the jar file that depends on 1.3.0 *actually* requires it to function.

16:34 kjeldahl: Yeah, I checked lib and the jar wasn't there, so it can not be used.

16:35 ninjudd: kjeldahl: yeah, i tried it and i see something is trying to pull 1.3

16:36 kjeldahl: oh

16:37 ninjudd: kjeldahl: you can require swank-clojure directly instead of lein-swank

16:37 Raynes: lein-swank is actually in swank-clojure now.

16:39 philjordan: chouser: right, I think I've found all the bits I need, thanks - Ring, Moustache, Enlive - anything else?

16:39 ninjudd: kjeldahl: looks like it is enlive

16:40 enlive has this: [org.clojure/clojure "[1.1.0,)"]

16:41 Raynes: Ew.

16:41 I hate version ranges.

16:41 They're so often unnecessary.

16:41 kjeldahl: Thanks for the detective work.

16:41 Raynes: [1.1.0] would be a 'soft' version dependency, meaning that if you required 1.2.0, your version would > enlive's, killing the purpose for a version range.

16:41 kjeldahl: Got rid of lein-swank as well; works great.

16:42 Raynes: Er, without the square brackets, I guess.

16:42 ninjudd: kjeldahl: no problem

16:42 * Raynes hasn't looked at maven documentation in a long, long time.

16:44 tobiasraeder_: Can anyone explain me what (defn [[name [& args]]] ...) exactly does?

16:44 (defn myfn [[name [& args]]] ...) obviously

16:45 philjordan: has anyone got any advice for reconciling state in STM with state in persistence (DB)?

16:46 tobiasraeder_: myfn will accept 1 argument, which must be a seq, the first element of which will be bound to name, the rest to args

16:46 tobiasraeder_: uh, strike that

16:47 Raynes: That's an odd destructuring form.

16:47 Isn't [& args] a bit of redundancy there?

16:47 philjordan: tobiasraeder_: 1 argument, a seq. first element -> name, second element also a seq -> args

16:47 but yeah, that's equivalent (except for enforcing seq-ness) to [[name args]]

16:48 so (myfn ["blah" [1 2 3]]) binds "blah" to name and (1 2 3) to args

16:49 not quite sure why you'd want that...

16:49 tobiasraeder_: @philjordan thank you

16:53 philjordan: so yeah, has anyone stored state in Clojure's STM while also storing some in another transactional system (database)? any hints on not making a total cockup of it?

16:54 jcromartie: philjordan: don't do it

16:54 philjordan: one or the other

16:54 philjordan: I couldn't really find anything relevant online on the topic, though I might have been searching badly

16:54 jcromartie: the problem is that your ref or whatever just becomes a cache

16:54 and now you're on the hook to handle cache invalidation

16:55 because at *some* point the other system will be updated without going through your functions that make sure both of them get updated

16:56 philjordan: jcromartie: I do realise this, just wondering if there are any strategies. I'm not thinking of a cache per se, even storing different state in the 2 systems seems like a hard problem.

16:57 jcromartie: it's the whole reason why we say that mutable state is bad :)

16:59 philjordan: yes, it's just that (a) a lot of state is transient and writing it to disk is crazy (b) some state is important and absolutely needs to be dumped to disk

16:59 the best thing I can come up with is some kind of transaction log

17:00 which isn't so great for structured retrieval later

17:01 (basically, serialising persistence access, using an agent from a dosync)

17:03 but reads will go out of sync pretty much immediately

17:06 jcromartie: hmm

17:06 philjordan: I'd pick one persistent store and stick with it.

17:06 I assume you're building a web app

17:06 philjordan: yeah, it looks like it.

17:07 jcromartie: philjordan: is it a web app?

17:08 philjordan: well, the web app I'm about to start building won't have any dire performance requirements, I was just asking in general, as I've encountered the issue before and never solved it satisfactorily

17:08 the issue came up in a multiplayer game server I built for a customer last year

17:09 jcromartie: I see

17:09 yeah I built one web app with Clojure and started to roll my own persistence (refs persisted to disk by agents)

17:09 in the end, a DB was better

17:09 at least for the persisted data

17:09 there was some truly transient stuff in refs

17:10 philjordan: the games themselves were transient, the scores etc of course weren't. didn't run into any issues in practice, and I think I engineered it well enough that there weren't any edge cases, but it was a bit of a mess

17:10 jcromartie: hm

17:10 well that makes sense at least

17:11 philjordan: what's the easiest way to talk to a db from clojure these days?

17:11 (loaded question, ha!)

17:11 jcromartie: but I'll tell you that 90% of the bugs in my full-time employment's ASP.NET web app come out of state being stored in multiple places, denormalized and mutable

17:11 clj-sql?

17:11 clojure.contrib.sql

17:12 easy enough

17:12 there's no mature ORM-type library, although that wouldn't really be a good name for something like that in Clojure

17:12 yayitswei: is there a way to make "cake compile" not restart the JVM? as it is, I have to restart swank and reconnect my SLIME every time I compile

17:13 ninjudd: yayitswei: are you compiling java? or just clojure?

17:13 philjordan: jcromartie: I have no big issue with writing queries explicitly as long as data type mappings are sane and I never, ever have to worry about escaping

17:13 yayitswei: just clojure

17:14 philjordan: jcromartie: do you know of any schema versioning systems for clojure?

17:14 jcromartie: philjordan: how about CouchDB? :)

17:15 oh here http://osdir.com/ml/clojure/2010-02/msg01189.html

17:15 philjordan: jcromartie: I think I'll pass on that one, I'll be using enough unfamiliar tech for this project as it is

17:15 jcromartie: yeah

17:15 * arohner should probably release his ORM library

17:16 philjordan: jcromartie: my last Clojure web project was in December 2008, there were no serious libraries back then

17:16 ninjudd: yayitswei: yeah. i'm not sure it is necessary to restart if you recompile clojure files

17:16 yayitswei: i may have just put that in to be consistent

17:17 philjordan: thanks for the link btw

17:18 ninjudd: yayitswei: well, i guess it is necessary for gen-class

17:18 yayitswei: is there a reason you need to aot compile everythin?

17:20 yayitswei: if there's a reason you need to have :aot :all, then cake needs to restart your project jvm when you compile

17:22 yayitswei: ninjudd: I see, does C-c C-k update the jar files? it doesn't right?

17:23 I need to update the files in the class/ directory

17:23 ninjudd: it doesn't

17:24 yayitswei: sorry, does it update the classes/ directory?

17:27 ninjudd: no. it just loads the file into the jvm

17:30 yayitswei: ninjudd: thanks, just verified that

17:32 oh well, restarting is just one extra step, I can just chain 'compile' and 'swank' together

17:36 ninjudd: yayitswei: or you can add autostart to your config

17:37 yayitswei: add this to .cake/config: swank.autostart = localhost:4005

17:37 yayitswei: ninjudd: thanks, didn't know about that

17:37 ninjudd: you need a different port for each project if you plan to run multiple simultaneously

17:38 yayitswei: http://github.com/ninjudd/cake/wiki/Swank

17:38 yayitswei: ninjudd: got it

17:39 lpetit: I've enhanced the Clojure/OSGi integration notes with a separate part currently (this may change) "Clojure-OSGi manifesto"

17:40 I guess that while such "big picture" goals are not shared by anybody, we will again and again follow separate roads while having the feeling of being on the same.

17:40 https://docs.google.com/document/edit?id=11G7v_I1DMWisc5pWKWisW85rUkGk9egi_voT4Mp_vQo

17:44 ninjudd: hey !

17:44 ninjudd: lpetit: hey

17:46 lpetit: have you read the following link ^^^. We're not alone in our quest to make clojure play with OSGi. aav is also very active on the subject, and has already create a repo on github

17:46 ninjudd: lpetit: We're sorry, but google@justinbalthrop.com does not have access to this document.

17:47 lpetit: ninjudd: I myself have tried some patch experiments on clojure core, including your (ImportExpr), but while talking about it with Rich, there was a problem. ImportExpr seemed somehow correct w/regard to AOT compiled classes. Still banging my head against the wall, though, to understand if this also applies to import statements emitted from regular clojure files.

17:47 ninjudd: will try to correct that

17:48 https://docs.google.com/document/edit?id=11G7v_I1DMWisc5pWKWisW85rUkGk9egi_voT4Mp_vQo&authkey=CKeqoZQJ

17:48 ninjudd: new link ^^

17:49 * aav is back

17:49 lpetit: my congtribution at the end

17:52 ninjudd: does it work for you?

17:53 ninjudd: lpetit: still reading the conversation with rich earlier today

17:54 lpetit: did that part of the patch actually help solve your problem?

17:55 that was the part of the patch i was actually less sure about, but discussion never got past the changes to *use-context-classloader*

17:55 lpetit: ninjudd: you mean the part concerning ImportExpr ? It seemed so. Though Rich arguments somehow made it into my head, and now I'm confused

18:03 ninjudd: lpetit: yeah. it has been a while since i was trying to do this, so i'm struggling to get my head back around it

18:10 cemerick: ninjudd: you should be able to see that doc, but I can add you for edit

18:11 ninjudd: cemerick: i can see it now

18:11 cemerick: ninjudd: well, you have edit anyway :-)

18:11 later

18:17 ninjudd: lpetit: reading the doc. OSGi isn't directly related to what i am working on, but the issues you're dealing with are similar to what i have to deal with if i want to use a single JVM for both cake and the project it is building

19:01 lpetit: ~seen cemerick

19:01 clojurebot: cemerick was last seen quiting IRC, 49 minutes ago

19:25 nathanmarz: hello clojurians, looking for some feedback on some clojure code

19:25 http://gist.github.com/602003

19:25 trying to turn a java class into a clojure function for creating objects of that type

19:25 so i can do things like (apply mk-fooclass args)

19:28 it works, but wondering if there's a better way

19:30 ohpauleez: dear vim people or users of paredit.vim:

19:30 does anyone know how to delete matching paren

19:31 dnolen: nathanmarz: do you need to use eval in this case? couldn't you get the class name as a symbol, convert to string to find the class? factory-fn could become a macro.

19:31 ,(.getConstructors (Class/forName (str 'java.lang.String)))

19:31 clojurebot: #<Constructor[] [Ljava.lang.reflect.Constructor;@1e20bca>

19:31 nathanmarz: dnolen: well i use reflection on the class to get the number of args to the constructor

19:31 oh i see

19:32 dnolen: nathanmarz: yeah, I'm just saying that you can avoid the use of eval here.

19:32 ataggart: ,*clojure-version*

19:32 clojurebot: {:interim true, :major 1, :minor 2, :incremental 0, :qualifier "master"}

19:32 nathanmarz: yea

19:33 is there a practical difference? will the macro code be faster or anything than the function returned via eval?

19:33 dnolen: nathanmarz: eval trigger compilations. You might not want/need that at runtime.

19:34 ataggart: ,(Integer. (byte 0))

19:34 clojurebot: java.lang.IllegalArgumentException: No matching ctor found for class java.lang.Integer

19:35 nathanmarz: dnolen: makes sense, thanks

19:45 ohpauleez: for those curious about my my question. <leader>S. Also W, J, O are helpful

21:09 reburg: if i have some object and i want to get a version of it that complies with some interface, that's a job for reify, right?

21:13 oh and i just discovered extend-type, which does precisely what i want

21:13 never mind

22:07 hiredman: I think I am going to take a classloader outback and stab it in the stomache and twist

22:10 KirinDave: Having problems?

22:11 hiredman: I am trying to replace lein's launching of a new jvm for eval-in-project with using a new classloader

22:12 I can do stuff like getting the value of *clojure-version* using the new classloader and it is the project's clojure version not lein's

22:12 but loading files via load doesn't work

22:16 KirinDave: How does it break?

22:19 hiredman: http://gist.github.com/602200

22:28 TheBusby: hiredman: I'm not sure if this is related, but I was talking with technomancy yesterday about replacing the ant dependency for process spawning with a JNI library.

Logging service provided by n01se.net