#clojure log - Sep 27 2010

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

0:39 bhenry: ,(doc let)

0:39 clojurebot: "([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein."

0:39 bhenry: does let have the same implicit do as defn?

0:39 amalloy: yes

0:39 bhenry: thanks. i guess i can see that from the doc now.

0:39 amalloy: (let [x 1] (println x) x)

0:40 ,(let [x 1] (println x) x)

0:40 clojurebot: 1

0:40 1

0:46 laurus: How do I manually add a library to cljr that isn't in Clojars?

0:47 amalloy: laurus: are you using a build tool like lein or cake?

0:47 laurus: amalloy, no, just cljr with the global repository.

0:47 I have a bit of code here that has a project.clj file, for lein I guess, and I'd like to "install it"

0:48 amalloy: believe it or not, lein install will do that :)

0:48 laurus: But where would I run that? I don't even have lein installed

0:48 ~/.cljr/lib is the place with all the jars, is it bad practice to copy a src directory in there?

0:48 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

0:48 amalloy: well, i don't know. i know the jar eventually winds up somewhere in ~/.m2, but this is not really my strong suit

0:49 laurus: Oh, interesting, some of them are in .m2 as well

0:49 Or perhaps all of them

0:49 Well thanks anyway, I'll just import it manually in the REPL for now and figure this out later

0:49 Figure out the "right way" later I mean :)

0:49 amalloy: okay. that said, lein/cake are a godsend

0:50 laurus: Well I really like cljr for the simplicity, I tried cake but it was buggy and started up a bunch of JVMs that I didn't need

0:50 And lein was annoying because I had to have "projects"

0:50 amalloy: all right. suit yourself; i didn't build any of them :)

0:51 laurus: :) Actually I may have just answered my own question: it seems that ~/.cljr/lib/* is automatically part of the classpath!

0:51 So I think if I just put the files in there it'll automatically recognize them and make them available

0:58 amalloy, I feel like cljr should be recommended as the starting point for people new to Clojure

0:59 amalloy: fortunately i'm pretty new to the community; not doing any evangelizing myself

0:59 laurus: Ok :) I didn't know that, hehe

0:59 dnolen: laurus: not if yr on os x. cljr is lame there.

0:59 laurus: dnolen, oh, really

1:00 It's great on GNU/Linux

1:00 I would assume Mac is similar

1:00 But I guess not :P

1:00 amalloy: but lein really is easy to install. download one file, lein self-install, and you're good to go - it downloads clojure and all the required stuff for you

1:00 dnolen: laurus: yes, mostly because of native lib integration with Java.

1:00 laurus: amalloy, same with cljr, it's just that cljr you don't have to deal with these projects so it's great for people who are new and want to poke around but who also want to install other JARs.

1:01 dnolen, oh, wow, okay

1:01 dnolen: laurus: I like lein and cake, on os x cljr is too slow and weird to be useful.

1:02 laurus: dnolen, wow, that's really too bad

1:02 You should let them know about that

1:02 For me, cake was buggy and strange

1:02 dnolen: laurus: it can't be fixed, Apple's Java is the issue really.

1:02 laurus: dnolen, wow, I'm sorry to hear that!

1:02 You can't just install OpenJDK?

1:03 dnolen: laurus: I'm on OS X, why would I want to do that ;)

1:03 amalloy: laurus: i don't really understand the aversion to projects. it's just a directory for whatever you're fiddling around with

1:03 laurus: amalloy, it's just easy to be able to run cljr from any directory

1:03 And I'm kind of thinking about people who are totally new to Clojure

1:03 amalloy: lein runs from anywhere too

1:03 laurus: And just need something simple and fast to check it out

1:04 dnolen: laurus: cake is fine, though it does have it issues. persistent jvm is plus for me, and it has sane REPL history/autocompletion

1:04 laurus: That's true, I'm just thinking about how to tell a new person to try Clojure out

1:04 dnolen, cool

1:04 amalloy: i think the disconnect here is that you think cljr is simpler than lein/cake. i really don't get that

1:05 dnolen: amalloy: it is simpler in the Python/Ruby broken sense of simpler

1:05 laurus: amalloy, the package management system is global

1:05 dnolen: global lib install, which for real development is a massive PITA

1:05 but cake has both

1:05 global and project

1:05 laurus: dnolen, right, but I don't do "real development," I'm using Incanter mostly

1:06 ninjudd: laurus: what issues did you have?

1:06 laurus: how long ago did you try cake?

1:06 laurus: Oh hi ninjudd

1:06 About a week ago

1:06 amalloy: oh good, ninjudd is here. i can stop preaching and go back to my book :)

1:06 laurus: Perhaps I wasn't using it correctly, but it started up JVMs that didn't eventually stop

1:06 So at one point I had about six JVMs going :P

1:07 amalloy: heh. feature, not a bug

1:07 laurus: Another thing, this is a minor nitpick, is that I had to manually create the .cake directory :P So there was an initial error message there

1:07 amalloy: *cedes the floor to ninjudd*

1:07 laurus: amalloy, hey, thanks for exchanging opinions, I appreciate it

1:08 The main one was the JVMs starting and me not being able to stop them easily I suppose

1:08 But again maybe that's a feature

1:08 It just seemed like it was for more hardcore people

1:09 dnolen: laurus: 'cake stop' for projects, 'cake kill' all when you want to shut it all down, not so bad methinks. it seemed buggy months ago, now pretty solid I think (at least on os x)

1:09 ninjudd: yeah auto shutting down the jvm on inactivity is on the list of things to do

1:09 laurus: dnolen, I see

1:09 ninjudd, cool

1:09 I'm glad you guys are making it, I wasn't trying to say cljr is "better" than these other tools, I was just referring to it as a great out-of-the-box setup for people new to Clojure who want to mess around, kind of like me

1:10 dnolen: laurus: cljr does see good, it just a bad experience on os x.

1:10 s/see/seem

1:10 laurus: Right :) I see

1:12 Have a good night everyone!

1:12 ninjudd: the hope is that cake's global project can fill that role too

1:12 you should be able to be up and running with clojure in 1 minute using cake

1:14 the new cake motto is: cake. for hardcore people.

1:22 tomoj: ninjudd: have there been any changes to the way cake deals with the persistent jvm?

1:22 i.e. has it been made more robust?

1:24 brehaut: Has anybody running a clojure website had any problem with stack overflows with many many lines of "at clojure.lang.Keyword.intern(Keyword.java:39)" in the strack trace ?

1:24 ninjudd: there was a bug early on that caused it to launch many jvms per project which has been fixed

1:24 tomoj: awesome

1:24 I have been scared to try it again since that happened to me

1:25 ninjudd: and the io handling has been improved quite a bit

1:26 tomoj: we are also planning to stop using two jvms per project and add an auto-shutdown option

1:29 tomoj: two jvms per project is a bit much for me right now.. only have 1GB ram at the moment

1:30 hmm, so you might have auto-shutdown after a certain time of repl idleness?

1:31 I don't think I could use any kind of auto-shutdown

1:31 I leave answers to things sitting in repls

1:33 what would be nice is some way to easily see which projects have jvms running, and to easily shutdown from anywhere

1:40 ninjudd: cake ps and cake kill do that

1:40 tomoj: nice

1:41 ninjudd: also, it wouldn't shut down if the repl was still connected

1:41 tomoj: ah, I see

1:42 amalloy: ninjudd: out of curiosity, what *are* the two jvms for? i think cake/bake is hilarious but i don't understand it

1:43 ninjudd: it is so that cake's dependencies don't pollute you project

1:43 say you want to use a different version of some library cake uses or a different version of clojure

1:43 tomoj: does lein use some fancy trick to get around that?

1:44 ninjudd: lein does the same thing.

1:44 amalloy: i see, i think. you need a jvm with cake stuff to do bootstrapping, and if you made us use the same one there'd be issues. once you're up and running, you load another jvm

1:44 ninjudd: but two classloaders is the right way to solve that problem

1:45 that's what we're working on to use just 1 jvm

1:45 tomoj: lein uses two jvms?

1:46 amalloy: tomoj: yes. try: $ pidof java; lein repl&; pidof java

1:46 ninjudd: yeah. they just aren't persistent

1:46 tomoj: I think I read something about lein getting a persistent jvm

1:46 ninjudd: eval-in-project is what starts the second jvm in lein

1:46 tomoj: so I guess with that I'll have the one persistent jvm for the project and a jvm actually running the project code

1:47 ninjudd: tomoj: yeah for repl only if I understand correctly

1:47 tomoj: thinking of `lein interactive` I guess

1:48 this gives me an idea

1:51 amalloy: tomoj: this pause after your idea is ominous

1:52 tomoj: have emacs connect to a persistent leiningen jvm

1:52 then run lein commands from project.clj or any .clj file in the project

1:58 scottj: you'll want to use slime-quit-lisp to kill the swank

2:57 LauJensen: Good morning crew

2:57 amalloy: morning lau

2:58 happen to know if there's a limit to the length of a symbol?

3:01 never mind, i guess there isn't. clojure is perfectly happy to give me 10000 a's in a row as a symbol

3:02 quizme: http://pastie.org/1183807 <--- I'm trying to use (ns main (:use mymessage)) but I'm getting java.io.FileNotFoundException ....

3:02 my classpath has "." in it.

3:04 amalloy: quizme: the usual lisp problem: not enough parens :)

3:04 quizme: are u serious ?

3:04 holy fudge thanks

3:04 amalloy: (ns main (:use (mymessage)))

3:04 quizme: ok

3:04 i'm retarded

3:04 than you

3:04 amalloy: welcome

3:05 the intended usage pattern is something like (:use (super.meta.hyper sub1 sub2 sub3)); thinking of it that way helps me remember the parens

3:06 quizme: amalloy ok thanks for the pneumonic

3:06 i mean mnemonic

3:07 raek: but (ns main (:use (mymessage))) shouldn't work, right?

3:07 amalloy: raek: why not? works for me

3:07 raek: would that use no namespaces with the prefix mymessage

3:07 LauJensen: amalloy: For some reason I didn't get a highlight, but by convention the limit is 74 characters

3:07 amalloy: LauJensen: the reason is i didn't use your whole name :P

3:08 LauJensen: amalloy: no, its set to hightlight many forms of my name, including 'lau'

3:08 amalloy: oh, neat

3:09 quizme: amalloy Unable to resolve symbol: print-message

3:09 amalloy: okay, maybe i'm wrong

3:09 quizme: hehe

3:09 raek: quizme: I would recommend to check out some project management tool, such as leiningen or cake. managing the classpath manually is not very fun in the long term. lein and cake does this things for you automatically

3:10 (super.meta.hyper) is the degenerate case of (super.meta.hyper sub1 sub2 sub3)

3:10 => no namespaces used

3:10 quizme: raek. ok. leiningen then i guess.

3:11 amalloy: yes, you're right. clojure's namespace syntax still confuses me, i guess

3:11 raek: you should be able to do it manually, of course...

3:11 quizme: making a irc client/bot too?

3:11 quizme: weird... it's working now though...

3:11 raek: just doing a tutorial

3:12 raek: but yeah it's possible i might make one

3:12 raek: wanna put chat on my website.

3:13 raek: also, I kinda wanna make a real-time interactive type of a program.

3:13 raek: quizme: http://github.com/raek/quirclj/ http://raek.se/quirclj/

3:13 my try to make an irc library

3:13 quizme: raek ok thanks i'll try it out

3:13 raek: I mostly use Raynes' irclj myself, http://github.com/Raynes/irclj

3:14 most importantly, his library is fairly complete

3:14 I have just begun on mine

3:15 quizme: i have a bad habit of wanting to make everything from scratch

3:15 raek: me too, kinda

3:15 but I will try to integrate whatever gets done in quirclj into irclj

3:16 amalloy: raek: i think my "degenerative form" still works, though

3:17 raek: doesn't work for me

3:17 just returns nil, but nothing is used

3:17 amalloy: oh, here is an interesting twist

3:18 (ns tmp (:use (myns.core))) doesn't work, but (ns tmp (:use [myns.core]))) seems to

3:18 raek: http://pastebin.com/kw9m6hRN

3:18 yes, the square brackets mean a different thing

3:19 there should be some error reporting if one tries to use the empty prefix list, I think

3:20 that has cause *so many* beginner's mistakes

3:20 *caused

3:21 amalloy: raek: or it should be documented, at least - (doc ns) doesn't mention square brackets

3:21 (or, indeed, the lack of round parens)

3:23 raek: hrm, that's bad...

3:25 amalloy: one of these days i'll get around to filling out a contributor agreement and fix some holes in the docs

3:26 but for now, it's bed time

3:26 quizme: anybody have a suggestion on how to be awesome in the Clojure community and get a Clojure job?

3:28 amalloy: quizme: start your own business using clojure

3:29 dmead: hey channel

3:29 raek: quizme: nothing more specific than: code. a lot. and hang around in #clojure and the group.

3:29 dmead: is there a tool to show the AST for a clojure program?

3:30 raek: well, in Lisps, some people would say that the code is the AST...

3:30 dmead: well yea, but the compiler still has to use it's own representation

3:32 raek: is there something that's not present in the lists and vectors of the code representation that you need? (just curious)

5:44 mrSpec: Hello

5:45 I'm trying run "lein swank" but I got "That's not a task. Use "lein help" to list all tasks."

5:45 what am I doing wrong?

5:45 LauJensen: mrSpec: Add this to project.clj " :dev-dependencies [[leiningen/lein-swank "1.2.0-SNAPSHOT"]]" then run lein deps, then try again

5:46 mrSpec: ahh, I had ::dev-dependencies :/ My mistake. Thanks!

5:54 tomoj: I want to work with this proprietary file format which basically describes nested hashmaps and vectors

5:54 mrSpec: I have one more problem, when trying run slime-connect "Versions differ: 2009-08-02 (slime) vs nil (swank). Continue?" It means that my swank hasnt been installed?

5:54 tomoj: but for the values, it's important that I get the types right when converting back into this format

5:55 for instance if the value of one field in a hashmap is a short, I need to keep it as a short when converting back

5:55 and I probably don't want users of my library to have to care

5:55 so it seems like I'm going to have to describe the types of all the fields somehow

5:55 any ideas?

5:56 maybe I can put the types in metadata on the maps?

5:57 then users just have to preserve metadata

5:57 LauJensen: tomoj: It depends a lot on your own API, but generally speaking this would be the use-case for meta-data

5:57 tomoj: it seems strange, though..

5:57 LauJensen: mrSpec: I saw a fix for that someone in the intertweet a few weeks (2 - 3?) ago. Forgot when where how

5:57 tomoj: I need to understand better which operations preserve metadata and which don't

5:58 LauJensen: tomoj: Are there any inconsistencies?

5:58 mrSpec: LauJensen: are logs available anywhere?

5:58 logs?

5:58 clojurebot: logs is http://clojure-log.n01se.net/

5:59 mrSpec: o :D

5:59 tomoj: LauJensen: you mean in the way clojure treats metadata?

5:59 LauJensen: mrSpec: I think it was on disclojure.org

5:59 tomoj: yes. As I understood it, meta data only works with clojure datatypes, and no function taking and returning one such, breaks it

5:59 tomoj: well..

5:59 mrSpec: LauJensen: ok, thanks

6:00 tomoj: ,(meta (into {} (with-meta {:foo 1} {:bar 2})))

6:00 clojurebot: nil

6:00 bobo_: mrSpec: let me know if you find it. i get that error aswell but havent botherd to fix it

6:00 mrSpec: bobo_: but it works for you

6:00 with this error?

6:00 bobo_: yes, just press y

6:00 tomoj: ,(meta (seq (with-meta {:foo 1} {:bar 2})))

6:00 clojurebot: nil

6:00 mrSpec: ah ok

6:00 tomoj: you lose metadata when you seq

6:00 I don't know if there are other places

6:01 mrSpec: I have to go afk for a wile, I'll check this in the afternoon

6:01 LauJensen: tomoj: How odd

6:02 tomoj: so e.g. one of the tags is a list of doubles

6:02 if

6:02 well, actually

6:02 that should be fine

6:03 I can store a typemap in metadata on the hashmaps

6:03 even if the values are things the user will seq, they probably won't seq the hashmaps themselves

6:03 and metadata is retained in merge

6:31 kjeldahl: Regarding slime-connect version messages, if you're emacs users, this is what I have in my .emacs: (require 'slime)

6:31 (setq slime-protocol-version 'ignore)

6:31 Seems to work fine.

6:37 neotyk: kjeldahl: removing compiled slime files (those with elc) helped for me

6:40 kjeldahl: neotyk: Ok, thanks.

6:41 neotyk: kjeldahl: np. hth

6:49 fliebel: Hey, I've been fighting bugs since yesterday. I'd really like a debugger now. What is the best way to get this? Google returns a little dissatisfying and contradicting results. I'd even be willing to go over to the evil side and install a huge Java IDE. I'm currently using VimClojure, but I don't think that sports a debugger.

6:52 neotyk: fliebel: what kind of debugging?

6:53 fliebel: could you narrow problem to simple fns and play with them in repl?

6:53 fliebel: neotyk: Just figuring out what a certain variable contains at a certain point without adding println all over the place.

6:54 neotyk: fliebel: with slime you could do slime.core/break

6:54 this was ported from debug repl

6:54 fliebel: neotyk: That is what I've been doing, but just jumping in the middle of an fn and check some values is very helpfull :)

6:54 ah

6:54 I'm not on Emacs, but I could have a look at the debug repl

6:55 neotyk: so you don't need slime for it

6:55 fliebel: And I'm just reading CCW has breakpoints.

6:56 neotyk: could be, I have this thing against eclipse, running for years already ;-)

6:57 so for me anything than eclipse ide is much more attractive

7:29 serp_: let's say I have two threads continiously running transactions that poke the same ref. is there some mechanism that prevents one of the threads to starve?

7:37 lpetit: raek: once you've used (read) on your code, everything should be in the return of the (read).

8:04 LauJensen: fliebel: Fantastic blogpost

8:05 lpetit: LauJensen: link ?

8:06 LauJensen: http://pepijndevos.nl/how-reify-works-and-how-to-write-a-custom-typ

8:06 fliebel: LauJensen: Thanks :)

8:09 LauJensen: I'm amazed by the responses I get :) I even got an email from one of the Amsterdam Clojurians if I want to give a talk at one of their meetings. But… It's chouser who did all the hard work obviously.

8:10 LauJensen: fliebel: You're from Amsterdam ?

8:10 fliebel: LauJensen: Nope, about a hour away from it.

8:11 LauJensen: Ah ok. Well, its a good blogpost deserves some PR. We're actually considering mounting a Conj Labs in Amsterdam :)

8:13 fliebel: LauJensen: I would really like to come. Only need to save some money :(

8:14 LauJensen: Yea would be cool. For a late 2010 session we've discussed London and Amsterdam and right now the arrows pointing across the sea so you might have 'good' time as the next session likely won't be before february

8:14 kjeldahl: Let me see if I understand: In order to be able to use postgresql with clojure (and leiningen), I need to 1) Download the jar postgresql-9.0-801.jdbc4.jar from jdbc.postgresql.org, 2) Create my own repository in ~/.m2 (make up a name, rename jar to postgresql-9.0.jar), and then finally list in project.clj as a normal dependency?

8:15 LauJensen: kjeldahl: I think there already exists an artifact for that driver in Maven Central, so just add that name to :dependencies, run cake deps and you're good to go

8:16 kjeldahl: LauJensen: Ok, and if so I do not need to manually get the jdbc stuff? I have seen org.clojars.kjw/postgresql on clojars.org, but not sure what it is.

8:17 fliebel: LauJensen: Bussel or Londen is also doable. I just need to find the financial resources. :) I'd better start of by buying the Joy of Clojure :)

8:17 LauJensen: kjeldahl: http://lmgtfy.com/?q=postgres+jdbc+driver+maven+artifact

8:18 kjeldahl: lol

8:18 LauJensen: :)

8:18 kjeldahl: I'm clueless about the java build systems or whatever they are. That's why I'm asking all the stupid questions. I haven't typed maven once so far...

8:19 LauJensen: I didn't type it because I thought you were stupid, I just wanted you to know what I did, instead of just giving you the artifact name

8:20 kjeldahl: So I have to step out of the leiningen kindergarden and learn about Maven and poms?

8:21 Ok, reading http://www.infoq.com/news/2009/11/clojars-leiningen-clojure

8:24 LauJensen: kjeldahl: not poms. Its just a matter of getting the right name for the dependency, ie follow the link above, click the first hit, click details, see

8:24 <dependency>

8:24 <groupId>postgresql</groupId>

8:24 <artifactId>postgresql</artifactId>

8:24 <version>8.4-701.jdbc4</version>

8:24 </dependency>

8:24

8:24 In Cake (or lein) that means [postgresql/postgresql "8.4-701.jdbc4"]

8:24 Put that in project.clj and run 'cake deps' (replace cake with lein if you prefer to use lein)

8:25 kjeldahl_: LauJensen: Thanks a bunch agian.

8:25 LauJensen: np

9:15 djpowell: Is there a guide anywhere about the primitive and equality features that are currently in master?

9:16 LauJensen: djpowell: check the assembla wiki

9:16 djpowell: I was there during all the experiments, but I can't remember what went in

9:16 Ok, cool, I'll take a look

9:19 LauJensen: hugod: Did you remove your demo-documentation from the pallet github site?

9:34 hugod: LauJensen: not intentionally

9:34 * hugod checks

9:34 LauJensen: hugod: check the link on the front page of pallets repo

9:39 hugod: LauJensen: Fixed. Thanks for letting me know.

9:39 LauJensen: np

10:00 fliebel: Is there any way clojure.contrib.trace is going to work again, or is it just dead since 1.2?

10:02 chouser: did it stop working because of the direct binding of core fns?

10:18 LauJensen: fliebel: ^^

10:20 fliebel: chouser: No idea… Someone on stack overflow said it was because of direct compilation of recursive calls or something like that.

10:30 bhenry1: with

10:30 (try (make-client acct-num acct-name active q-id q-title)

10:30 (catch Exception e))

10:30 i still get:

10:30 java.lang.AssertionError: Assert failed: (string? q-title)

10:30 how can i catch my :pre conditions?

10:30 fogus: bhenry1: (catch AssertionError e ...

10:31 bhenry1: ah. so that's where that comes from. derrr moment.

10:36 xkb: hi

10:37 Does clojure have a function like zip in haskell?

10:37 mrBliss: you can use (map vector coll1 coll2)

10:37 xkb: ok let me try that

10:37 aha

10:38 to create sublists

10:38 fliebel: xkb: Don't know Haskell, but there is zipmap

10:38 xkb: fliebel: thanks

10:38 I'm trying to simplify some code

10:39 iterating over two lists, applying a function to the element at the same index

10:39 mrBliss: ,(map (fn [a b] (+ a b)) [1 2 3] [10 100 1000])

10:39 clojurebot: (11 102 1003)

10:39 xkb: in haskell I would solve it using zipWith, as in zipWith (+) [1,2,3] [4,5,6] => [5,7,9]

10:39 fliebel: xkb: That'd be what mrBliss said, but with your won function instead of vector

10:40 mrBliss: ,(map + [1 2 3] [10 100 1000])

10:40 clojurebot: (11 102 1003)

10:40 xkb: ok :)

10:40 nice

10:40 that's what I meant

10:40 funny map takes several collections

10:41 mrBliss: it stops as soon as one is exhausted (also works with infinite sequences)

10:41 ,(map vector [4 5 6] (range))

10:41 clojurebot: ([4 0] [5 1] [6 2])

10:42 fliebel: mrBliss: I heard someone say apply can also take a lazy seq, but I can't see how.

10:42 mrBliss: fliebel: Neither can I :)

10:45 fliebel: mrBliss: This could work though: (apply #(+ %1 %2) (range)) because the fn has an arity of 2, only 2 items of range would be needed, more would throw an error anyway.

10:46 Is there a way to tell how many args an fn takes?

10:47 mrBliss: fliebel: your apply example doesn't work in my REPL (doesn't terminate)

10:47 fliebel: mrBliss: It doesn't but it could theoretically work.

10:50 I fonly there was a more reliable way then :arglists

10:51 mrBliss: fliebel: I think somebody asked the same question yesterday (or the day before), but I didn't remember the answer (if there even was an answer)

10:52 xkb: hmm can u reload a file on the fly in repl btw?

10:52 fliebel: xkb: (require '[some.ms :reload])

10:53 *ns

10:55 d - c = b; xkcd == xkb

10:56 edw: Using SLIME, I often get an error ("error in process filter: if: Wrong number of arguments: nil, 0"), e.g. when choosing a restart in the debugger. This is using `slime-connect' or when connecting to a project. Any thoughts, ideas?

10:57 mrBliss: edw: Emacs 23.2 and the latest slime from ELPA fixed these problems for me

11:00 edw: mrBliss: Hmm. I have 23.2, but have been staying away from ELPA because I can't get it to actually install swank-clojure w/o exploding. (That was before 23.2 though...)

11:01 AWizzArd: I am looking for a Map that can contain only up to N key/value pairs. When a new one is added, then the oldest entry gets removed. Is there already something like that, maybe something that ships with the JDK?

11:01 mrBliss: edw: I usually install everything (slime, slime-repl and clojure-mode) but swank-clojure. Works fine for me. Here are my dotfiles for reference: http://github.com/mrBliss/dotfiles/blob/master/.emacs.d/clojure.el

11:01 AWizzArd: Like: defmemo, but with a memory limit

11:01 defmemomostcurrent

11:01 edw: mrBliss: Thanks for the pointer. I'll check that out.

11:02 chouser: AWizzArd: looks like apache commons collections has LRUMap which may be useful

11:03 AWizzArd: did you want persistent?

11:08 AWizzArd: or perhaps just java.util.LinkedHashMap

11:16 cemerick: AWizzArd: FWIW, some memorization utilities from back in the day, one of which uses LinkedHashMap as chouser suggested: https://gist.github.com/48f2974657cdda5f560d

11:19 xkb: do we have a prefered pastebot?

11:19 chouser: used to be paste.lisp.org, but the bot doesn't come here anymore. anything's fine, lots of people use gist.github.com

11:20 xkb: http://gist.github.com/599202 <= why is this slower than the old version with explicit loop(s)?

11:24 cemerick: xkb: everything in the "new version" is being boxed

11:24 chouser: and boxing hurts

11:24 xkb: How can I prevent that?

11:25 without resorting to the "old" code

11:25 :)

11:26 kelsin: cemerick: for the curious nooby, what is "boxed"?

11:26 havn't heard that term before

11:26 cemerick: kelsin: google autoboxing

11:27 kelsin: nice, searching "boxed" and other things wasn't finding anything, thanks :)

11:27 cemerick: xkb: There may be a primitive-friendly reduce in the new 1.3 static/prim stuff, but I'm not up to speed there yet.

11:27 Aside from that, an explicit loop is the fastest approach AFAIK (but I'm not a numerics expert).

11:28 xkb: 2 bad.. I want to demo this code to a few people new to clojure

11:28 so I prefer the more "functional" style using higher-order functions

11:32 chouser: xkb: using defn inside a defn is wrong anyway

11:32 defn always defines a var in the namespace, not a local scope

11:32 cemerick: heh, I didn't even notice that :-/

11:32 xkb: Everyone does, I think. :-) Here's what's being worked on in that department.

11:32 http://dev.clojure.org/display/doc/Enhanced+Primitive+Support

11:32 xkb: chouser: I'd wanted to use an anonymous function preferably

11:33 chouser: ah, so how do I define a local-scoped function?

11:33 chouser: xkb: (let [fit (fn [a b] ... or (letfn [(fit [a b] ...

11:34 xkb: ah, now I see

11:34 I had the wrong order in the let

11:34 previously

11:35 I'm still wrapping my haskell mind around clojure :P

11:35 chouser: xkb: it's going to be a while, I think before reduce/map on a seq can compete with loop/recur on arrays for raw 100% performance

11:35 AWizzArd: chouser and cemerick: thanks for your suggestions

11:37 cemerick: chouser: It probably just won't happen. seqs -> boxing, not to mention the fn invocation overhead, esp with trivial fns like +

11:37 chouser: seqs return boxed objects, map calls fns using their boxed invoke methods not any primitive even if it exists, and the same for reduce

11:37 cemerick: ...unless the JVM fairy comes around to save us

11:37 chouser: cemerick: right

11:37 cemerick: fixnums being the nirvana, I suppose

11:38 chouser: hm. I suppose some sort of advanced escape analysis during JIT might be able to do something with code like this

11:40 dnolen: chouser: cemerick: rhickey has mentioned several times that he wants higher order operations on primitives - I thought pods/transients were initial work in that direction.

11:40 Scala can do this - so Clojure had better as well ;)

11:40 cemerick: I'm sure they are, but they don't do anything for stuff like (reduce + seq-of-nums) AFAIK

11:41 chouser: dnolen: you're sure scala can do reduce/map on a lazy stream without autoboxing?

11:43 dnolen: chouser: your right, no not lazy - but in Clojure you can't even do it at all - lazy or no.

11:43 chouser: I would imagine however it worked it would be lazy - transients aren't lazy.

11:43 s/would/wouldn't

11:44 chouser: map uses the ISeq interface to get values out of lista and listb, regardless of what sort of collections they are

11:44 I don't see what that has to do with transients

11:48 dnolen: chouser: non-lazy map/filter/reduce that that can work on primitives would be useful is all I mean. transients have to be constructed with loop/recur, there's a pattern here ... the desire for higher order w/o losing perf.

11:49 chouser: dnolen: oh yes, absolutely a desire.

11:50 laurus: Is there a way to change the font size in Incanter's view function? The data rows are so small it's hard for me to read them

11:53 cemerick: dnolen: the notion of a "primitive seq" given the current state of the JVM is a bit of an oxymoron

11:55 chouser: well, I'm sure it could be done if everything were fully typed.

11:56 dnolen: cemerick: but we already have gvector, whether primitive map iterates over a collection one by one using ISeq is implementation detail I think. no?

11:56 chouser: one could certainly imagine a IChunkedIntSeq with an IIntChunk that had an nthInt method that returned primitive ints

11:57 cemerick: dnolen: gvecs aren't seqs, in spirit or impl AFAIU

11:57 lpetit: Hello

11:57 laurus: JTable is hilarious

11:57 chouser: ...and a mapInt fn that used those and called the .invoke(int, int) method of the :static fn you give it

11:57 ...etc...

11:57 cemerick: chouser: scary.

11:57 laurus: How do I print a method's source code in Clojure?

11:58 * lpetit is still fighting with AOT compiled classes and classloaders in an OSGi context ...

11:58 AWizzArd: laurus: typically the source cold will be compiled away. So, if you want to keep it, you should store it somewhere.

11:58 rhickey: we are well on the path to primitive leveraging HOFs

11:58 dnolen: cemerick: ? http://github.com/richhickey/clojure/blob/master/src/clj/clojure/gvec.clj#L54

11:58 chouser: ...and a compiler that used various bits of metadata to find these various classes and fns when properly hinted.

11:58 laurus: AWizzArd, I see

11:58 AWizzArd: laurus: In Contrib there is a 'source' macro, I think in repl-utils

11:59 laurus: I want to override the view function in Incanter to change the font size for the JTable

11:59 rhickey: now that we have fns that can take/return primitives, and collections of primitives

11:59 cemerick: dnolen: but that VecSeq is going to box every primitive flowing out of it. rhickey's got tricks a'comin' though, I'm sure.

11:59 chouser: laurus: for functions whose source .clj is on the classpath, you can use (source <fnname>) in the repl, like (source map)

12:00 laurus: By golly it worked! Thanks AWizzArd and chouser!

12:00 cemerick: lpetit: that's a good fight. I'll help if I can.

12:00 chouser: AWizzArd: it's in clojure.repl now

12:00 rhickey: need an abstraction for primitive fns, a la IFn, and a protocol for communicating A) I want primitives, B) I take primitives, C) I can provide primitives, for participant fns/structures

12:00 AWizzArd: chouser: ah, it moved

12:01 laurus: AWizzArd, chouser: Unfortunately this is a defmulti, so how do I view the defmethod that I want?

12:01 rhickey: cemerick: right, collections of primitives only satisfy the Object based interfaces today, but could easily do more tomorrow

12:01 AWizzArd: laurus: it really is meant as a little helper tool. If you want to look at source code you are supposed to open the .clj file in your editor.

12:01 rhickey: and pods do come into play when used to avoid the internal boxing of chained laziness

12:01 laurus: AWizzArd, ok :)

12:02 cemerick: rhickey: then we might have something like lazy-seq-int in the future for when we know we're returning ints in our seq-producing code, etc?

12:02 chouser: rhickey: pods could replace my theoretical IChunkedIntSeq above?

12:02 lpetit: rhickey: how does an AOT compiled gen-class, when loaded from plain old java class (for example), initialize itself ? Specifically, is there something special concerning the classloader that will be used to load/use/require its dependent namespaces (hypothesis: those are not already loaded) ?

12:03 cemerick: thks :)

12:03 rhickey: see the iterseq stuff here for a hint of pods used with seqs http://gist.github.com/306174/

12:03 cemerick: I hope not. I hope that the primitiveness can be hidden

12:03 if everything can handle primitives, it just works

12:04 chouser: laurus: I don't think the line number of defmethods is stored anywhere currently, so no way for 'source' to look it up.

12:04 rhickey: but might need some help for return values, which drive

12:04 AWizzArd: hmm

12:04 laurus: chouser, it's okay, thanks :)

12:04 rhickey: e.g. reduce-long

12:05 chouser: hm, that's a well-forked gist

12:05 lpetit: too early to twitt about the future availability of primitive handling everywhere in clojure ?

12:06 rhickey: lpetit: yes, way to early

12:06 too

12:06 lpetit: rhickey: Then please answer my question about AOT compilation, so that I can dig into this problem again :-p

12:06 xkb: :)

12:06 chouser: if fns picked up the :line metadata from their forms, 'source' could be extended to help with defmethods

12:09 lpetit: btw, cemerick, chouser et al., if you know the answer, you're very welcome. I'm hitting this problem since saturday night :-(

12:10 chouser: lpetit: every time I've tried to understand OSGi and related classpath issues, I only get a headache.

12:10 lpetit: I'll try again some day, but as of yet I have no answers.

12:11 cemerick: lpetit: AFAIK, clojure-on-osgi is still an impossible needle to thread, at least in general terms.

12:12 * AWizzArd wished there was a marker interface for Records.

12:12 lpetit: chouser: I'm close to an interesting solution for solving the "macro" issue, that is allowing bundle A to contain some clojure code, bundle B to contain clojure core, and with just the "A depends on B" declared dependency (OSGi declared), have bundle B be able to refer back to bundle's A classloader environment.

12:14 chouser: lpetit: interesting.

12:15 lpetit: Basically, here is what I'm doing in bundle B (let's name it ccw.clojure) : in the start() method, Class.forName("clojure.lang.RT") to start the initialization. And just after that, get the Compiler.LOADER var, set its root value to my own ClassLoader, which redefines findClass() by first delegating to ccw.clojure's classloader, then to each classloader of the bundles which declare depending on ccw.clojure.

12:15 This creates a "web" of bundles which share the same clojure instance, held by ccw.clojure bundle.

12:16 Normally, even AOT compiled classes living e.g. in bundle A should be able to work correctly.

12:18 But I'm now in the testing phase, and I'm facing problems : my enhanced classloader I placed in Compiler.LOADER seems to be used for some use cases, but when a namespace is loaded indirectly via the loading in memory of an AOT compiled class (a namespace with a :gen-class directive in it's ns TLE), it seems like my enhanced classloader is not called.

12:18 rhickey: lpetit: it just bottoms out to the normal RT.load stuff. At AOT load time however, Compiler.LOADER won't be bound, which is probably not what you want. But the correct way to drive things is with the contetClassloader, which will be used if set up

12:19 lpetit: s/seems like/seems that/

12:19 sexpbot: <lpetit> But I'm now in the testing phase, and I'm facing problems : my enhanced classloader I placed in Compiler.LOADER seems to be used for some use cases, but when a namespace is loaded indirectly via the loading in memory of an AOT compiled class (a namespace with a :gen-class directive in it's ns TLE), it seems that my enhanced classloader is not called.

12:20 lpetit: Thus my question: is there anything special concerning the "loading" of AOT compiled classes that I've not taken into account. I have the vague feeling that the classloader which is used is the classloader of the bundle of the AOT compiled class, when I thought (and I've browsed clojure code again and again) it should have been what RT.baseLoader() returns, which should *always* be my enhanced classloader once I've installed it at

12:21 cemerick: I think I'm close to a working general solution, see ^^^

12:21 rhickey: lpetit: you could have static init order problems

12:22 cemerick: lpetit: I hope so.

12:22 rhickey: lpetit: banging something into Compiler.LOADER is unsupportable

12:22 lpetit: rhickey: context classloader is unpredictable in OSGi environments.

12:23 cemerick: I worry that no one yet in the community has enough osgi expertise to really be able to spec out a full solution though.

12:23 e.g. ouch: http://twitter.com/njbartlett/status/23931383593

12:23 Not that that has any bearing on practical use of it when one has control of the app in question.

12:23 rhickey: lpetit: right, thus the many problems, The entire notion of webs of classloaders is outside the scope of the original definition of classloaders and every OSGi-like module environment invents their own stuff

12:24 lpetit: rhickey: it's just not used, and what should be in it is unspecified by the spec, and every implementation vendor is doing something slightly different with it to help "legacy" code work

12:25 rhickey: but I still rarely see coherent reports of what exactly is wrong with OSGi+Clojure, mostly just "it won't work" which it obviously will, but certain anticipated things don't, but are not specified

12:25 lpetit: cemerick: maybe I'll post the same content to twitter in a few days, "have been brainstorming OSGi/Clojure with cgrand lately ..." . Just hope the end will look different, though :)

12:26 rhickey: at least saying - I wan't to share a single clojure.lang namespace from multiple modules is more coherent

12:26 cemerick: rhickey: I have notes floating around here from a painful twitter discussion with Neil some months ago. I'll try to ping him before the conj to get an update on his thinking.

12:27 lpetit: rhickey: be "clojure" the name of a bundle with OSGi sources. be "client" the name of a bundle requiring bundle "clojure". Be "ns1" a ns in bundle "client". Be "ns2" a ns in bundle "client". let "ns1" (:require ns2).

12:28 rhickey: lpetit: in spite of the general lack of support for context classloaders in OSGi, setting one up for the specific purpose of communicating with RT.baseLoader should still work

12:29 lpetit: you could also experiment with patching Compiler.compile()'s generated static load() method to push LOADER, RT.makeClassLoader()

12:29 lpetit: rhickey: now from bundle "client", require "ns1". When trying to require "ns2", we will be in a class from bundle "clojure". This class will use the context classloader (default for clojure), which will resort in most OSGi envs to use the classloader of the class's bundle as a last resort. And bundle "clojure"'s classloader has no visibility on classes and other resources in bundle "client". Thus has no visibility on the resource "

12:30 rhickey: lpetit: but you can set up the context classloader, not rely on OSGi to do so

12:31 lpetit: rhickey: Yes. I want to share a single clojure bundle from multiple bundles. That's what OSGi can offer to me, or else I have to create a separate "world" inside OSGi, which I won't ('cause then there's absolutely no possibility for AOT classes to connect to this "separate world")

12:32 rhickey: I don't want to mess with the context classloader 'cause I want to play the OSGi rules well: it's content is not guaranteed, nor is it guaranteed that if I place something in it, it will stay forever at the value I placed. And, also, context classloader should be set for each and every thread which could "hit" clojure bundle via e.g. loading of an AOT class from a declarative GUI stuff in Eclipse, and I have *no* possibili

12:33 rhickey: lpetit: right, so OSGi and it's ilk really only consider dynamic use of Class.forName and patch that. They have no standard way for dynamic classloaders to attach to useful roots in their classloader-web systems

12:33 but they usually have some way (buddies or somesuch?)

12:34 lpetit: OSGi etc don't have rules for non-static deps, that's the problem. So you play by their rules and nothing useful happens

12:34 lpetit: rhickey: with some limitations. I've tried playing with buddies on Eclipse, but it seems that it will not work if you do not declare all the potential interesting packages in advance as "exported packages". Will not provide an interesting dynamic experience in a repl

12:34 rhickey: they are seriously only thinking about Java and Java-like static deps

12:37 I'd recommend this: lpetit: you could also experiment with patching Compiler.compile()'s generated static load() method to push LOADER, RT.makeClassLoader()

12:37 lpetit: rhickey: currently, Compiler.LOADER's root seemed free from any value. So I thought that just after clojure's initialization, where it's OK to let the default behaviour happen, since clojure only depends on itself, I could place once and for all what must be used for the lifetime of the clojure bundle. I even placed an shutdown-agents call in the bundle's (stop) method :-)

12:38 rhickey: perhaps substituting a new DynamicClassloader(osgi-loader being used right now)

12:38 lpetit: rhickey: ok, will leave within minutes and no time to dig into the code now. Could you explain more what you're suggesting, so that I can go ahead offline without any further tip ?

12:38 rhickey: lpetit: see above about static init order

12:39 lpetit: I don't understood the part about static init order :-(

12:39 rhickey: lpetit: the code you've written to set up Compiler.LOADER isn't being called before the static init of a class that needs it

12:40 lpetit: rhickey: re: perhaps substituting a new DynamicClassloader(osgi-loader being used right now) = that's what I'm doing, instanciating a DynamicClassLoader with my enhanced osgi-loader and placing it in Compiler.LOADER's root

12:40 rhickey: pushing in the AOT-generated load() will ensure that, and you can root with the OSGi loader that's loading first, creating the transitive dep you want

12:41 lpetit: placing it in when, that's the problem

12:42 AOT-generated load() will be called at static init time, a very dangerous time where only some classes are loaded and the load order depends on the dependency graph

12:42 lpetit: rhickey: ok, I thought that since I was pushing it way before the AOT class was really loaded (because it is loaded lazily by the Eclipse framework when I first try to open a file), it was ok.

12:44 rhickey: lpetit: you might not even need your special loader

12:44 which is better, because you are likely to violate OSGi by doing that

12:46 lpetit: rhickey: unfortunately, I must leave now, I'm very late. I'll try to come back later this night. I'm surprised you think there could be a solution without violating OSGi rules (or just using the way OSGi impls currently violate OSGi rules with their context classloader solutions ?)

12:46 rhickey: the solution would be in "pushing in the AOT-generated load()" ?

12:46 rhickey: lpetit: try that

12:46 lpetit: rhickey: I don't understand what this sentence means concretely :-(

12:48 * lpetit don't mind violating OSGi when he sees *all* OSGi implementations auto-violating themselves !

12:48 rhickey: Compiler.compile() generates the AOT class, including a static load() method that is called from the class' static init. Actually you could do the push in the static init since there's already pushing in there

12:49 lpetit: rhickey: ok, when you talk about push, it's "bytecode" jargon, right ? I'll look at this tonight. Thanks.

12:49 bye

12:50 rhickey: http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#l6631

12:50 oh well

12:57 AWizzArd: How can I enforce to get an int in the current master? At the moment I have: (class (int 50)) ==> java.lang.Long

12:58 cemerick: ,(class (.intValue 50))

12:58 clojurebot: java.lang.Integer

12:59 cemerick: Though I can't think off the top of my head why that would be necessary.

13:00 AWizzArd: cemerick: I would like to test my serializer function, which can in principle also be used from Java directly.

13:00 cemerick: gotcha

13:01 rhickey: ,(class (Integer/valueOf 42))

13:01 clojurebot: java.lang.Integer

13:01 rhickey: on 1.3:

13:01 user=> (class (.intValue 42))

13:01 java.lang.Long

13:01 want an Integer, say so

13:02 don't rely on side effects

13:02 impl details

13:03 AWizzArd: Well, the type gets changed to Long somewhere. (def i (Integer/valueOf 100)) ... (class i) ==> Long

13:05 It's not that important, I am just testing to serialize different data types and now it was Integer's turn, but I am pretty sure the fns work correctly.

13:07 sproust: AWizzard: is this serializer part of something open source?

13:07 rhickey: AWizzArd: could you please post a bug report for that last example?

13:07 AWizzArd: sproust: it will be in some days

13:07 rhickey: ok

13:07 rhickey: thanks

13:08 sproust: AWizzard: under what name? I'm interested; have to write something with serialization/deserialization too.

13:09 AWizzArd: sproust: I will tell you more in some days ;)

13:10 sproust: I tested today its speed, and it seems pretty efficient, all written in Clojure. For example, I serialized one million "Hello World 88" strings (with numbers from 1 to one mio) within about 2 seconds, and deserialized those from disk back within a bit over one second, on simple desktop hardware, no SSD

13:13 sproust: Interesting. Here's my use case: I have code generator for a network protocol that supports substructures, variable length lists, enums, var length strings and all the PODs. It works with C++ and Python, and I'd like to be able to connect a Clojure process to these guys. Option 1: write a Java backend and use it from Clojure, Option 2: write a backend directly in Clojure. It sounds like you've done (2).

13:14 Do you support unsigned integer types?

13:16 aaron__: trying to understand why I'm not allowed to nest anonymous functions

13:16 java.lang.IllegalStateException: Nested #()s are not allowed

13:16 TeXnomancy: it looks like sometimes defn copies all the var's metadata to the fn and sometimes it doesn't (in clojure 1.2); is that a known bug?

13:16 mrBliss: aaron__: you won't know if % belongs to the inner or the outer anonymous function

13:17 TeXnomancy: trying to narrow down the circumstances in which it gets dropped

13:17 AWizzArd: sproust: I've done (2), yes. In principle everything is supported, though if you want unsigned types then a wrapper defrecord should be used.

13:17 dnolen: aaron__: you can nest anon fns, just not #()

13:17 aaron__: oh so if i just convert to (fn... syntax?

13:19 dnolen: ,((fn [x] ((fn [y] y) x)) 1)

13:19 clojurebot: 1

13:19 dnolen: aaron__: ^

13:20 njbartlett: cemerick: Yes, I do :-)

13:20 cemerick: njbartlett: nifty :-)

13:20 njbartlett: cemerick: Just asking Alexey if he's available

13:21 cemerick: njbartlett: Laurent Petit has been on a bit of an OSGi/Clojure crusade the past few days -- though he just took off....

13:21 I looked into it somewhat briefly a while ago as well, if you'll remember.

13:22 TeXnomancy: also: is there a reason (:name (meta (fn my-fn []))) doesn't return my-fn?

13:22 njbartlett: cemerick: Okay. There are a number of challenges, and Alexey seems to be quite far along. He has the advantage of knowing OSGi well for a few years before getting involved in Clojure

13:22 aaron__: dnolen: thnx

13:22 njbartlett: cemerick: I looked at it also, but I just don't know Clojure :-)

13:23 cemerick: njbartlett: yeah -- I have a vague notion of the issues involved, but I'm not clear enough on them to really push the issue with rhickey.

13:23 aaron__: mrBliss: ah yes, ambiguity. thnx for explanation

13:23 njbartlett: cemerick: Well as I recall, when I first looked it was impossible because Clojure used a fixed classloader. Recent versions use the Thread Context ClassLoader so that can be adapted.

13:24 cemerick: Right...that's where it sounds like Laurent is poking at (though perhaps there are other issues around AOT-compiled classloading as well).

13:24 aav: njbartlettb: right. now it somehow possible.

13:24 cemerick: njbartlett: if either you or Alexey can write up the main blockers as you guys see them, that would go a long way towards bridging the divide, as it were. :-)

13:24 njbartlett: cemerick: But there's still significant challenges such as dynamic unloading etc, which may happen in OSGi but there doesn't seem to be any way to release the classes associated with a Clojure value. Still it won't be a disaster if that aspect is not supported.

13:25 cemerick: Looks like aav is online now

13:25 cemerick: Yeah, unloading seemed to be the biggest challenge when I looked at it, and also possibly parallel multiple versions of the runtime.

13:25 aav: nice to meet you :-)

13:26 aav: cemerick: Hi! :)

13:26 njbartlett: cemerick: Yup. I wanted to avoid multiple clojure runtimes because they seem rather slow to start, e.g. a few seconds. Maybe it's improved but you certainly don't want more than (say) 10 Clojure runtimes floating around :-)

13:26 cemerick: It's a necessary evil thanks to classloading.

13:27 There's certainly value to being able to ramp up whatever modules one happens to have around, and not have to worry about one using 1.2.0 vs. another using 1.3.0, etc.

13:27 njbartlett: aav: Do you know how far Roman Roelofson got with his effort?

13:27 aav: njbartlett: i think 1 runtime is ok. in any case we have only one jvm runtime. proper control over such things as loading/unloading could help a lot

13:28 njbartlett: i don't know

13:29 njbartlett: in fact there is a more fundamentsl question - what is clojure/osgi integration. as we discussed some days ago.

13:31 cemerick: aav: That's been a recurring question here as well. Some that have much more osgi experience have apparently been frustrated with clojure, but getting more formal descriptions of what was needed to smooth the way has been tough.

13:31 njbartlett: aav: Yes you're right. It's clear that a dynamic non-oo language doesn't need some of the service oriented features offered by OSGi. I see it as more important for interop between Clojure and non-Clojure code in a large application

13:32 aav: For example, what if I want to write an Eclipse plug-in in Clojure?

13:32 cemerick: Apologies for that. It's a lack of understanding on both sides, I believe.

13:32 cemerick: njbartlett: Exactly why I invited you :-D

13:32 aav: njbartlett: or seeing osgi as a simply loading/modulariation tool for a pure clojure app. as I see it now with my project

13:33 cemerick: My usage is always very straightforward, e.g. using RCP for a dedicated app, which is not a problem.

13:34 njbartlett: Right I think OSGi offers some nice features w.r.t deployment and management even in a pure Clojure app.

13:34 aav: njbartlett: right. that is what i'm talking about

13:36 njbartlett: aav: You would know more about that, and whether those advantages are truly compelling. From my side it's a practical issue -- I'm not able to use Clojure as long as it's incompatible with my preferred runtime. And even when I do use it, it is likely to be part of a mixed language environment with lots of Java libraries

13:37 cemerick: To me, it seems the big question is: are there changes to clojure itself that are necessary to get to an ideal solution (given the dynamic nature of things), or are we just looking at a good BundleActivator recipe that shows how to link up the classloaders properly?

13:37 njbartlett: aav: You want to summarise what you've achieved so far?

13:38 cemerick: I think we can get quite far without changes to Clojure, but dynamic unloading doesn't seem possible currently.

13:38 cemerick: And it's more likely to be an extension bundle that can be installed to enable Clojure support, rather than a BundleActivator recipe

13:39 cemerick: njbartlett: so the premise is only one version of clojure loaded and available per runtime then?

13:39 aav: njbartlett: the main thing i have for the moment is a more or less proper loading of clojure files from different osgi bundles, that respects osgi classloading

13:40 njbartlett: Okay how about we state some requirements...

13:40 First, we should be able to ship .clj files in a bundle and have them loaded and run by the Clojure runtime

13:40 aav: i.e.: if a.clj from the budnle A loads b.clj from the bundle B, and b.clj refers to some java class, that is not exported from B - it will work

13:41 cemerick: may I suggest a shared google doc? :-)

13:41 njbartlett: Second, those .clj files should have visibility of compiled classes shipped in the same bundle, and/or the imported by the bundle

13:41 Hehe good plan

13:41 cemerick: njbartlett, aav, /msg me your gdocs email addys :-)

13:41 njbartlett: njbartlett at gmail dot com

13:42 cemerick: I'll rope Laurent in next time I see him as well

13:43 njbartlett: https://docs.google.com/document/edit?id=11G7v_I1DMWisc5pWKWisW85rUkGk9egi_voT4Mp_vQo#

13:43 njbartlett: cemerick: Thanks. It's great to have you working to try to solve this....

13:43 cemerick: The OSGi Community Event is happening this week, there's likely to be a few people there interested in Clojure too

13:43 cemerick: njbartlett: I doubt I can contribute much, unless there actually are Clojure changes to be made. Just trying to get the right people together. :-)

13:44 njbartlett: cemerick: Right, which in itself is a big help

13:44 aav: cemerick: that's the most important thing

13:45 * aav will publish current state of clojure.osgi @github (probably even today)

13:45 cemerick: njbartlett: Nifty; if anyone there has ideas/concerns/whatever on the topic, point them at the gdoc, and I'll add them in if they have particular points they want to push

13:46 njbartlett, aav: http://bit.ly/clojureosgi

13:53 ataggart: Does anyone know why bit-shift-left, when passed an int or long will resolve to Numbers.shiftLeft(long, ...), but when passed a byte it resolves to Numbers.shiftLeft(Object x, ...)?

13:56 lazy2: nick lazy1

13:57 lazy1: Sorry

14:09 mrSpec: I had added in project.clj ":dependencies [jung/jung "1.7.6"]", then I did $ lein deps, what should I add in core.clj to use this library? :import [edu.uci.ics.jung.graph.*] is not enough?

14:10 aria42: Will it be possible in 1.3 to make a map which stores primitives as values, similar to the gvec ? A lot of my slowdown from Java for statistical stuff comes from

14:10 lazy1: mrSpec: There's no * import in clojure (IIRC)

14:11 chouser: aria42: I'm not aware of anyone working on a generic hash-map type (gmap?) like gvec.

14:11 dnolen: aria42: why not use defrecord for that? access like map but get primitive fields

14:11 aria42: Wouldn't you need deftype to make it act completely like a map and override toString etc?

14:11 dnolen: aria42: defrecord already has all the map stuff.

14:12 mrSpec: lazy1: ah ok, but (:import [edu.uci.ics.jung.graph.SparseMultigraph] ) doesnt work too :(

14:12 dnolen: (:import [edu.uci.ics.jung.graph SparseMultigraph] )

14:12 mrSpec: ^

14:12 lazy1: After "lein deps" how do you run clojure?

14:13 mrSpec: lein swank

14:13 dakrone: lazy1, 'lein repl'

14:13 aria42: dnolen: Awesome thanks. It's a huge slowdown relative to Java, but might be able to move all machine learning code to Clojure

14:13 mrSpec: and slime-connect

14:13 lazy1: dakrone: That was a question for mrSpec, sorry for not being clear

14:13 mrSpec: Sorry, don't know swank

14:13 dakrone: lazy1, ahh okay, apologies

14:15 aria42: dnolen: I thought defrecord/deftype couldn't return primitives or use as args. at least currently

14:15 mrSpec: lazy1: hmm should this space change anything? it didnt for me

14:15 lazy1: dakrone: Never apologise for a good answer :)

14:15 mrSpec: lazy1: ah I see.

14:16 I got "edu.uci.ics.jung.graph.SparseMultigraph

14:16 [Thrown class java.lang.ClassNotFoundException]"

14:16 lazy1: mrSpec: I use "lein repl" and then (import 'edu.uci.ics.jung.graph.SparseMultigraph)

14:16 mrSpec: lazy1: ok, I'll try this

14:17 chouser: aria42: (defrecord Foo [^int i ^long j]) (clojure.contrib.repl-utils/expression-info '(.i (Foo. 1 2))) ;=> {:class int, :primitive? true}

14:17 lazy1: mrSpec: You can check the value of *classpath* to see if the jar is there

14:18 aria42: chouser: okay thanks. not sure why i thought that.

14:20 chouser: aria42: using (:i x) will autobox the return value I think

14:20 aria42: chouser: right because the ILookup interface returns object

14:21 chouser: right

14:21 mrSpec: lazy1: In lein repl : clojure.core=> *classpath* java.lang.Exception: Unable to resolve symbol: *classpath* in this context (NO_SOURCE_FILE:0)

14:21 and a line earlier I got classnotfound exception :/

14:22 chouser: aria42: but gvec returns autoboxed objects too. both gvec and records will store using primitives with the memory and cache savings that implies

14:22 lazy1: mrSpec: Which version of lein and clojure do you use?

14:23 mrSpec: lazy1: the newest I think, installed today ;) clojure-1.2.0.jar

14:23 lazy1: & Leiningen 1.3.1 on Java 1.6.0_20 Java HotSpot(TM) Client VM

14:25 aria42: chouser: gvec has to do that to satisfy ISeq though. Might be a bad idea but you could have a protocol for a double map that avoided autoboxing.

14:25 lazy1: mrSpec: *clojure-version*

14:25 chouser: aria42: vectors don't implement ISeq, but I know what you're saying.

14:26 yayitswei: quick question: how do you specify compile-path in cake? in leiningen, it's :compile-path "war/WEB-INF/classes"

14:26 mrSpec: lazy1: {:major 1, :minor 2, :incremental 0, :qualifier ""}

14:27 lazy1: mrSpec: Seems OK. The only thing I see is that you're in clojure.core namespace and not in user namespace

14:28 ninjudd: yayitswei: cake doesn't currently support :compile-path. what are you trying to do?

14:28 lazy1: mrSpec: Try (ns user) and then *classpath*

14:29 mrSpec: lazy1: ah, I was in myproject.core package

14:29 yayitswei: ninjudd: trying to build a webapp directory that i can deploy to google app engine (it only accepts a directory, not a war file)

14:30 mrSpec: lazy1: ok, I see "/lib/jung-1.7.6.jar" in this classpath string

14:30 lazy1: mrSpec: Then you've reached the limit of what I can help :)

14:30 mrSpec: och :(

14:30 ok, thanks!

14:31 ninjudd: yayitswei: i would add a copy to the end of compile then

14:31 lazy1: mrSpec: Oh, why is there "/" at the begginng of the jar, should be absolute path to the lib director inside the project

14:31 clojurebot: namespaces 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

14:32 yayitswei: ninjudd: good idea, thanks

14:32 mrSpec: lazy1: yes, it /home/mrspec/project/lib/jung

14:32 ninjudd: or symlinking classes within your repo would work too

14:32 lazy1: mrSpec: So this is the problem, however I don't know what caused it

14:32 yayitswei: even better

14:32 mrSpec: lazy1: maybe I should import something else?

14:33 lazy1: mrSpec: Don't know anything about jung

14:33 mrSpec: lazy1: ok, I'll try find some more informations. Thanks btw!

14:35 lazy1: mrSpec: No worries

14:35 mrSpec: it is strange, cause the same import works for me in NetBeans

14:35 but I've moved project to emacs :/

14:35 and used lein

14:37 lazy1: mrSpec: From the command line, try "java -Djava.ext.dirs=lib clojure.main" and then import

14:41 mrSpec: lazy1: (import 'edu.uci.ics.jung.graph.SparseMultigraph) ? Not found :/

14:47 gcv: A question for anyone familiar with the Clojure compiler: why are protocol fully-qualified names converted to use underscores instead of dashes, whereas types and record names are not?

14:50 chouser: I don't know. My guess is that it's an oversight.

14:50 lazy1: mrSpec: According to the docs, SparseMultigraph is a generic, probably need some clojure import magic I don't know

14:51 chouser: generics don't require anything unusual in Clojure.

14:51 using them doesn't, I mean.

14:51 lazy1: chouser: You know way more than me on the subject

14:52 chouser: if (import 'foo.Bar) says ClassNotFound, then foo.Bar must not be on the classpath clojure is using.

14:52 gcv: chouser: The relevant code is in core_deftype.clj: emit-deftype*, emit-defrecord, and emit-protocol, right? I want to change it to see if it makes a bizarre classloading problem go away.

14:52 chouser: the possible causes of this are many and tiring.

14:57 gcv: yeah, I think that's right.

14:58 looks like the relevent parts of defprotocol may have been taken from gen-interface code which is rather older and more fully tested "in the wild"

15:01 octe: i'm using swank/slime to develop a program, and i'm passing a function as a callback to a function and storing it

15:01 re-evaluating the passed function in slime leads to a new definition of the function, but the stored callback still refers to the old one

15:01 is there some way to lazily call it?

15:01 not sure if'm explaining very good :)

15:02 chouser: octe: you could try passing and storing the var instead

15:02 (set-callback #'foo) instead of (set-callback foo)

15:03 octe: the callback should be callable in exactly the same way as it was before

15:04 mrSpec: simpliest solution is the best, I copied manually all downloaded from jung's website libraries to ./lib and it works.

15:04 thanks!

15:05 octe: chouser, cool, thanks

15:31 lpetit: hello again

15:38 LauJensen: lpetit: helloo

15:38 lpetit: LauJensen: Hello!

15:39 I think I've understood what's the piece I missed the previous time, when Rich kept talking 'bout "push something, push something". He was referring to "pushThreadBinding", isn't it ?

15:41 chouser: lpetit: he posted a link right after you left: http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#l6631

15:42 lpetit: chouser: oh yes, thx

15:42 chouser: but bytecode generation is not (currently) in my skills

15:43 chouser: so there's a lot of implicit knowledge that's just fleeting inches over me when I'm talking with Rich right now :)

15:43 chouser: lpetit: it is that way always with me when talking to Rich, whether about bytecode or anything else. :-)

15:43 lpetit: chouser: :)

15:44 chouser: lpetit: but I think you're right. Compiler.pushNS() does a pushThreadBindings on *ns*

15:44 lpetit: chouser: so now for something a bit more involved. I want to ... what exactly do I want to ? :)

15:45 chouser: At first, when he talked about pushing, I thought he wanted me to move some lines of code from some init() function to some load() function

15:45 * lpetit blurs

15:46 raek: was there some neat way to make the repl print through pprint?

15:46 * lpetit blushes, not blurs

15:47 chouser: lpetit: I have to work hard to come up with weak guesses as to what various bits of byte-generating code do

15:48 lpetit: so I'm staring at that line rhickey pointed to

15:48 ataggart: chouser, et al.: I'm digging into the compiler to try and figure out why (bit-shift-left int int) will resolve to Numbers.shiftLeft(long, int), but (bit-shift-left byte int) will only resolve to Numbers.shiftLeft(Object, Object). Do you know of a reason Rich excluded such automatic widening conversion for bytes?

15:48 lpetit: chouser: and I'm starting at this sentence from him "you could also experiment with patching Compiler.compile()'s generated static load() method to push LOADER, RT.makeClassLoader() "

15:48 chouser: it looks like the body of some function. the static init of a class?

15:48 * lpetit and chouser feel like Sherlock Holmes

15:49 lpetit: chouser: I guess the first argument is the name of a class, the second the signature of a method.

15:49 chouser: clinitgen.invokeStatic(Type.getType(Compiler.class), Method.getMethod("void pushNS()"))

15:49 chouser: lpetit: so, you're already pushing a thread binding for *ns* -- perhaps you could also do that for LOADER and initialize it to a new loader created with RT.makeClassLoader()?

15:50 rhickey: chouser: yes, the static init of the init class for an AOT compiled file

15:50 lpetit: means invoke the static method of type Type.getType(Compiler.class) (that is of class Compiler) , and the method is pushNS()

15:50 rhickey: er, ns

15:50 lpetit: yes,

15:50 Now I'm trying to understand how to pass arguments

15:50 rhickey: chouser: right, push a binding for Compiler.LOADER

15:51 JVM bytecode is a basic stack machine

15:51 lpetit: I need to do something like pushTreadBindings(Compiler.LOADER, RT.makeClassLoader())

15:51 So I first push the arguments, then the method call ?

15:51 professor Rich ? ;-)

15:52 rhickey: lpetit: just parrot what is there. The compiler has a helper to do the pushNS, and just calls that. You could do something similar

15:52 push args, invokeStatic

15:52 amalloy: i found this emacs function to make C-a move to the beginning of text instead of beginning of line, but sometimes i want to move to the beginning of the line. is there a built-in function to move to the beginning of text, unless it's already there in which case go to beginning of line?

15:53 lpetit: rhickey: ok

15:54 Hmm, If I do a second separate call to pushNS, then I'll have to add a second pop, right ?

15:57 OMG ! All this java sugar with finally is just local gotos at bytecode level !

15:58 * lpetit hates java even more for that :-)

15:58 lpetit: while understanding that it is not java-related at all :)

15:58 kotarak: lpetit: well, everything boils down to that, I guess.

15:59 klang: amalloy: would Ctrl-up/down be acceptable?

15:59 cpfr: its all goto control flow at the bottom

15:59 lpetit: kotarak: hello ! Indeed, but still, it does something the first time you see it :)

15:59 it's like seing your idol in toilets

16:00 klang: amalloy: what is the function called?

16:00 amalloy: klang: beginning-of-line-text

16:00 klang: Ctrl-up/down move paragraphs. i don't mind binding it to whatever key, i'm just trying to find out if there's a function for the behavior i want or if i have to write it

16:01 kotarak: lpetit: sometimes it shines through: http://groups.google.com/group/clojure/browse_thread/thread/3c886a42aab88444#

16:02 lpetit: ;)

16:04 klang: amalloy: Don't mind me then. It seems that you have the functions you want, but not enough keys?

16:05 amalloy: i suppose that's true. i was hoping to bind them both to C-a so i could just hit it twice to override the default behavior

16:05 eg, the Home key in eclipse does that

16:06 klang: amalloy: you want cords?

16:06 amalloy: klang: i don't think so

16:06 klang: amalloy: key-chord.el --- map pairs of simultaneously pressed keys to commands

16:07 amalloy: i want to bind to C-a a function that does this (if (at beginning of text) (go to beginning of line) (go to beginning of text))

16:07 it sounds like there isn't one, so i'll just slap it together myself

16:08 klang: amalloy: You almost did, just then.

16:08 amalloy: haha

16:08 i know. just didn't want to duplicate code

16:09 klang: amalloy: well, you'll know how it works, when you are done. Inventing the wheel is fine.

16:09 amalloy: fair enough. thanks

16:09 klang: no help from me ..

16:10 amalloy: well, you confirmed that i am not doing myself a disservice by inventing the wheel

16:12 klang: amalloy: heh!

16:13 amalloy: klang: maybe you can still help - do you know where i can find source for the built-in functions like (bolp)?

16:17 klang: amalloy: M-x describe-function

16:17 amalloy: in bolp's case, it's a C function

16:19 amalloy: hm. that gets me a description from *Help*, but no lisp code that i can see, even for functions that are "compiled Lisp functions"

16:22 klang: amalloy: the source for blop is written in C .. I don't think you want to go that far, but you could if you wanted. The source is available.

16:22 amalloy: o

16:22 er

16:22 kotarak: msg LauJensen Hi! You remember the slight regression in performance of vlist against a vector?

16:22 woops

16:22 amalloy: i'm not actually looking for bolp; it was just an example

16:23 klang: well, the example still holds .. if it's an elisp function, there will be a link to the file where it is defined and _that_ will be easily available.

16:24 amalloy: i see. okay

16:25 lpetit: Why use with-loading-context in the definition of ns ?

16:25 klang: hold your horses .. something is different ..

16:25 lpetit: And why does with-loading-context push (.getClassLoader (.getClass ^Object loading#)) into clojure.lang.Compiler/LOADER ?

16:25 What if instead, in with-loading-context, I push RT.makeLoader() into Compiler.LOADER ? ;-)

16:25 klang: I guess you have to have emacs elisp source files installed for that to work (I don't on this machine, it seems)

16:26 lpetit: Do I then solve my problem, and open a can of worms elsewhere ?

16:26 klang: amalloy: it works for the functions where the .el file is available somewhere..

16:28 lpetit: Who wrote the first ns ?

16:32 chouser: hehe, when I also change with-loading-context, it works again !

16:32 Let's say Hourray 'til Rich says it's not supportable ! :-/

16:34 amalloy: klang: okay, *now* i need help with keybindings :)

16:35 http://gist.github.com/599774 - the function works if i call it with M-x, but i can't bind it to a key because it says Symbol's function definition is void"

16:36 oh haha, never mind. i typed the wrong name :P

16:37 klang: well, then the error message *does* make sense :-)

16:39 amalloy: and yes, it does work fine, and follows your pseudo code above!

16:40 amalloy: sure does! good ol' emacs. anyway it works like a dream now. you should try it, it's clearly better than the builtin :)

16:41 klang: I am trying it, I am trying it! .. it deviates from how my fingers work, though!

16:42 amalloy: haha

16:43 klang: mostly i found i want beginning-of-text to do editing, but beginning-of-line to make C-k more useful

16:45 klang: amalloy: well, that IS a compelling argument :-)

16:48 amalloy: Laters, because it's late in my neck of the woods. .. and look into some tab completion (hippie-expand) for emacs, you woun't regret it :-)

16:50 amalloy: thanks klang

16:50 klang: no problem

17:15 gfodor: hey all, I'm a little stumped here. I have a java static class that has a nested static interface, and I can't seem to reference the interface form closure. The static class, for example, is com.myorg.MyService and the interface is com.myorg.MyService.Iface (this is generated from thrift). when I reference com.myorg.MyService in the REPL it resolves, but com.myorg.MyService/Iface and com.myorg.MyService.Iface fail to resolve. I'm trying

17:15 extend this interface via gen-class

17:15 s/closure/clojure

17:15 chouser: com.myorg.MyService$Iface

17:16 gfodor: yes, thank you!

17:17 btw, JoC is *awesome*

17:19 chouser: ah, thanks. :-) Except we missed that detail? :-/

17:22 gfodor: probably not -- just using chapter 10 here as a guide

17:22 not in there I don't think, but probably elsewhere

17:23 chouser: hm, a couple examples like in chapter 5, but not explicitly called out anywhere it seems.

17:26 gfodor: welp, when in doubt, try every non-alphanumeric character :)

17:26 KirinDave: Hey folks, are there any discussions of patterns for deftype/reify use?

17:26 I find myself wanting something like inheritence, but I'm unsure how I should model it in cloure.

17:27 Err, clojure.

17:27 Specifically I'm writing a port of webmachine to clojure, and I'm looking at how Erlang did things.

17:28 It seems like inheritence would actually be a very good way to model a default webmachine resource, allowing for overrides.

17:29 Otherwise, I'm going to have to make like, what... a macro?

17:29 Or maybe do what erlang does literally and check if a namespace has methods

17:29 But I don't like that very much.

17:30 Is there a pattern for modeling a simple override (restricted 1-level inheritence) for deftype when they need it? Default implementations for definterface?

17:31 kotarak: KirinDave: you can have that with extend.

17:32 KirinDave: kotarak: Is that the right way tho?

17:32 kotarak: I think so.

17:32 KirinDave: If I want to, say, make complex syntax stuff on to.

17:32 Err, on top

17:32 Using all the macro-let

17:39 kotarak: I guess in order to make extend do that transparently, it'd have to do a merge of a default behavior map with a map or syntax-assisted thing defined by the user.

17:42 chouser: KirinDave: http://kotka.de/blog/2010/08/Static_vs_Dynamic.html

17:43 KirinDave: chouser: I confess even a smalltalk nerd like me is having a bit of a hard time fully grokking the intended use of these primitives.

17:43 chouser: :-)

17:43 KirinDave: chouser: Which reminds me

17:44 chouser: extend with merge is currently the cleanest and most-recommended way to mix "default" and "specific" functionality for a single type or record

17:44 KirinDave: He says it is "faster" to use the def* route as opposed ot extend

17:44 chouser: yes, slightly

17:44 KirinDave: Is that at the time of instantiation

17:44 or for every method call?

17:45 chouser: instantiation speed should be the same, I think. It's the method call that's different

17:45 KirinDave: Oh. Bummer

17:45 I mean, they're syntactically isomorphic, so no big deal.

17:45 chouser: using a protocol method on a type that defined that method "inline" will be as fast as a java method call -- that is, as fast as possible in the JVM world.

17:46 KirinDave: I suppose if I am writing something to try and handle lots of data at high speed, it'd be preferrable to use that method

17:46 octe: what's the syntax for type hinting that it's a string array?

17:46 KirinDave: With a syntax transformer

17:46 chouser: using a protocol method on a type that it was extended to is still very fast (faster than a multimethod, for example) but not quite raw java method-call speed.

17:47 bbl

17:49 kotarak: octe: ^{:tag "[Ljava.lang.String;"} string-array

17:49 octe: ^"[L....;" string array might also work.

17:50 octe: ^"[Ljava.lang.String;" tokens

17:50 worked

18:02 bhenry: ,(seq? ())

18:02 clojurebot: true

18:03 bhenry: ,(seq ())

18:03 clojurebot: nil

18:04 chouser: what if, by default, multiple forms on the same line of the repl were eval'ed as if inside (->> ) ?

18:11 lpetit: chouser: Yata ! I did it !

18:14 octe: ,(list? "asd")

18:14 clojurebot: false

18:14 octe: ,(list? ["a" "b"])

18:14 clojurebot: false

18:14 octe: ,(vector? ["a" "b"])

18:14 clojurebot: true

18:19 amalloy: chouser: seems like an idea worth toying with, anyway. especially if you're the one implementing it

18:20 though it has the weird implication that pasting something into the REPL from a source file won't necessarily do the same thing

18:23 i can't think of an example of *good* code that would have a problem, but imagine (def x 10) (def y 9); auto-coercing that into a ->> would mess things up beyond recognition

18:26 rplevy: does Compojure not accept dots in route parameters?

18:26 as the arguments I mean

19:36 re my earlier question, just in case anyone wanted to know the answer, you can override the default regexp that partitions a section of the URI. The default is on line 93 of clout/core.

19:51 charliekilo: I searched and could not find where clojure.contrib.properties, esp. with-system-properties, want in 1.3.0-alpha1. Any hints are appreciated

19:51 correction: ... went ...

20:03 solussd: is it not possible to dismiss a MPMoviePlayerViewController (presented modally) if it was presented inside of a modally presented view controller? It seems to just ignore my calls to dismiss it.

20:03 wrong channel, sorry

20:09 tomoj: so I'm writing a parser for this simple binary format. you read a byte, that gives you the packet type. then you can look up based on the packet type a sequence of types to read from a DataInputStream. this is what I've got so far: https://gist.github.com/e0ed6482a332826e4dcd

20:10 for each defpacket which defines a packet type, I alter-var-root to add a parsing fn to a map of packet type ids -> parsing fns

20:10 what I'd really like is to just expand to a case statement on the packet type id

20:11 but that means I need to wait until all defpackets are done and gather them, then expand

20:11 which means they all have to be in one macro call, in one file

20:11 any ideas?

20:14 amalloy: tomoj: you could require all the defpackets to be given at the same time: (defmacro defpackets [& specs]...)?

20:14 tomoj: right

20:14 but then they all have to be in the same file

20:14 I'm wondering if there's a decent way to do it where they don't have to be

20:15 actually, I will just require the user to declare which packetdefs they are using when constructing their parse fn

20:15 nevermind

20:45 chouser: amalloy: yeah, good point

20:49 I guess if I had paredit at the repl I wouldn't find this attractive at all?

20:50 amalloy: chouser: caught me on my way out, actually. i'll be around in a couple hours if you still want to bounce ideas off me

20:57 laurus: How does one print the header of a data-file in Incanter?

20:58 Oh, duh

20:58 (col-names <datasetname>)

20:58 :P

21:03 bhenry: ,(seq "")

21:04 clojurebot: nil

21:04 bhenry: laurus, sorry not for you. just looking at something.

23:39 can anyone get me started with ring.middleware.session/wrap-session

23:41 i have (wrap-session {:cookie-name "qa-session"} handler), but i don't know how to manipulate and read the session data

23:43 scottj: I don't use ring directly but it adds a :session key to my request for me

23:44 bhenry: (:session req) returns an empty map, but i can't figure out how to set that map with my values for the session.

23:45 ideally i'd want to manipulate data in the handler, then set the session in the response. for future access to the session data in other handlers.

23:46 scottj: I think your handler would return a response with something in the session key

23:46 bhenry: hmm. i tried that. i'll keep digging.

23:48 scottj: they're functional. sandbar adds banging functions

23:50 tomoj: haha, my output is #<NullPointerException java.lang.NullPointerException>

23:50 and a usage message

23:50 bhenry: i saw session-put! in an example that :uses entire name-spaces. i think i actually have sandbar in my class path right now, so i'll play with it

23:50 tomoj: thanks, really helpful hadoop!

23:57 technomancy: sneak preview: http://p.hagelb.org/lein-mock.html

Logging service provided by n01se.net