#clojure log - Feb 02 2009

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

0:50 ricree: Hi. I'm new to clojure, and I'm having a tough time figuring out how to get it to work with java libraries. I've been trying to work through this post (http://briancarper.net/2008/10/31/qt4-in-lisp/), but when I try the import commands I keep getting ClassNotFoundException. Can anyone point me to a good resource for figuring out what I'm doing wrong here?

0:53 cp2: ricree are you using -cp when you invoke java or are you using add-classpath in the code

0:54 ricree: -cp

0:55 although I tried it in slime when I added the .jar files to my .clojure directory, and I get similar results

0:55 when I print out the classpath with (println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader)))) , it shows the jar files

0:56 cp2: i had a similar problem a few days ago, and it was because i was using both -cp and -jar

0:56 although im not entirely sure

0:57 durka42: when i had this problem i was running an old jvm, and the jars that wouldn't import were marked newer

0:58 ricree: I suppose that part of the problem is that I'm new to both clojure and java. I'm honestly having trouble sometimes keeping straight where exactly these things are supposed to be getting loaded from at times

1:00 durka42: ricree: join the club. classpaths are the bane of java programming

1:02 xitam: is there any way to use a sorted-map with a custom comparator? or some way to make a comparable object out of a struct?

1:04 what i'm trying to do is implement a-star search as sort of a beginner project with clojure, and i guess typically the "open set" of search nodes is implemented with a priority queue

2:44 cads: !seen rhickey_

2:45 hrm

2:46 replaca: cads: it's three in the morning where he is

2:46 cads: insn't it?

2:46 cads: hehe

2:46 I need to hang out here at american hours then

2:49 I read somewhere where he writes, of the question "should I learn clojure through SICP?", that SICP is great for learning programming but that it won't really help with the task of learning the clojure toolset (I'm paraphrasing and might be wrong).

2:49 And I was wondering what path would be recommended for someone learning clojure as a first language.

2:49 replaca: cads: yeah, that's about right

2:50 cads: what do you know already?

2:50 no programming yet?

2:50 cads: I know enough programming to make my way through the tutorials I can find

2:51 replaca: what languages do you know?

2:51 cads: but I have a friend I'd like to recommend lisp to

2:51 I know ruby and haskell

2:51 replaca: For you, I'd do Stuart Holloway's book

2:52 cads: the one in beta?

2:52 replaca: you might want to do SICP and "On Lisp" for context

2:52 yeah

2:52 for your friend, I would think that Clojure would be a tough place to start

2:53 just cause I don't think the clojure-specific starter doc is there yet

2:53 and there's the extraneous confusion of a new language

2:53 cads: I'm tempted to recommend stuff like SICP and graham's "On Lisp" but that was frustrating to me, when my goal was to play with clojure

2:53 BigTom: cads: stu halloway's book is pretty good

2:54 he has just added a chapter on functional programming

2:54 replaca: yeah, like rhickey said, they're not directly related

2:54 cads: what helped was the getting started guide, and rich's talk on clojure for lisp programmers

2:54 BigTom: I am working through SICP (very slowly!)

2:54 cads: which I wanted to complement him on

2:54 replaca: cads: that's what I used too, but I knew lisp & java coming in

2:55 BigTom: I knew java and was familiar with scheme

2:55 cads: I know lisp more from theory papers than playing with it, and it's great that clojure in many ways feels like a purer lisp than CL, while being more practical than scheme

2:56 replaca: you could say that (though others would flame you) :-)

2:56 BigTom: I love it :-) I finally get a Lisp that I can do at work

2:57 replaca: rhickey has made some great design decisions

2:57 cads: replaca: most CLers are all about CL, rather than the abstract ideal of lisp, I've found

2:57 replaca: CL is still fighting wars from the 80s so it feels clunky now, IMO

2:58 well they like the standard and the library

2:58 I can't blame them entirely

2:58 cads: but it's an old library and standard

2:58 replaca: after all, I'm the guy you implemented the CL format func for Clojure :-)

2:59 yeah, that's part of the problem

2:59 *you => who

3:00 cads: I have a hard time feeling like I could axiomatize CL like I've seen done in purer settings in papers

3:01 and at the same time I have a hard time seeing how something that could be grasped mathematically by a single person would also be a pragmatic language to do programming in

3:01 replaca: yup, though Clojure may have some similar problems (cause of the Java interop)

3:01 in any case, gotta crash here in California!

3:01 cads: take care replaca

3:01 replaca: goodnight all!

3:32 Lau_of_DK: Top of the morning gents

3:32 Raynes: Good morning.

3:41 cgrand: Hello

3:55 Lau_of_DK: cgrand: Did you notice my new project on Github?

3:57 cgrand: not yet :-)

3:58 Lau_of_DK: I ripped your partition-by for it :)

3:58 Along with shell-out

4:05 cgrand: you don't want to depend on contrib?

4:06 Lau_of_DK: No, not really

4:08 cgrand: Can't you load git.ui from the classpath? (Just asking, I don't know Jambi)

4:09 Lau_of_DK: I was fiddling with that last night, but maybe I was too tired

4:09 I'm looking into just passing the content of the file to the UI loader

4:11 cgrand: What you call a port of Jambi to clojure is the end of engine.clj + slot.clj. Right?

4:11 Lau_of_DK: Yea, and as Chousuke reminded me, its not a port, its bindings. I need to update the README

4:12 cgrand: I like the tone of it (the README)

4:13 Lau_of_DK: Im glad you like it - because its informal ?

4:14 Or because I actually took the time to write quality instructions for windows users?

4:17 cgrand: its informality... which instructions for windows users?

4:20 be kind, I'm still uncaffeinated

4:21 Chousuke: is a dependency of contrib really that bat?

4:21 bad*

4:21 kind of defeats the point of contrib if people don't use it :/

4:22 having it as a separate dependency relieves you from the burden of maintaining the code, too :)

4:23 Raynes: Kind of like saying you don't want to depend on a languages standard library :|

4:23 language's*

4:25 Chousuke: well, clojure kind of has two standard libraries.

4:25 Lau_of_DK: Chousuke: To me Contrib is big, its not optimal in all regards (like, for obvious reasons I dont want to associate with contrib.sql), and I just dont want to fiddle with more namespaces, I dislike that system, so its easier just to cut/paste 100 lines and mention where I took them from

4:25 cgrand: The instructions at the very bottom of the readme

4:26 Chousuke: Lau_of_DK: if you compile your code though you won't get anything other than the parts you used from contrib :/

4:27 Lau_of_DK: I know - I said 'associate' :)

4:27 Chousuke: and frankly, caring about contrib.sql being there is just silly :)

4:28 Lau_of_DK: I think its a big dependency to force on your users

4:28 I think I'll just make standard loot.clj with the snippits I need

4:29 Chousuke: it's not that big, is it. 632K with *everything* compiled in. :P

4:29 Lau_of_DK: Thats pretty huge compared to my entire project being 28k

4:29 Chousuke: it

4:29 it

4:29 gah

4:29 it's just a compile-time dependecy.

4:30 +n

4:30 though hm

4:30 never mind :P

4:30 thought of something that might be a problem, but isn't.

4:31 Lau_of_DK: haha

4:31 I think the whole point of IRC is that you can have what we call a "reflection" without nessarcily sharing it, in case its useless :)

4:34 cgrand: To me Jambi appears to be a bigger dependency than contrib...

4:34 Lau_of_DK: It is

5:39 Chousuke: ooh, when did the clojure site get the "related functions" thingy? very nice.

5:40 * Chousuke hasn't visited the site in a while :p

5:49 leafw: is there any way to call "this"? In a proxy, or when creating a function to pass as a Runnable to a new Thread, I have no means of calling isInterrupted() from within the body of the thread, unless I do some hoops such as declaring first a "self" ref to nil and then altering it to contain the thread, and in the fn that works as Runnable, call (.isInterrupted @self)

5:49 example here: http://github.com/acardona/xmms2-clj/blob/c4745f0e19c75e67a08ae6fb7c1a8500f0663d93/xmms2.clj#L95

5:50 even though the dereferencing is not done in the context of the dosync transaction, it looks like and it is an ugly workaround.

5:54 achim_p: leafw: can't you use let?

5:54 (let [runnable (fn [] (println "blah"))

5:54 thread (Thread. runnable)]

5:54 ...)

5:54 leafw: achim_p: I tried, but it failed with null pointer

5:55 no, the problem is that isInterrupted is as a method of Thread, not interface Runnable. I would have to call (.isInterrupted Thread/currentThread)

5:55 which is not tragic, but looks silly

5:56 it would certanly simplify things ...

5:56 there's no need for a transaction in there.

5:56 Chousuke: the first argument to a proxy method is "this" isn't it? or was it automatically bound...

5:56 leafw: sorry, this is not a proxy. So in a proxy it's possible?

5:57 Chousuke: I think the first argument of any function in a proxy is the first argument of that function, not "this"

5:57 Chousuke: Each method fn takes an additional implicit

5:57 first arg, which is bound to 'this

5:57 leafw: oh really!

5:57 that is good news.

5:57 thanks.

5:58 Chousuke: that's in a proxy; with fns I don't think there's a way to refer to the thread you run the fn in, other than through Thread/currentThread

5:58 leafw: that's ok

5:58 I'll use that.

5:58 with the let [runnable suggestion.

5:58 achim_p: leafw: hmm, i don't really see why you can't instantiate the thread in a let form and call .isInserrupted on the let-bound symbol you assign the thread to ...

5:58 ayrnieu: (.start (Thread. (proxy [Runnable] [] (run [] (println (str "this: " this))))))

5:58 this: clojure.proxy.java.lang.Object$Runnable@d22889

5:59 leafw: as always, clojure offers 3 ways to do something

5:59 thanks ayrnieu

5:59 Chousuke: probably more :)

5:59 the problem is finding the best.

6:00 leafw: I agree.

6:01 Chousuke: I think a closure will do as well, (let [t (Thread. #(do (something) (something-with t)))] (.start t))

6:02 ayrnieu: ,(let [a #(list a 1)] (a))

6:02 clojurebot: java.lang.Exception: Unable to resolve symbol: a in this context

6:03 Chousuke: hm :/

6:03 achim_p: leafw: forget what i said, it's too early in the morning :) let doesn't work of course - mutual references

6:03 leafw: achim_p: no problem. I had tried that.

6:04 proxy is overkill. The runnable path is nice.

6:16 much cleaner now. Thanks guys.

6:21 lisppaste8: ayrnieu pasted "defmethod takes a MultiFn as its first argument (as opposed to: the name of one)" at http://paste.lisp.org/display/74717

7:44 turbo24prg: ayrnieu: that's tricky, but it makes sense, of course

7:49 ayrnieu: it's useful.

7:49 Compare http://gist.github.com/56893 to http://gist.github.com/54950

8:15 Chousuke: ayrnieu: why don't you use autogensyms in the actor macro? :/

8:17 ayrnieu: in the second one? I didn't know about them.

8:17 Chousuke: you do now though? :)

8:18 ayrnieu: yeah, I use them in the ! !! arecur macros in the first one.

9:40 AWizzArd: rhickey: did you already decide if lazy-cat is an issue, with having the empty sequence being nil?

9:47 rhickey: AWizzArd: I'm working on laziness issues in a branch, and not going to spend any time on current laziness issues that will go away if the branch work becomes core

9:48 Chouser: are the fully-lazy branch and streams branch completely orthogonal?

9:51 AWizzArd: rhickey: makes sense

9:53 rhickey: Chouser: yes, basically I am still on the fence about streams. finding them, even when made safe as I have done, ugly,

9:53 Chouser: rhickey: really, that's interesting.

9:54 rhickey: but integrating streams means dealing with the ISeq/more issue, which opens the door to fully lazy sequences, which are very beautiful and Clojure-like

9:55 so in the lazy branch I am fiddling with ISeq, with much success, in terms of backwards compatibility and full laziness, having made Clojure itself work with fully-lazy filter/map/concat replacements

9:56 I was working on performance over the weekend, since full laziness requires another indirection in inner loops

9:56 ricree: can anyone point me in the right direction for using java libraries besides the core java libs? I've been trying to play around with some examples in jambi and java-gnome, but I can't seem to get at the library classes. As far as I can tell, the .jar files are in the classpath

9:57 rhickey: but it looks like making (rest x) == (seq (more x)) is a good recipe for backwards compatibility

9:59 ayrnieu: ricree, what are you trying to do that is failing?

9:59 rhickey: Chouser: streams are ugly since many of them will need state

9:59 Chouser: their only attribute is performance at this point

10:00 Chouser: rhickey: yep, the contention there seems pretty inherent. You've got it bottled up pretty tight, but it still feels like you have to think about the statefulness inside.

10:01 rhickey: Chouser: the lazy branch has a major enhancement relating to clearing closed-over objects on a tail call of a one-time function, the key to avoiding accidentally hanging onto head when recursing

10:02 I've been clearing locals for a while, but the closed-overs were a tricky problem the user can't solve

10:03 Chouser: very cool. did that require more analysis of the code to see what could be cleared?

10:04 rhickey: Chouser: I'm not yet sure how I'll expose it, if at all, but essentially you can adorn a fn* as :once-only, meaning it will only be run once, as is the case in delay and the new lazy-seq - the compiler picks up this once attribute and generates closed-over clearing code at the same point as local-clearing code

10:05 Chouser: ah.

10:05 rhickey: I need the attribute since clearing it depends on its being invoked only once, true for any call-and-cache mechanisms

10:06 Chouser: unexposed would mean only a few builtin cache mechanisms could use it?

10:06 rhickey: Chouser: right, at least initially

10:07 ricree: ayrnieu: well, trying to import anything is giving me trouble. For example, I've been trying to go through the example at http://briancarper.net/2008/10/31/qt4-in-lisp/ , and I can't get the initial import statement to work right. It gives me a NoClassDefFoundError

10:07 rhickey: delay being one of them, and the most likely to be used other than lazy-seq, which is very special at this point, giving generated fns new superclasses (i.e. other then AFn/RestFn)

10:08 AWizzArd: hmm

10:08 Chouser: ricree: try pasting your exact import line and java command-line, maybe someone can spot the error.

10:09 ricree: (ns clojure-qt4-demo

10:09 (:import (com.trolltech.qt.gui QApplication QPushButton QFont QFont$Weight)

10:09 (com.trolltech.qt.core QCoreApplication))

10:09 this is taken straight from the example on the site I linked

10:11 ayrnieu: That should work. You can try typing in just: com.trolltech.qt.gui.QApplication

10:12 or you could look at (System/getProperty "java.class.path") to see if it really points to these jars.

10:12 Chousuke: ricree: you're not just adding the directory containing the jars to the CP, are you?

10:13 ricree: because it doesn't work that way.

10:13 ricree: The jars seem to be included when I print out the classpath

10:13 AWizzArd: Oh btw, can Clojures trampolines be used to provide stack-safety for all kinds of mutual recursive calls?

10:14 I was not sure if they can be applied in any situation, or if there exist cases where they can't protect from stack overflows.

10:14 Chouser: AWizzArd: the function you give to 'trampoline' returns a function instead of making a tail call

10:14 AWizzArd: Chouser: yes, I understand that

10:15 Chouser: AWizzArd: so you have to write the function specifically to be used by 'trampoline'

10:15 AWizzArd: right

10:15 But maybe there exist some really crazy cases of tail calls where this can't be done.

10:15 gnuvince: thickey_: I showed your site to the webdesigner I work with; he likes the way you show the websites :)

10:15 AWizzArd: I don't think so, but in a discussion with a mathematician (and known c.l.l troll) I was not so sure anymore.

10:15 ricree: Chousuke: I did, but I'm currently running this from slime, and my understanding was that it would load whatever .jars were in my ~/.clojure directory. That seems to be the case when I print out the classpath. Am I missing something?

10:16 Chouser: well, my point is that it has to be a well understood discrete system.

10:16 Chousuke: hmm :/

10:16 ricree: maybe one of the classes is misnamed in the article?

10:16 Chouser: AWizzArd: if you *know* your function is being called by 'trampoline', then sure -- any tail call you would make you simply replace with returning a closure.

10:17 Chousuke: ricree: you sure you have the correct JARs in the first place? :)

10:18 AWizzArd: In fact this other guy could not deliver an example so far, so I come to think that all cases can be mapped to trampolines.

10:20 ricree: Chousuke: I think so, but I'm not 100% sure. Just putting qtjambi-4.3.jar and qtjambi-linux32-gcc-4.4.3_01.jar into the classpath should be sufficient, right?

10:20 Chousuke: I guess :/

10:21 ricree: try running java manually?

10:21 ie. manually specify the java classpath and start a clojure repl.

10:22 ricree: I have, but I'll go ahead and give it another go to make sure

10:22 rhickey: AWizzArd: the argument there was that it wasn't a universal TCO if it had to be a discrete system (invoke specially by trampoline), which is true, trampoline is not universal TCO, just a la carte TCO for subsystems

10:24 AWizzArd: oki, I see

10:24 rhickey: AWizzArd: so, not a limitation of trampolines as an implementation technique for TCO (as was pointed out, it is quite commonly used by Scheme implementations), just that trampoline, as a library fn, is not universal TCO, and I never said it was

10:26 AWizzArd: ok

10:26 thx

10:28 rhickey: AWizzArd: remember, don't feed trolls :)

10:28 ricree: Chousuke: I tried the command "java -cp qt-jambi-4.4.3_01.jar:qtjambi-linux32-gcc-4.4.3_01.jar:clojure.jar:jline-0.9.94.jar jline.ConsoleRunner" from the directory with the jar files. I get the following error when I tried to just type out one of the classes "java.lang.ClassNotFoundException: com.trolltech.qt.gui.QApplication (NO_SOURCE_FILE:0)". I was able to get to classes like javax.swing.JFrame, so it looks like it's just having trouble

10:29 Chousuke: hmm

10:30 ricree: that's weird, it should exist :/

10:34 ricree: when I was trying to figure this out last night, someone suggested that it might be an older version of the java runtime. I checked, and everything is up to date from the Ubuntu repositories. Think it would be worth it to try installing things manually to make sure it is as up to date as possible?

10:34 gnuvince: recur sends you to the nearest recursion point, there's no way to arbitrarily choose one, right?

10:35 ricree: although I haven't been able to get it to work with any other jar files, so that doens't seem likely to be the problem

10:35 AWizzArd: What I find nice is that I get private mails of CLers who got interested in Clojure, asking questions and such

10:37 gnuvince: right

10:37 ricree: ah well, I have to get ready for class. I'll try to figure this all out when I get done today. Thanks for the help, it's appreciated

10:38 gnuvince: AWizzArd: thanks

10:38 Cark: awizzard : there's again an argument about clojure on c.l.l ?

10:39 AWizzArd: Cark: well, every few days some known trolls try to convince Lispers that Lisp sucks. I show them some Clojure code and usually outperform their examples in Ruby or such. So, enough talk is going on in c.l.l

10:40 Cark: may i ask who you are on cll ?

10:40 AWizzArd: /who AWizzArd

10:40 Cark: i've been i follow this newsgroup for a couple years =)

10:41 ahh right

10:41 they've been pretty harch to you

10:42 Chousuke: what does c.l.l stand for? :P

10:42 AWizzArd: comp.lang.lisp

10:42 cooldude127: mhm

10:42 ayrnieu: http://groups.google.com/group/comp.lang.lisp is one way to get there.

10:42 Chousuke: you know, I realised that about half a second after I asked.

10:42 cooldude127: lol

10:42 AWizzArd: ;-)

10:44 cooldude127: b-trees suck

10:46 MarkVolkmann: I need to pass a string to a macro. I have the string in a variable created with def. How can I force the symbol created by def to be evaluated to its string value when I pass it to the macro?

10:46 Chouser: MarkVolkmann: you want to use the value of that def as it stands at compile time?

10:46 Cark: (defmacro bleh [var-name] `(println ~var-name))

10:47 MarkVolkmann: Yes

10:47 Cark: oh

10:47 so scratch that

10:47 MarkVolkmann: It's really a constant string in my usage.

10:47 Chouser: MarkVolkmann: you're willing to assume that the thing passed in to the macro is always the name of a Var?

10:47 MarkVolkmann: It's a URL path being passed the GET macro in Compojure.

10:48 cooldude127: MarkVolkmann: unless the macro already evaluates what you pass to it, you can'

10:48 t force it to

10:48 MarkVolkmann: I can't modify the macro.

10:48 Chouser: oh

10:48 MarkVolkmann: The macro wants a string.

10:48 ayrnieu: `(eval (annoying-macro ~myvar))

10:49 Chouser: hm, do you have a link to the macro?

10:49 ayrnieu: it's OK to use eval if you resent it!

10:49 Chouser: heh

10:50 Cark: (defmacro bleh [var-name] (let [a# var-name] `(println ~a#)))

10:50 ?

10:51 MarkVolkmann: Remember though that I can't change the macro since it's supplied by Compojure.

10:51 Cark: that's not right anyways

10:52 MarkVolkmann: Are suggesting that I should override the GET macro?

10:52 Chouser: MarkVolkmann: do you have a link to the specific macro you're trying to use?

10:53 MarkVolkmann: It's defined in compojure/http/routes.clj. I'll see if I can find a URL that provides the source.

10:53 http://github.com/weavejester/compojure/blob/87d9d6591bb5649e9ac99733eddfff992b33c7b4/src/compojure/http/routes.clj

10:54 Chouser: it's the GET macro?

10:54 MarkVolkmann: The parameter in question is "path".

10:54 Cark: i would wrap the macro in a function ... (defn call-the-macro [var] (the-macro var))

10:56 then you can either call (call-the-macro "coucou") or (call-the-macro *coucou*)

10:58 Chouser: Cark: I don't think that'll work.

10:58 lisppaste8: rhickey pasted "fully-lazy sequences vs. streams" at http://paste.lisp.org/display/74721

10:58 Chouser: here's a simplified example: (defmacro ick [p] (let [x (str "<" p ">")] x))

10:58 Cark: didn't check the macro itself

10:58 Chouser: I can call: (ick "hi") and get "<hi>"

10:58 rhickey: fully-lazy sequences vs. streams - which would you rather write?

10:59 Chouser: but if I call (ick myvar) I get "<myvar>" rather than the contents of myvar

10:59 Cark: right

11:01 rhickey : the lazy-seq is easier on the eye

11:01 ayrnieu: blech: http://gist.github.com/56945 - actors, 'non-blocking' I/O, and an echo-server rough with debugging hooks. But it works until a client disconnects :-) I think I can do something with this.

11:04 rhickey: suggestions for alternatives to 'more' still welcome, you can look at that paste for typical usage. I had also considered 'etc'

11:05 Chouser: 'more' is relatively common as a local name following &

11:05 rhickey: Chouser: yeah, etc too :(

11:06 Chouser: anyway, the lazy-seq is much easier for me to think about. Perhaps that would change if I grew accustomed to looking at stream code.

11:07 for the lazy-seq version, I feel like I'm keeping track of two objects: the lazy-seq itself and the cons

11:07 rhickey: Chouser: actually map is one of the more straightforward stream code, being stateless

11:07 ayrnieu: MarkVolkmann - see clojure.contrib.apply-macro

11:07 rhickey: Chouser: lazy-seq might not be the best name, it's more of a lazy-seqable, or lazy-coll

11:08 ayrnieu: (let [hum "hi"] (apply-macro ick [hum])) => "<hi>"

11:08 oh, that just uses eval. Nevermind.

11:08 Chousuke: ayrnieu: how's iterator-seq! different from iterator-seq?

11:08 Chouser: for the stream version, there's the coll, the iter, the stream, and the eos.

11:08 ayrnieu: Chousuke - the .remove is important.

11:09 Chousuke: hmm

11:09 oh, and in conds, I think :else is more idiomatic than "true"

11:09 thickey_: gnuvince: thanks =)

11:09 Chouser: the 'if' packs a surprising amount of mental complexity into one line.

11:11 ayrnieu: :else looks nice, thanks.

11:18 Chouser: MarkVolkmann: it looks to me like apply-macro's about as good as you're going to get.

11:19 MarkVolkmann: but you might take it up with James Reeves, and see if he'd be willing to provide a less restrictive API.

11:19 MarkVolkmann: Thanks. Maybe I'll suggest to James Reeves that ... yeah, what you said.

11:20 Chouser: I think that if compile-ruote's call to compile-path-matcher were inside the syntax-quote instead of outside, you'd be able to use names that resolve to string instead of only string literals.

11:21 presumably the reason it is this way instead is for performance.

11:22 but that could be obtained by caching at runtime instead, I would think. There may be other solutions as well.

11:54 WizardofWestmarc: that was strange, got a "you are banned from the channel" message first time I tried to connect to the room

11:55 danlarkin: odd

12:01 rhickey: cycle has a nice def in fully-lazy land:

12:01 (defn cycle

12:01 "Returns a lazy (infinite!) sequence of repetitions of the items in coll."

12:01 [coll] (lazy-seq (seq (concat coll (cycle coll)))))

12:01 AWizzArd: hmm, is concat lazy?

12:02 rhickey: AWizzArd: this is in the fully-lazy branch

12:02 AWizzArd: yeah nice

12:03 Clojure gives people great training in thinking lazy

12:03 I got some private mails from long-time lispers who asked me how my code worked.. they wonedered because lazyness what not in their minds.

12:03 rhickey: AWizzArd: Clojure is only a tiny bit lazy, compared to Haskell

12:05 AWizzArd: it's nice though

12:05 full lazyness could perhaps sometimes result in strange behaviour, regarding memory at runtime.

12:06 ayrnieu: ,(first (concat (repeat 1) (repeat 2)))

12:06 clojurebot: 1

12:07 Chousuke: hmm.

12:08 ayrnieu: wizard, mibbit.com has been used for spamming.

12:10 WizardofWestmarc: ayrnieu: ah ha

12:14 may have to install an irc client again then.

12:18 cgrand: rhickey: can't cycle be similarly defined in current Clojure with lazy-cat?

12:23 clojurebot: svn rev 1243; [lazy] interim checkin

12:23 svn rev 1244; [lazy] moving off of lazy-cons - remove, takes, drops

12:26 rhickey: cgrand: probably, but this has no macro-fu

12:27 e.g. maybe lazy-cat can go away when all sequence fns are fully lazy

12:28 * rhickey is removing all lazy-cons calls in core.clj

12:28 kotarak: Huh? Big things going on?

12:29 gnuvince: what replaces it? Just cons?

12:29 AWizzArd: Hi K�te

12:29 rhickey: kotarak: this in the lazy branch only for now

12:29 Chouser: I think rhickey enjoys breaking ClojureScript even more than I enjoy breaking everyone else's code.

12:29 AWizzArd: ;-)

12:39 cgrand: rhickey: ok it's nice but I don't understand the seq in (lazy-seq (seq (concat ...)))

12:41 rhickey: cgrand: lazy-seq may not be the best name, what is does is define a logical collection in terms of the seq returned by the body, since concat (and all the sequence fns) now returns a logical collection (e.g. not a seq necessarily) you need to call seq on it

12:42 user=> (concat [] [] [])

12:42 ()

12:42 user=> (seq (concat [] [] []))

12:42 nil

12:43 AWizzArd: rhickey: (def x (concat [] [] [])) ==> will concat end immediately without even looking at the first arg?

12:43 rhickey: basically the body of lazy-seq must always yield a seq

12:43 Chouser: without the seq, cycle would return an infinite seq of empty things?

12:43 could

12:44 replaca: Q: from a method in a :gen-class, how do I call a method in the superclass (skipping my own)? I.e., I have a method .write in my class, but I want to call (.write (super this)) instead of (.write this).

12:45 LordOfTheNoobs: Would it be rude of lazy-seq to wrap its body in a implicit seq?

12:45 Chouser: replaca: see :exposes-methods in the gen-class docstring

12:45 ayrnieu: clojure.core/proxy-call-with-super proxy-super supers

12:45 replaca: Chouser: I don't think that's what I want. I have a write method in my class already.

12:45 rhickey: Chouser: , no, you'll get ClassCast exception since the return value of concat is not an ISeq

12:46 replaca: ayrnieu: I'm not using proxy, but (ns (:gen-class))

12:46 Chouser: ayrnieu: that's for proxy, not gen-class

12:46 rhickey: all the sequence fns return Seqables, not ISeqs

12:47 Chouser: replaca: yes, but if you want to get at the super-classes write method, you can use :exposes-methods to get a new name for it, so you can call it.

12:47 replaca: Chouser: ahh, ok, let me read doc :-)

12:49 rhickey: AWizzArd: yes, in fully-lazy land all sequence fns consume only when absolutely necessary:

12:49 user=> (def x (concat (map #(doto % prn) (range 10)) (map #(doto % prn) (range 10))))

12:49 #'user/x

12:49 user=> (first x)

12:49 0

12:49 0

12:49 replaca: Chouser: yup, that's it. Thanks! (This syntax feels a little unnatural)

12:50 Chouser: rhickey: oh, lazy-seq demands an ISeq, not just a Seqable?

12:52 replaca: Q: do call the exposed method as (.super-write this ...) or (super-write this ...)?

12:52 rhickey: Chouser: right, it creates a closure that implements seq for its return value, so body must yield ISeq, lazy-seq yields Seqable

12:53 Chouser: replaca: former, I believe.

12:53 rhickey: (lazy-seq body) -> x, (seq x) calls body

12:53 and caches

12:54 replaca: Chouser: thanks

12:55 Chouser: which brings me to LordOfTheNoobs' question -- why can't lazy-seq call seq on its arg? That's usually pretty cheap if you already have an ISeq, and would be quite handy if you don't.

12:56 technomancy: is anyone in the Seattle area going to SeaFunc this week?

12:57 rhickey: Chouser: it could do - I'm trying to do without that at present

12:57 technomancy: looks like an interesting meeting

12:59 hiredman: sounds interesting, but it might interfere with my social reclusing, and it is, well *downtown*

12:59 technomancy: hiredman: you're in Seattle?

13:00 hiredman: north seattle

13:00 technomancy: it's in the University district... not really downtown

13:00 but that doesn't mean the parking is decent

13:01 rhickey: LordOfTheNoobs: sorry, I missed your q about lazy-seq calling seq, it could, I'll look into the perf...

13:01 technomancy: heh: "The merits of the FP approach are highly debateable. Much more clear, is that people who debate these issues are interesting."

13:01 Kerris7: actions vs words

13:02 technomancy: hiredman: looks like it bounces around to different locations, but this one is at Ruby restaurant in the U district.

13:02 hiredman: technomancy: I am looking at the google streetview

13:07 technomancy: I work up in south shoreline (looking at the clojure google map)

13:10 rhickey: perf looks ok, now lazy-seq calls seq on body, so:

13:10 (defn cycle

13:10 "Returns a lazy (infinite!) sequence of repetitions of the items in coll."

13:10 [coll] (lazy-seq (concat coll (cycle coll))))

13:11 technomancy: hiredman: oh cool; I'm right on 155th.

13:11 but I work downtown

13:11 * cgrand rejoices

13:12 * danlarkin can't figure out how to place a pin on the clojure users map

13:12 hiredman: danlarkin: took me a while to

13:12 too

13:12 * duck1123 gives up hope of seeing a SE-Michigan Clojure users group

13:13 danlarkin: hiredman: care to share? :)

13:13 hiredman: you have to click "edit" on the side bar, and then there is a menu sort of thing across the top

13:13 with a pin icon

13:13 rhickey: only 9 lazy-cons calls left...

13:13 clojurebot: svn rev 1245; [lazy] moving off of lazy-cons, lazy-seq calls seq on body

13:14 danlarkin: hiredman: ohhh, I bet I have to bed logged in to google. that'd explain it

13:15 hiredman: huh

13:15 SeaFunc (a group of Seattle functional programmers formerly known as SeaLUG - Seattle Lisp Users Group)

13:15 technomancy: guess they wanted to avoid being called SLUG

13:16 kotarak: Guys from Denver, shouldn't take over the idea: DeFunc....

13:17 WizardofWestmarc: haha that'd be great

13:17 I'd have to go simply because of the awesome name

13:22 duck1123: hmm... I wonder if anyone likes MiFunc

13:22 Lau_of_DK: Hi all

13:23 ayrnieu: duck, do you mean clojure.lang.MultiFn ?

13:23 WizardofWestmarc: heya Lau

13:23 ayrnieu: oh, nevermind.

13:25 cooldude127: WOOHOO i can take a break from stupid java homework, my b-tree works

13:26 Lau_of_DK: woohoo :)

13:28 AWizzArd: Hi the Lau

13:29 ayrnieu: ,(let [mi (new clojure.lang.MultiFn (fn [a & _] a) :default)] (doto mi (defmethod :add [_ a b] (+ a b)) (defmethod :sub [_ a b] (- a b))) [(mi :add 2 3) (mi :sub 2 3)])

13:29 clojurebot: DENIED

13:36 WizardofWestmarc: here I thought it was just a net split

13:39 cooldude127: technomancy: yay, imenu is working with clojure-mode

13:42 technomancy: cooldude127: great!

13:42 have you tried the installer?

13:43 cooldude127: technomancy: no, not yet, i'm afraid to mess with my setup

13:43 i'm using clojure-slime-config tho

13:44 technomancy: cooldude127: M-x clojure-install won't touch your current setup if you give it a test location when it asks you where to install

13:44 cooldude127: I ask just because I'd like to get it tested on more systems than my own

13:44 cooldude127: technomancy: yeah ok i can test

13:49 technomancy: can haz bugs

13:49 it tried to check everything out into ~/.emacs.d

13:50 technomancy: cooldude127: what location did you give it when prompted?

13:50 cooldude127: technomancy: ~/sr

13:50 c

13:50 ~/src

13:50 clojurebot: Excuse me?

13:50 technomancy: heh

13:50 cooldude127: clojurebot: this doesn't involve you

13:50 clojurebot: It's greek to me.

13:50 technomancy: cooldude127: what's the value of clojure-src-root then?

13:51 cooldude127: technomancy: i set that to ~/src as well before i did this. normally it's ~/lisp/clj

13:53 technomancy: somehow that (cd src-root) isn't doing its job

13:53 technomancy: cooldude127: that's *really* strange; there's no mention of ~/.emacs.d anywhere in the code

13:54 clearly

13:54 maybe I need to move the cd inside the shell-command call

13:54 cooldude127: technomancy: maybe, cuz it depends on which buffer i'm in, the result of (pwd) is different

13:56 technomancy: it doesn't make sense tho. if i do M-: (cd clojure-src-root), then do M-! pwd, i get ~/src (expanded)

13:57 technomancy: yeah; I'm not sure how that works. it seems like putting it in shell-command would be pretty foolproof though.

13:57 cooldude127: technomancy: yeah, like adding (shell-command src-root) before the dolist ?

13:58 cuz i could try that real quick

13:58 technomancy: cooldude127: I was thinking (shell-command (format "cd %s; %s" src-root cmd))

13:59 cooldude127: technomancy: oh that works

13:59 let me try that

14:01 technomancy: that is working, i think, emacs kinda freezes up, but that's its fault, it's checking out into the right directory

14:01 ryszard_szopa: Hi, I've got a question about classpaths and clojure

14:01 technomancy: cooldude127: yeah, the slime checkout takes forever because there's so much history

14:01 cooldude127: considering using CVS for that, but I hate CVS, so it's a rock and a hard place.

14:01 ryszard_szopa: I understand that I am supposed to set the classpath at the command line

14:02 cooldude127: technomancy: i think i got a timeout on that git repo tho

14:02 last time

14:02 ryszard_szopa: but what should I do when developing in the REPL?

14:02 add-classpath seems to have no effect

14:02 technomancy: cooldude127: I could do a shallow clone, but IIUC that means you wouldn't be able to do an update in the future.

14:02 hiredman: clojurebot: add-classpath

14:02 clojurebot: add-classpath is bad, avoid it. I mean it!

14:02 cooldude127: ryszard_szopa: are you using the command-line repl or slime?

14:02 technomancy: I thought it was ok on the repl

14:02 ryszard_szopa: slime

14:03 technomancy: as long as you promise you're just screwing around. =)

14:03 ryszard_szopa: set the swank-clojure-extra-classpaths variable

14:03 cooldude127: ryszard_szopa: you should configure your swank-clojure-extra-classpaths

14:03 technomancy: i hate you

14:03 technomancy: heh

14:03 it should be a list of all the jars/dirs you want apart from clojure.jar itself

14:04 ryszard_szopa: cooldude127: no way of doing that via something like ,l in slime?

14:04 cooldude127: ryszard_szopa: not that i know of

14:04 technomancy: ryszard_szopa: I think you will need to restart slime

14:05 ryszard_szopa: Huh... I am not sure I like the idea of restarting the repl each time I realized I need to use yet another library...

14:05 technomancy: kill all the slime-related buffers as well as the *inferior-lisp* buffer

14:05 ryszard_szopa: it's annoying, but that's how the classpath works.

14:05 gnuvince: ryszard_szopa: see my blog: http://gnuvince.net

14:05 cooldude127: ryszard_szopa: well, i haven't really noticed it as a problem, i don't really work with too many other libraries besides clojure-contrib, at least in the middle of a project

14:05 gnuvince: ryszard_szopa: I posted a clojure-add-classpath command for Emacs.

14:06 ryszard_szopa: you run it before starting SLIME (or else you need to stop and start it again)

14:06 cooldude127: technomancy: i have problems again. now it checks everything out, but slime won't load. no classdeffound clojure/main

14:07 technomancy: crapp�

14:08 cooldude127: technomancy: i think i know why, clojure didn't compile

14:08 i think it's the same problem as the other stuff

14:08 technomancy: if clojure didn't compile, it should complain with a message and stop

14:08 cooldude127: technomancy: well it didn't, cuz i don't have any jars

14:10 technomancy: oh wait, maybe that's not it, but one problem is that those (cd ...) lines use clojure-src-root instead of src-root

14:10 ryszard_szopa: gnuvince: I see, thanks. So it seems that Clojure is more like than like CL in terms of loading libraries.

14:10 technomancy: gnuvince: are you sure you don't want that function to use add-to-list on swank-clojure-extra-classpaths instead?

14:11 cooldude127: ryszard_szopa: if you were saying more like java than CL, then yes it is

14:11 technomancy: cooldude127: oh, of course... that's the problem

14:11 cooldude127: technomancy: yeah my clojure-src-root was my original one this time

14:12 technomancy: shit it's doing it wrong again

14:12 ryszard_szopa: cooldude127: yeah, that's what I was saying ;-)

14:13 cooldude127: technomancy: now it's checking it out into my home folder, wtf!?

14:13 gnuvince: technomancy: what would it change?

14:13 technomancy: cooldude127: yow.

14:14 cooldude127: comment out the slime line for testing the checkout stuff; should make it quicker

14:14 cooldude127: technomancy: this time i didn't type anything, i just accepted the default ~/src. could it possibly be misreading the default and using "" ?

14:14 k

14:14 technomancy: cooldude127: that's possible

14:15 cooldude127: yeah, it doesn't handle default values correctly. which of course I never tested because I already had a checkout in ~/src. =)

14:15 cooldude127: technomancy: how do we fix?

14:16 shoover: can someone please tell clojurebot *why* add-classpath is bad?

14:16 (and by extension, tell the rest of us)

14:16 cooldude127: technomancy: ok well it's definitely the default, cuz entering it in does it right

14:17 technomancy: cooldude127: (if (string= src-root "") (setq src-root clojure-src-root))

14:17 cooldude127: technomancy: what's that last parameter of clojure-src-root in the read-from-minibuffer call?

14:18 technomancy: cooldude127: it's *supposed* to provide a default value, but it doesn't.

14:19 cooldude127: technomancy: "However, in the usual case (where read is nil), read-from-minibuffer ignores default when the user enters empty input and returns an empty string, """

14:19 technomancy: wtf... the default value only works if you're reading a lisp object. that's... not useful.

14:19 cooldude127: technomancy: lol

14:20 technomancy: what about read-string?

14:20 technomancy: cooldude127: i'm just going to force the default value afterwords if there's an empty string

14:20 cooldude127: technomancy: it looks like read-string tho is what you want

14:21 technomancy: cooldude127: just pushed out a new version to my clojure-mode "installer" branch on github

14:21 oh?

14:21 cooldude127: http://www.gnu.org/software/emacs/elisp/html_node/Text-from-Minibuffer.html

14:21 ryszard_szopa: when I do (setq swank-clojure-extra-classpaths '("/Applications/Processing.app/Contents/Resources/Java")), clojure slime refuses to start

14:21 technomancy: oh, that's more like it

14:22 ryszard_szopa: it says: java.lang.Exception: No such namespace: clojure.lang.RT (basic.clj:261) and some "No such var" exceptions

14:22 technomancy: ryszard_szopa: the classpath might be picky about trailing slashes

14:22 but it shouldn't cause that kind of error. =\

14:23 cooldude127: technomancy: so it looks like it should be (read-string (concat "Install Clojure in (default: " clojure-src-root "): ") nil nil clojure-src-root)

14:23 technomancy: cooldude127: sounds good; will push out that fix

14:23 cooldude127: technomancy: i'm doing it right now to test

14:24 hiredman: ryszard_szopa: I think I have seen that before

14:25 can you pastebin the whole exception?

14:25 lisppaste8: url?

14:25 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

14:25 cooldude127: technomancy: yeah the default value is working now

14:26 lisppaste8: ryszard pasted "clojure won't start, classpath issues" at http://paste.lisp.org/display/74730

14:26 technomancy: cooldude127: the format invocations are horribly wrong though

14:26 cooldude127: technomancy: are they? mine work

14:26 technomancy: the ones I pushed, I mean

14:27 cooldude127: yeah, you forgot your s's

14:28 technomancy: i actually didn't even need to do a (format) for the ant ones

14:28 which is weird as hell

14:28 technomancy: so the cd lisp function works for ant but not for git?

14:28 cooldude127: technomancy: yeah wtf?

14:30 technomancy: cooldude127: ok, I found another box to test it on; seems to work fine there though it's also an ubuntu system. what are you running?

14:30 cooldude127: technomancy: i've been doing my work in my emacs-starter-kit code, let me push it and you can see what i have working

14:30 technomancy: this is emacs 23 cocoa on OS X

14:31 technomancy: cool. will want to test in 22 as well, but that makes me feel better that it works on Macs

14:31 hiredman: ugh

14:31 he left

14:32 ryszard_szopa: there is some member of clojure.lang.RT that used to be public, but became private that swank-clojure is trying to call

14:33 cooldude127: technomancy: http://tinyurl.com/amvszn

14:35 technomancy: looks good

14:35 cooldude127: technomancy: yeah seems to work, at least for me

14:36 ryszard_szopa: hiredman: oh... so do you think svn-up swank-clojure may help?

14:36 cooldude127: more like a git pull

14:36 swank-clojure is on git isn't it?

14:36 hiredman: ryszard_szopa:

14:36 maybe

14:37 you can change clojure.lang.RT/ROOT_CLASSLOADER to (clojure.lang.RT/baseLoader) in basic.clj

14:37 maybe

14:39 ryszard_szopa: git pulling made it work. Thanks!

14:40 technomancy: cooldude127: what do you think about switching to CVS for slime? the git clone takes a long time...

14:41 cooldude127: technomancy: i think it might be a good idea, git doesn't really gain much in this case

14:41 if you're installing this way, you're probably not hacking on slime

14:41 duck1123: I think that's the first time I've heard CVS recommended over git because git was too slow

14:41 cooldude127: lol

14:41 cvs doesn't carry a bunch of history

14:42 technomancy: right; the only downside is that it would depend on four things instead of three (git, jvm, ant)

14:42 duck1123: can't you tell git to not dl all the history

14:42 cooldude127: duck1123: then you can't update apparently

14:42 duck1123: ahh... I've never tried it

14:42 cooldude127: me neither, technomancy said it :)

14:43 i think i'm gonna install with this for real now, not just testing

14:44 technomancy: never tried it; that's just what I've heard

14:45 duck1123: shallow coppies can't be cloned or fetched from or pushed to/from

14:45 you should still be able to fetch/pull into

14:45 cooldude127: duck1123: then how do we do such a thing?

14:45 i'm about to run it, i want to make this happen :)

14:45 duck1123: git clone --depth 2 git://....

14:45 technomancy: duck1123: ah; I must have misunderstood

14:46 Chousuke: I find git to be faster *despite* the fact it clones the whole history.

14:46 duck1123: I just checked the docs

14:46 technomancy: Chousuke: I haven't actually tried this; it's just a hunch

14:46 slime has *lots* of history though

14:46 cooldude127: Chousuke: in general, yes, but with something like slime, it's slow as crap

14:46 duck1123: I wonder if you can pull in more history after the fact

14:46 Chousuke: cooldude127: it took a few minutes for me.

14:46 not exactly slow.

14:46 emacs took a bit longer.

14:47 duck1123: I had problems git cloning slime on friday, I might try this as well

14:47 cooldude127: Chousuke: cvs doesn't take nearly that long tho, and this clojure-install thing makes emacs hang until it's odne

14:47 *done

14:48 Chousuke: hmm, I might just test it

14:48 duck1123: doing it right now

14:49 Chousuke: github is usually slow though. ./

14:49 or well, slowish

14:49 technomancy: just pushed out a fixed version that uses a shallow clone for slime

14:50 * Chousuke does a full clone

14:50 technomancy: http://github.com/technomancy/clojure-mode/blob/9219f13d87f4e98feeca01dc6079c1c558b907d6/clojure-mode.el

14:50 Chousuke: ... slow internets, only 6kB/s |

14:50 not a git problem though.

14:50 technomancy: if anyone else could test this I'd appreciate it

14:51 cooldude127: technomancy: i don't know if it actually made it any better

14:51 Chousuke: the whole slime repo seems to be about 3MB

14:51 with full history.

14:51 duck1123: --depth 2 seems like it is still downloading a lot

14:51 technomancy: Chousuke: 33MB for me

14:51 Chousuke: technomancy: unpacked?

14:51 cooldude127: WOO i have up-to-date slime and stuff

14:51 technomancy: Chousuke: from git://git.boinkor.net/slime.git

14:52 cooldude127: clojurebot: latest?

14:52 clojurebot: latest is 1245

14:52 technomancy: Chousuke: .git itself is 30MB. haven't packed it; this is a fresh clone.

14:52 Chousuke: technomancy: the transported size is about 3MB

14:52 technomancy: with --depth 2 it took 5.350 secs

14:52 Chousuke: or maybe closer to 4 actually.

14:53 cooldude127: technomancy: so the git repo for clojure can be a few revs behind

14:53 Chousuke: Receiving objects: 28% (3867/13438), 1.10 MiB | 6 KiB/s

14:53 why are my intertubes so clogged right now :/

14:53 cooldude127: lol. brb

14:53 * Chousuke sometimes gets 3MB/s...

14:54 duck1123: I'm doing an offlineimap sync of my gmail account as well

14:54 Chousuke: and then sometimes it looks like my ISP decides to put me on low-speed zone.

14:54 completely randomly.

14:56 duck1123: what git repos are you pulling from nablaone's on github?

14:56 Chousuke: yeah

14:59 technomancy: should work in 22 now

15:03 duck1123: so you guys were able to clone slime recently, or no? I'm still getting "Cannot obtain needed blob abe81d1e64ba1dba47e4a1d81ee2c83a124615f4"

15:04 technomancy: duck1123: you could try git://git.boinkor.net/slime.git

15:04 but the github one works for me with depth 2

15:05 duck1123: ah ha. --depth works over git:// but not http://

15:06 The firewall at my work blocks the git:// port

15:06 technomancy: weak

15:07 rhickey: One more lazy-cons to go - in for

15:07 * rhickey shudders

15:07 duck1123: I was trying to set up all of my dependencies for my dotfiles as submodules in git, and I needed Url's that would work both at work and home

15:10 cooldude127: technomancy: so is clojure-install now pretty much finalized?

15:11 technomancy: cooldude127: I'm happy with it as long as it works on 23, 22, gnu/linux, and OS X.

15:11 if it works on w32 then great, but I'm not going to lose sleep over it. =)

15:11 cooldude127: yeah i wouldn't

15:11 technomancy: anyway, I'll probably send a pull request to jochu to see if it can get merged upstream

15:11 then I'll ping the mailing list and toss up a blog post.

15:12 cooldude127: cool

15:12 i'm happy to have up-to-date stuff

15:12 technomancy: oh right; well there still needs to be an update function; this just does the initial clone.

15:13 but that should be easy to write.

15:13 cooldude127: technomancy: yeah, just git pull in each dir

15:13 technomancy: and recompile

15:13 but yeah

15:13 cooldude127: oh yeah that too

15:14 technomancy: if you've got some spare cycles... patches are accepted. =)

15:14 preferably to the clojure-mode repo rather than the starter-kit

15:14 cooldude127: Chouser: you get your custom-print stuff in yet?

15:14 technomancy: i'll see if i have time, but my elisp skills are quite bad

15:15 technomancy: cooldude127: well this seems like a great place to get started

15:15 cooldude127: lol true

15:16 well, i'm just in health class, so i got time, let's see what i can do :)

15:16 Chouser: rhickey: ha! 'for' only took you an hour to knock out the first time, right?

15:17 cooldude127: nope, haven't even brought it up on the group yet.

15:17 cooldude127: technomancy: why don't i get the installer branch when i clone the repo?

15:17 Chouser: cooldude127: do you have a good (simple?) use case?

15:17 cooldude127: Chouser: ok, just wondering, i'm still using my crappy hack

15:18 Chouser: um, i don't know if it's simple, but i'm writing some code that deals with matrices, and i have it so they print out in columns and rows

15:18 kind of like matlab

15:20 rhickey: Chouser: heh - for should be a lot easier now, but...

15:20 technomancy: cooldude127: git clone just clones master; you need to add it as a remote

15:20 cooldude127: or use the github gem; it's pretty handy for stuff like this

15:20 cooldude127: technomancy: i think git checkout --track worked for me

15:21 technomancy: oh, right

15:21 rhickey: its full of workarounds for partial laziness as is

15:21 it's

15:23 cooldude127: technomancy: clojure-update probably doesn't need a src-root, shouldn't it just use clojure-src-root, since it would assume it's already setup correctly?

15:24 technomancy: cooldude127: that sounds like a good assumption

15:24 cooldude127: would be good to provide a helpful error message if it hasn't been set correctly (or if the install hasn't happened) though.

15:25 cooldude127: yeah i was gonna check if the appropriate directories were there

15:25 technomancy: might be enough just to check the return value of shell-command

15:25 cooldude127: oh yeah maybe

15:25 technomancy: it'll be zero if it succeeded

15:26 cooldude127: yeah

15:26 emacs lisp is like cl, where let is not sequential, that's let*, right?

15:26 ayrnieu: right.

15:27 cooldude127: k

15:27 gnuvince: right.

15:29 Chouser: cooldude127: oh, that is a good example. still readable by 'read', just \newline instead of \space in a few places.

15:29 cooldude127: Chouser: not exactly

15:29 Chouser: oh

15:30 cooldude127: not readable by read at all

15:30 Chouser: well, that could be my example anyway. :-)

15:30 cooldude127: lol

15:30 that works then

15:31 Chouser: cooldude127: out of curiosity, though, why do you need prn and friends to print in this format, instead of just having a new function?

15:31 cooldude127: Chouser: i want the repl to print it this way, instead of having to call a function everytime

15:31 Chouser: oh, sure.

15:31 cooldude127: that's how i did it at first, but it was infuriating

15:32 technomancy: i have something here that i'm about to test for the update function

15:32 ayrnieu: ,(doc repl)

15:32 clojurebot: java.lang.Exception: Unable to resolve var: repl in this context

15:32 ayrnieu: ,(doc clojure.main/repl)

15:32 clojurebot: "([& options]); Generic, reusable, read-eval-print loop. Reads from *in* and writes to *out*. *in* must either be an instance of LineNumberingPushbackReader or duplicate its behavior of both supporting .unread and collapsing CR, LF, and CRLF into a single \\newline. Options are sequential keyword-value pairs. Available options and their defaults: - :init, function of no arguments, initialization hook default

15:32 ayrnieu: :print is one of the options

15:33 cooldude127: ayrnieu: but how do i make that happen in the normal slime repl?

15:34 ayrnieu: I don't know what slime does.

15:34 hiredman: clojurebot: slime?

15:34 clojurebot: slime is icky

15:35 cooldude127: technomancy: i think i have something that works, but it displays a buffer with the ant results, why doesn't yours do that? i ripped your compiling code verbatim (except for a variable name change)

15:35 ayrnieu: ok

15:35 well this is working for me at the moment

15:38 technomancy: cooldude127: it could be related to the length of the output

15:38 check the shell-command docstring

15:39 cooldude127: technomancy: i can send you a patch of what i have for a clojure-update function

15:39 and you are right, it's long enough now to show

15:39 i guess

15:40 technomancy: if you wrap it in a save-window-excursion, it will probably suppress the buffer being shown

15:40 cooldude127: no need for a patch if it's just a single new function; you can just lisppaste it

15:41 cooldude127: technomancy: ok i will after i try the save-window-excursion

15:42 technomancy: that's probably better, the diff is weird cuz i used your little C-c n shortcut and it changed a lot of indentation

15:42 technomancy: ok save-window-excursion suppressed it, i'll paste it real quick

15:44 technomancy: yeah, definitely don't want to clean up whitespace in the same commit as real features

15:45 kefka: Which do you recommend for accessing MySQL: SBCL + CLSQL or Clojure + JDBC?

15:45 lisppaste8: cooldude127 pasted "clojure-update emacs function" at http://paste.lisp.org/display/74734

15:45 cooldude127: technomancy: lisppaste for emacs is soooo cool

15:46 technomancy: that it is. =)

15:46 cooldude127: technomancy: i find that the autoloads for it don't work tho

15:46 hiredman: well, obviously, the one with clojure...

15:46 kefka: Assume I can do it with either Clojure or SBCL

15:46 cooldude127: like when i try to just use one of the lisppaste functions, it says it can't load the file

15:46 technomancy: cooldude127: yeah, I think that's a bug in elpa

15:47 cooldude127: technomancy: it works once i explicitly load the lisppaste.el file

15:47 technomancy: cooldude127: i'd collapse your let* into a let with a single variable

15:47 kefka: I started down the SBCL + CLSQL road, but CLSQL has a lot of missing features that are pissing me off... plus it seems not to be a very "lively" project in terms of development

15:47 cooldude127: technomancy: you're welcome to, i did it for clarity in my development, which i expected to be longer

15:47 lol

15:47 ayrnieu: I think that Java doesn't have very solid libraries for accessing MySQL. It's an undernourished language with few developers or business use, you see.

15:48 cooldude127: ayrnieu: jdbc does work tho

15:48 WizardofWestmarc: I think he was joking

15:48 technomancy: cooldude127: sure; I'll make the change.

15:48 thanks for the codes.

15:48 cooldude127: technomancy: no problem, that didn't take very long. i love it

15:48 kefka: WizardofWestmarc: I hope so...

15:48 WizardofWestmarc: at some point I want to play with sqlite in clojure, but haven't gotten around to it

15:48 kefka: WizardofWestmarc: I took ayrnieu seriously, because I thought "it" meant MySQL

15:48 cooldude127: i like sqlite

15:48 yeah me too

15:49 WizardofWestmarc: um, mysql is a pretty heavily supported codebase...

15:49 kefka: WizardofWestmarc: e.g. MySQL undernourished compared to enteprise products

15:49 WizardofWestmarc: Cool.

15:49 cooldude127: How hard is JDBC to learn?

15:49 technomancy: it's too bad mysql isn't more closely connected with Sun... then it would get better Java support.

15:50 WizardofWestmarc: technomancy: it may get there with time, it's only been what, a year since they bought the company?

15:50 cooldude127: kefka: not too hard i think

15:50 technomancy: WizardofWestmarc: (it was a joke)

15:50 WizardofWestmarc: :P

15:50 I didn't think they'd tightened integration yet

15:50 hence still needing JDBC

15:50 cooldude127: nothing like a good joke to reveal how much none of us know what we're talking about :)

15:51 ayrnieu: kefka: http://www.jdbc-tutorial.com/

15:51 WizardofWestmarc: �_�

15:51 hiredman: kefka: there is also clojureql

15:51 which I think is maybe sort of like clsql

15:51 cooldude127: hiredman: hopefully with less suck

15:52 hiredman: I guess

15:52 WizardofWestmarc: well it's actively being worked on

15:52 hiredman: I haven't really used either

15:52 WizardofWestmarc: so that's an automatic plus ;)

15:52 technomancy: there's nothing quite like being able to bother the author on IRC if something goes wrong

15:53 hiredman: last I checked clojureql did not work well with postgres

15:53 cooldude127: technomancy: that's what i love about emacs-starter-kit ;)

15:54 i just go on irc and bug you when something's wrong

15:56 technomancy: heh

15:57 cooldude127: hmm, great health class is over and i actually accomplished something. thank you for that, i wouldn't have done shit otherwise

15:57 * technomancy remembers what it was like to be in school

16:08 * gnuvince got bit by integer literals *again*

16:08 gnuvince: ,(let [x (short 0)] ({0 "zero"} x))

16:08 clojurebot: nil

16:08 gnuvince: ,(let [x (short 0)] ({0 "zero"} (int x)))

16:08 clojurebot: "zero"

16:09 rhickey: gnuvince: why are you using shorts?

16:09 gnuvince: rhickey: getting them from a buffer.

16:09 (.getShort byte-buf)

16:10 rhickey: gnuvince: use a sorted map if you want fuzzy compares

16:11 ,(let [x (short 0)] ((sorted-map 0 "zero") (int x)))

16:11 clojurebot: "zero"

16:12 ayrnieu: ,((shorted-map 0 "zero") 0M)

16:12 clojurebot: java.lang.Exception: Unable to resolve symbol: shorted-map in this context

16:13 ayrnieu: ,((sorted-map 0 "zero") 0M)

16:13 clojurebot: "zero"

16:14 gnuvince: ,[(/ (Math/log 10000) (Math/log 32)) (/ (Math/log 10000) (Math/log 2))]

16:14 clojurebot: [2.65754247590989 13.28771237954945]

16:15 cooldude127: eww

16:15 what is that?

16:16 gnuvince: cooldude127: can't specify the base with Math/log

16:16 rhickey: gnuvince: it can't be otherwise and retain compatibility with java.util.Map, which is quite important to some people, so either normalize your keys or use sorted-maps

16:16 gnuvince: rhickey: I'll normalize.

16:17 It's not a chore, it's just a pitfall I keep falling into.

16:17 cooldude127: gnuvince: oh, change of base, got it

16:17 rhickey: gnuvince: Clojure once had its own numbers and Java interop was much more painful and pitfall-ful

16:18 gnuvince: I can imagine.

16:19 cooldude127: making clojure.lang.Ratio work with other numbers is weird enough. it doesn't fall into the hierarchy

16:19 gnuvince: what was the problem you were running into?

16:20 gnuvince: I have some litteral maps with integers as keys, and when I use shorts (that I get from reading a ByteBuffer) and try to fetch a value, I got nil because I forgot to convert to int.

16:20 This illustrated the problem:

16:20 ,(let [x (short 0)] ({0 "zero"} x))

16:20 clojurebot: nil

16:21 cooldude127: oh, i see

16:24 clojurebot: svn rev 1246; [lazy] got rid of lazy-cons

16:25 rhickey: ok, lazy branch safe for the intrepid

16:25 Chouser: wow

16:25 cooldude127: woahh! where did lazy-cons go?

16:25 rhickey: i.e. those willing to try living without lazy-cons

16:25 durka42: i guess i missed a huge discussion about what replaces it

16:25 Chouser: out moded, out dated, downsized, replaced.

16:26 cooldude127: what's done instead?

16:26 ayrnieu: http://clojure-log.n01se.net/

16:26 rhickey: the important thing to note, at least until I get to doc, is that sequence fns return logical sequences, not (necessarily) ISeqs

16:26 Chouser: specifically: http://clojure-log.n01se.net/date/2009-02-02.html#09:47

16:26 rhickey: use lazy-seq, cons and more in lazy fns, all of core has been changed over and should serve as an example

16:27 Chouser: so no nil-punning on anything except 'rest'?

16:27 rhickey: Chouser: and seq!

16:28 Chouser: ah. right.

16:28 rhickey: http://code.google.com/p/clojure/source/browse/branches/lazy/src/clj/clojure/core.clj#409

16:28 gnuvince: What's nil punning again?

16:28 Chouser: but not concat, filter, map, etc?

16:28 rhickey: http://code.google.com/p/clojure/source/browse/branches/lazy/src/clj/clojure/core.clj#1408

16:28 Chouser: right

16:29 amazingly, after I got lazy-seq in, I didn't have to change any consumer code of the lazy-sequence fns, only the fns themselves, so I expect the vast majority of code is using seq or rest, which work as always

16:29 hiredman: hmmm

16:29 rhickey: http://code.google.com/p/clojure/source/browse/branches/lazy/src/clj/clojure/core.clj#1441

16:30 http://code.google.com/p/clojure/source/browse/branches/lazy/src/clj/clojure/core.clj#1459

16:30 etc, search for lazy-seq

16:31 everything should be truly lazy now, if not it's a bug

16:31 Lau_of_DK: rhickey: If I start producing code that works with that branch, what are the odds that I ahve to throw it all away in a month or two ?

16:31 Chouser: is (apply concat coll) still greedy on the first couple elements of coll?

16:32 rhickey: user=> (def x (apply concat [(map #(doto % prn) (range 10)) (map #(doto % prn) (range 10))]))

16:32 #'user/x

16:32 user=> (first x)

16:32 0

16:32 0

16:33 fully lazy everywhere, or it's a bug

16:33 Chouser: :-) sweet

16:34 rhickey: Please try it out and let me know - I'll try to write up a little doc + treatise later tonight

16:34 gotta run

16:41 hiredman: xD

16:42 I take that back

16:42 :(

16:42 for a second I thought a Runnable was also a TimerTask

16:51 * durka42 notices a function in core.clj shadowing one of the core functions with its parameter

16:51 * danlarkin gasps

17:03 hiredman: what is better: mutiple atoms holding state, or one atom holding a map of state?

17:04 Cark: i adopted this rule : if you start using atoms/refs all over the place, the you can as well program in java

17:04 then*

17:05 hiredman: :P

17:05 as it happens I am proxying a java class

17:05 the javadoc has all kinds of reference to state, most of which I will ignore

17:05 Cark: ah the beast is lurking below, trying to take you in the mutation depths

17:06 ayrnieu: I have refs all over the place for debugging agents.

17:06 hiredman: I think it will end up with two pieces of state

17:06 Cark: yep when using agents i too have refs showing up

17:07 hiredman: one for cancel() so if the TimerTask is canceled it will no longer run, and one for scheduledExecutionTime

17:07 to keep track of the last execution time

17:08 Cark: why not a single ref with both values ?

17:08 hiredman: atom

17:09 Cark: ah right

17:09 te: i cant get clojure mode to do syntax hilighting

17:09 where have i failed as a father

17:09 hiredman: Cark: that is what I am doing right now

17:09 (atom {})

17:09 te: i have: (add-to-list 'load-path "~/.clojure/clojure-mode") (require 'cojure-mode)

17:09 do i need more?

17:09 hiredman: the time at which the most recent execution of this task was scheduled to occur, in the format returned by Date.getTime(). The return value is undefined if the task has yet to commence its first execution.

17:09 durka42: te: you chose emacs over vim :p

17:10 te: eventually yes

17:10 i havent played with emacs much since we last talked

17:10 hiredman: brilliant spec there

17:10 te: but i have some time to kill today

17:10 ayrnieu: te - (global-font-lock-mode 1), something like.

17:10 te: oh that will turn on hilighting and shite?

17:10 ill try it

17:11 ayrnieu: Also look at http://www.emacswiki.org/cgi-bin/wiki?ColorTheme

17:11 Cark: hiredman : heh, last time i had a ref being a map with one field being the agent, when this field was nil the agent was supposed to stop

17:12 pretty much the same thing

17:18 hiredman: ok

17:18 * hiredman digs around in clojurebot

17:29 nsinghal: I have classpath with "classes" and "src" directory of a java project in that order. When i do (require :reload-all 'org.cc.file) - it is not reevaluating the file. Does clojure not look for the changed clj file if it finds the file__init.class?

17:31 hiredman: hmmm

17:31 I am pretty sure I read somewhere that it picks whichever is newest, .class or .clj

17:52 hmmm

18:05 technomancy: te: it should be on by default unless you're on a really old version

18:07 ricree: I'm slightly confused by defining classes in clojure. If I wanted to do something like this jambi tutorial where they define a custom QT widget (http://doc.trolltech.com/qtjambi-4.4/html/com/trolltech/qt/qtjambi-tutorial5.html), what would be the best way to go about it in clojure?

18:13 ayrnieu: (proxy [QWidget] [] ...), I'd expect.

18:17 ricree: thanks, ayrnieu.

18:22 djpowell: what happens when you send or send-off to an agent from inside the agent?

18:23 does it reuse the same thread?

18:23 ayrnieu: Nothing obviously special. I don't know if it reuses the same thread.

18:24 djpowell: ok. The docs say that they are ordered though

18:24 ayrnieu: they are ordered from the caller's POV.

18:25 hiredman: djpowell: send and send-off are held till either the end of the action, or they are explicitly released

18:26 sends happen on a fixed size thread pool

18:26 ayrnieu: that is to say, multiple threads can send to an agent and these sends can be interleaved, but the sends from each thread will still be in their own order.

18:26 hiredman: cores + 1 I think

18:26 ayrnieu: do send-off spawn their own thread?

18:27 hiredman: it is another threadpool, maybe it grows dynamically?

18:27 dunno

18:34 ayrnieu: send-off creates a new thread; send uses the thread pool

18:34 hiredman: oh

18:35 hmm

18:35 ayrnieu: er, no, I'm confused.

18:35 final static ExecutorService soloExecutor = Executors.newCachedThreadPool();

18:35 this is what it uses.

18:36 hiredman: http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool%28%29

18:36 ok

18:36 clojurebot needs java doc url lookups

18:37 durka42: gorilla has such a function that i bet you could steal

18:37 ayrnieu: so the difference is that send-off may create a new thread, but send will stick to

18:37 Executors.newFixedThreadPool(2 + Runtime.getRuntime().availableProcessors());

18:37 hiredman: durka42: hmmmm

18:37 ,(System/getRuntime)

18:37 clojurebot: java.lang.NoSuchFieldException: getRuntime

18:38 durka42: ,(Runtime.getRuntime)

18:38 clojurebot: java.lang.ClassNotFoundException: Runtime.getRuntime

18:38 hiredman: ,(Runtime/getRuntime)

18:38 clojurebot: #<Runtime java.lang.Runtime@14275d4>

18:38 hiredman: ,(Runtime/getRuntime/availableProcessors)

18:38 clojurebot: java.lang.Exception: No such namespace: Runtime/getRuntime

18:38 ayrnieu: use clojure.contrib.javadoc

18:38 durka42: (.. Runtime getRuntime availableProcessors)

18:38 ,(.. Runtime getRuntime availableProcessors)

18:38 clojurebot: 1

18:39 durka42: ,(use 'clojure.contrib.javadoc)

18:39 clojurebot: java.lang.ExceptionInInitializerError

18:39 durka42: that was not supposed to happen

18:40 hiredman: ayrnieu: seems pretty bare

18:40 durka42: => (find-javadoc-url "java.lang.String")

18:40 "http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html"

18:40 ayrnieu: it gets URLs; what else did you want?

18:40 hiredman: I must be looking at an old rev

18:41 hmm

18:41 none if the 'clojure.contrib.javadoc verions I a can find have find-javadoc-url

18:42 durka42: rev 430

18:42 hiredman: I am looking at trunk on google code

18:43 ayrnieu: are you looking at the master svn repo, or a github copy?

18:43 OK. I have 432, trunk, and see ./src/clojure/contrib/javadoc.clj:(defn find-javadoc-url

18:43 hiredman: I am look at it in the google code web interface

18:44 ah

19:31 ricree: when defining a function from a gen-class call, what is the clojure equivelent of "this"

19:32 Chouser: ricree: if you're using gen-class (not proxy) then each function's first argument will be the value of "this" -- you can name it whatever you want.

19:32 ricree: oh, thanks. Out of curiosity, what is it when using proxy?

19:32 Chousuke: this

19:32 it's just auto-bound

19:33 ricree: ok. thanks

19:50 ayrnieu: QApplication::exec: Must be called from the main thread <- bah.

19:51 Chouser: yes, Qt is a bit touchy to get working the way you'd want in Java and/or Clojure.

19:52 ayrnieu: http://gist.github.com/57210 follows the java, but - at least in OSX - the created window gives me the color wheel.

19:53 durka42: the spinning beach ball of death you mean? :p

19:53 ayrnieu: SBoD, yes.

19:54 durka42: are you trying to .show() a button like it was a window? i don't know Qt at all but that seems wrong

19:54 ayrnieu: that's what http://doc.trolltech.com/qtjambi-4.4/html/com/trolltech/qt/qtjambi-tutorial1.html has

19:55 durka42: hmm, so it does

20:20 thearthur: hello all

20:20 im attempting to use clojure with mvn

20:20 talios: 'lo

20:20 thearthur: and cant get clojure-contrib into the classpath

20:21 talios: how are you using it with mvn?

20:21 thearthur: mvn seems overly complicated for clojure (hainv to create a stub java class to start clojure and all)

20:21 http://pupeno.com/blog/how-to-create-a-clojure-application

20:21 ayrnieu: aha, for the SBoD I just needed -XstartOnFirstThread

20:21 talios: I made a simple mojo plugin for the compiler the other night, will probably add something to run the repl shortly

20:22 ricree: can you create an instance of a class in the file where it is defined with gen-class?

20:22 thearthur: what should the clojure-contrib.jar be named and where should it be

20:23 so the loader-thing will find it?

20:23 Chouser: ricree: yes

20:26 cpath: Is this normal? After starting clojure repl, I replaced, added or changed jar or java classes. However it doesn't affect anything until restarting it.

20:27 I'm looking for :reload-all for java classes.

20:27 thearthur: when do i use a '.' and when do i use a '/' in (use 'bla.bla/foo)

20:28 durka42: thearthur: just make sure clojure-contrib.jar is in the classpath

20:28 / is for java class static members

20:28 and for namespace/function i believe

20:28 ayrnieu: foo.bar.baz is always for packages named 'foo.bar.baz'. These never refer to methods. Separate .foo .bar are methods. foo.bar.baz/quux calls the static method quux under foo.bar.baz

20:29 thearthur: should I put clojure-contrib under the maven root, or assume everyone building this will have it?

20:29 ricree: For some reason, I'm getting "Unable to resolve classname" errors with this code http://pastebin.com/d6d2de890 . Can anyone spot what I'm doing wrong here?

20:30 durka42: which classname

20:30 hiredman: wew

20:30 when it rains it pours

20:30 durka42: hmm i thought you were supposed to put gen-class in the ns macro nowasdays

20:30 ayrnieu: thearthur - the .jar is only 111K. I've seen projects on github that just include clojure.jar and such

20:30 durka42: nowadays*

20:31 ayrnieu: ricree, where do you get it?

20:31 cpath: Do I have restart clojure REPL whenever I change java classes, even though they are in classpath?

20:31 hiredman: cpath: I am pretty sure you do

20:32 metaperl: at the REPL, I typed something and got back (quote foo) instead of just foo ... if I type 'foo I get back just foo and that is what I see on my screen, but I must've typed a hidden character

20:32 ayrnieu: (.. QFont$Weight Bold value) <-- huh. I just did (.setFont (doto (QFont. "Times" 18) (.setBold true)))

20:32 ricree: when I call load-file on it in slime. it's coming from the (new BlockClass) at the end

20:32 hiredman: there are seperate java frameworks that do class reloading and stuff

20:32 metaperl: hi ayrnieu, you are into haskell arent you?

20:32 ayrnieu: metaperl - no.

20:32 metaperl: I thought I knew you from somewhere

20:32 talios: anyone here working woth OSGi at all?

20:32 hiredman: ricree: I am pretty sure (gen-class ...) only generates a class if you (compile ...) the namespace

20:33 cpath: hiredman, Thank you.

20:33 ricree: hiredman: is there a good alternative for what I'm trying to do here?

20:34 I've been trying to follow along with the qt tutorials. in particular (http://doc.trolltech.com/qtjambi-4.4/html/com/trolltech/qt/qtjambi-tutorial5.html )

20:34 hiredman: ricree: make a seperate namespace with gen-class and (compile ...) it

20:35 thearthur: how dose maven choose the class path?

20:35 hiredman: that is the only way to really extend a class

20:35 thearthur: I would check to see if maven has it's own irc channel were you can ask maven specific questions

20:35 talios: thearthur: class path is based on your declared dependencies

20:35 Chouser: ricree: you might need the fully qualified name of your new class.

20:36 ricree: should this be done in a separate file from the other code? can I use multiple namespaces in one file.

20:36 thearthur: no #maven,#mvn,#maven2 ... that i could find

20:36 ricree: Chouser: I tried that, didn't seem to work

20:37 durka42: thearthur: they're on irc.codehaus.org

20:38 thearthur: ok, :)

20:39 talios: thearthur: not sure if it

20:39 thearthur: not sure if it'll help, but over on http://www.talios.com/clojure_running_successfully_under_osgi.htm I describe how I'm attempting to use clojure with maven, using the mojo I wrote

20:40 just added a repl mojo, but not tried it yet as waiting on clojure to checkout on this machine to compile it first ;)

20:40 Chouser: ricree: you know that you have to compile that file for the gen-class to work?

20:41 thearthur: talios, :) /me looks at that

20:41 ricree: no, I didn't.

20:41 durka42: what's mojo?

20:42 ~mojo

20:42 clojurebot: excusez-moi

20:42 talios: durka42: a mojo is a maven plugin

20:42 durka42: moldy old java object :)

20:42 oh ok

20:45 Chouser: ricree: if you're not adding any methods in your new subclass, and you don't need the name of the class to be anything particular, 'proxy' is easier to use.

20:48 thearthur: how will the loader know to look in clojure-contrib.jar for clojure.contrib.duck-streams

20:49 hiredman: thearthur: the jvm looks through all jars for classpaths

20:49 clojure.contrib.duck-streams is actually a classpath/directory structure in the jar

20:50 clojure/contrib/duck_streams.clj

20:50 o_: I just saw Making Clojure Lazier on clojure.org. very interesting stuff. can someone explain what "nil punning" means there?

20:50 hiredman: ,(seq [])

20:50 clojurebot: nil

20:50 thearthur: nil punning is the result of (good? (gen-pun 'joke))

20:51 :)

20:51 o_: ;-)

20:51 but really

20:51 thearthur: sorry, i dont actually know

20:51 hiredman: I think nil punning is what rhickey calls it when (seq) of an empty thing is nil

20:52 so when you see stuff like (if n foo bar)

20:52 and n is a seq

20:52 o_: but isn't a seq of an empty thing an empty sequence ()?

20:52 hiredman: ,(seq [])

20:52 clojurebot: nil

20:53 hiredman: ^- no

20:53 o_: oh

20:54 well, then no nil punning is a good thing, no?

20:54 Chouser: nil punning is when you assume the return value of a fn is nil instead of an empty collection.

20:55 yes, it's very convenient

20:55 o_: chouser: but only if you (seq) it, no? otherwise it's still an empty seq.

20:55 ayrnieu: ,(nil? (seq []))

20:55 clojurebot: true

20:56 ayrnieu: is clojurebot running the fully-lazy branch?

20:56 o_: ayrnieu: according to the new docs, no.

20:57 hiredman: ayrnieu: nope

20:58 o_: does the new lazy branch means sequences behave more like functions and less like data-structures?

21:03 hiredman: o_: eh? not from what I have seen

21:04 (which, granted is not much)

21:04 I think it mostly just means more explicit calls to seq

21:04 Chouser: in both trunk and lazy, (seq foo) will return nil for empty foo

21:05 rhickey: lazy notes in progress: http://clojure.org/lazier

21:06 Chouser: in trunk, all functions that return seqs (map, filter, concat, etc.) return nil instead of anything empty, but in lazy branch they may return a non-nil empty thing, such that you have to call 'seq' on them to test if there's something there.

21:09 o_: I'm trying to figure out when I last used or assumed that map/filter/concat return nil when applied to an empty sequence but I can't. anyone got an example of idiomatic use of nil punning?

21:10 this is important. otherwise I won't know whether I should be excited or alarmed following the latest developments. :-)

21:11 ayrnieu: I just installed lazy and saw that what I was just doing still worked. That was pretty calming.

21:14 Chouser: If I understood what rhickey was saying earlier, he wasn't relying on nil punning as much as he thought. Perhaps not at all (except for with 'rest' which will still work)

21:16 ayrnieu: (rest x) == (seq (more x))

21:20 te: So I'm using clojure-mode with swank clojure/slime

21:21 basically i open up slime, and then M-x clojure-mode

21:21 the syntax turns on, but then when I hit return it doesn't interpret the block i just typed in

21:21 it just keeps going to the next line, as if i never hit enter

21:22 cooldude127: te: don't use clojure-mode in slime buffer

21:22 s

21:22 slime as it is is fine, it uses repl-mode

21:22 clojure-mode is for .clj files

21:22 te: it doesnt do any hilighting though

21:23 cooldude127: highlighting isn't really important at the repl

21:23 te: or does it?

21:23 yeah i know its not that big of a deal

21:23 but it would be nice while im learning

21:23 im very visual

21:23 cooldude127: te: it's not supposed to highlight the repl

21:23 te: i understand

21:23 cooldude127: te: you can type all your code into a file, and then eval it

21:23 te: im just making a comment

21:23 * te nods

21:23 cooldude127: C-M-x evaluates a top-level form

21:24 thearthur: what is the best method/framework for turning clojure code into a program that can ship?

21:25 hiredman: what do you mean by ship?

21:25 thearthur: ie: what is better than maven

21:25 and by better i mean easier to use

21:25 hiredman: if you mean "make a jar" most people use ant

21:26 I cannot say I am fond of maven or ant

21:26 thearthur: maven is hard to get right this classpath issue on clojure-contrib has stopped me

21:26 hiredman: make works fine

21:26 talios: I found maven quite easy to work with

21:26 ayrnieu: does a gen-class tutorial exist?

21:27 hiredman: clojurebot: compile?

21:27 clojurebot: Excuse me?

21:27 hiredman: ayrnieu: there is http://clojure.org/compilation

21:27 talios: thearthur: you just need to declare clojuire-contrib as a dependency in your pom.xml - if its not in a repository (local or otherwise), you could use a system dependency and specify the path

21:27 ayrnieu: yeah, I've seen that.

21:28 hiredman: there are that, and the doc string for gen-class

21:28 ayrnieu: ... huh. Nevermind.

21:30 thearthur: thanks talios

21:30 i will try to figure out how to do that

21:30 mvn is not intended it seems for the java newb

21:31 cooldude127: thearthur: go with ant if you're a beginner

21:31 talios: I wouldn't say that - I'd just say it sounds like you've not yet learnt how dependencies work.

21:33 thearthur: they are quite mysterious actually

21:33 talios, if i understood how the classpath was constructed things i think would get better

21:34 lisppaste8: ayrnieu pasted "lazy fail" at http://paste.lisp.org/display/74760

21:34 ayrnieu: with trunk, that compiles

21:36 OK, lazy rev 1247 compiles it.

21:42 ricree: honestly. compiling is kind of confusing

21:43 Chouser: it is a bit, and it certainly has more moving parts

21:43 I avoid it whenever possible

21:43 ricree: the most frustrating part is how easy the documentation makes it look

21:44 hiredman: you almost never need to (compile ...) stuff

21:44 clojurebot: I am using gen-class

21:44 clojurebot: No entiendo

21:44 hiredman: bah

21:44 ayrnieu: now I have two problems?

21:44 hiredman: is that it?

21:44 :P

21:45 ricree: so with defining a new widget in that QT example I was working with earlier. is there some way I should be doing this that avoids gen-class/compile?

21:46 Chouser: ricree: if you're not adding any methods in your new subclass, and you don't need the name of the class to be anything particular, 'proxy' is easier to use.

21:46 ricree: and that doesn't require compiling?

21:47 Chouser: correct

21:47 ayrnieu: (def widget (doto (proxy [QWidget] []) (.setFixedSize 200 120) ...))

21:50 ricree: by the way. thanks a ton for all the help, everyone. I know I've been making a pest of myself in this channel today, and I appreciate all the help I've gotten

21:54 Chouser: on behalf of all the other people who actually answered your questions, you're quite welcome. :-)

21:55 lisppaste8: ayrnieu pasted "qt4 - this seems about right" at http://paste.lisp.org/display/74761

21:56 gnuvince_: Is it just me or is the hardest part of "Clojure" when you are dealing with a mutable Java object and you wonder how the hell you're going to use it cleanly?

21:57 ayrnieu: I for one praise Java's ByteBuffers.

22:00 duck1123: evening folks

22:00 I bought Programming Clojure tonight. I'm happy.

22:02 cooldude127: gnuvince_: um, i would say the hardest part is doing things you're used to doing with mutable data when that isn't possible

22:02 ricree: I've been thinking about getting it, if for no other reason than as a sign of appreciation for the posts he did translating examples from PCL to clojure

22:02 it's been a tremendous help getting started with clojure

22:03 hiredman: the hardest part is when you find a java interface that is almost exactly the same as Runnable, but clojure functions don't implement it

22:03 cooldude127: lol

22:04 hiredman: I really should write a mk-interface macro to avoid writing proxy all the time

22:04 walters: hiredman: i wonder if invokedynamic could make the performance cost of auto-implementing single-method interfaces acceptable

22:05 seems like it could; you'd only pay to do the reflection once

22:05 danlarkin: hiredman: gen-interface?

22:06 hiredman: danlarkin: nah

22:07 just a macro that generates the proxy form for me

22:09 gnuvince_: ayrnieu: they're actually what I'm dealing with now.

22:15 yangsx: ,(reduce (fn [result entry] (if (even? (count entry)) (conj result entry) (conj (butlast result) (concat (last result) entry)))) [] [[1 2] [3 4] [6 7]])

22:15 clojurebot: [[1 2] [3 4] [6 7]]

22:16 yangsx: ,(reduce (fn [result entry] (if (even? (count entry)) (conj result entry) (conj (butlast result) (concat (last result) entry)))) [] [[1 2] [3 4 5] [6 7]])

22:16 clojurebot: ([6 7] (1 2 3 4 5))

22:16 yangsx: Can anyone help me understand the difference between the above two?

22:18 The second result is unexpected to me.

22:20 Is it a bug with reduce or butlast, or am I doing something wrong?

22:20 Chouser: I'll look at it

22:20 ayrnieu: ,(concat [1 2] [3 4])

22:20 clojurebot: (1 2 3 4)

22:21 ayrnieu: ,(vec (concat [1 2] [3 4]))

22:21 clojurebot: [1 2 3 4]

22:23 Chouser: oh, were you expecting butlast to return a vector?

22:25 yangsx: Chouser: yes, but I may be wrong?

22:25 Chouser: ,(butlast [1 2 3])

22:25 clojurebot: (1 2)

22:26 Chouser: butlast returns a seq

22:28 you can pour it back into a vector using 'vec', as perhaps ayrnieu was demonstrating

22:31 yangsx: Thanks, it seems I have to pay for the seq interface :) and that's not the first time I forgot it.

22:31 ricree: proxy returns a new instance, right?

22:31 Chouser: ricree: yes

22:31 yangsx: you may be interested in subvec

22:32 lisppaste8: ayrnieu pasted "qt5 - but the style bothers me." at http://paste.lisp.org/display/74762

22:33 ayrnieu: so (blocks) returns a new QWidget each time, but they bear no relation to each other as the Java example has it.

22:33 Chouser: yangsx: or if you're going to do a lot of pushing things onto one end of the collection and pulling them off the other, you might like clojure.lang.PersistentQueue

22:34 ayrnieu: hm. /me &

22:37 yangsx: Thanks, I'll try that if my program is too slow.

22:37 ricree: hehe. nice to know I'm not the only one working through those examples

22:39 hiredman: this mk-interface is proving more difficult then I had hoped

23:06 ricree: is there a way to have a function call in a macro expand without a namespace?

23:06 gnuvince_: Don't use `?

23:07 dnolen_: ricree: what are you trying to do?

23:08 cooldude127: ricree: use ~'blah

23:08 hiredman: lisppaste8: url?

23:08 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

23:09 cooldude127: ricree: actually, that might not work in your case

23:09 lisppaste8: hiredman pasted "mk-interface" at http://paste.lisp.org/display/74764

23:10 hiredman: it can end up being just as verbose as proxy

23:11 ricree: I'm trying to write a macro that lets you use an anonymous function as the callback for a qt connect call. I'm doing it by using proxy on the base object class and then calling a function from proxy's return value

23:11 lisppaste8: ricree pasted "connect macro" at http://paste.lisp.org/display/74765

23:11 hiredman: but if it is a single method interface...

23:11 still some issues

23:12 ayrnieu: ,(doc connect)

23:12 clojurebot: java.lang.Exception: Unable to resolve var: connect in this context

23:14 ricree: clojurebot seems to be having trouble tonight. I don't think I've seen even half of the calls to it succeed

23:14 hiredman: clojurebot: give more is <reply>please don't just say it doesn't work, exceptions are not just noise, so please pastbin code+the exception it generates

23:14 clojurebot: Alles klar

23:14 hiredman: ~give me more

23:14 clojurebot: Pardon?

23:14 hiredman: clojurebot: bite me

23:14 clojurebot: Huh?

23:14 hiredman: ~give more

23:14 clojurebot: please don't just say it doesn't work, exceptions are not just noise, so please pastbin code+the exception it generates

23:15 ayrnieu: ricree, it isn't having problems.

23:18 hiredman: ,(loop [] (recur))

23:18 clojurebot: Execution Timed Out

23:18 hiredman: xD

23:28 eyeris_: I am writing fact tests for clojureql. clojureql uses a keyword ::AnyDB. I want to pass that to a function from my test module. If I use ::AnyDB it resolves it to my namespace, as I'd expect. I've require'd the clojureql namespace as sql. When I try sql/:AnyDB I get the error: No such var sql/:AnyDB. How can I use :AnyDB from outside the clojureql module?

23:29 hiredman: eyeris_: :sql/AnyDB

23:29 ,::AnyDB

23:29 clojurebot: :clojure.core/AnyDB

23:29 eyeris_: Ahh!

23:29 That makes sense, sort of :)

23:30 hiredman: weird that that ends up in clojure.core

23:30 ayrnieu: ,*ns*

23:30 clojurebot: #<Namespace sandbox>

23:30 hiredman: hmmm

23:33 eyeris_: The multi-method still dispatches on :dk.bestinclass.clojureql/AnyDB though

23:33 What is strange is that it doesn't respect the alias of :sql/AnyDB

23:34 hiredman: sql is just an alias

23:35 eyeris_: Right, I know.

23:35 hiredman: ,(doc alias)

23:35 clojurebot: "([alias namespace-sym]); Add an alias in the current namespace to another namespace. Arguments are two symbols: the alias to be used, and the symbolic name of the target namespace. Use :as in the ns macro in preference to calling this directly."

23:36 eyeris_: What I'm saying is that, since clojure knows sql is an alias for dk.bestinclass.clojureql, it should be able to resolve :sql/AnyDB as :dk.bestinclass.clojureql/AnyDB before passing it to the multi-method.

23:36 hiredman: uh

23:43 blbrown: my lisp is a little rusty. If I want to apply a function to all members of a sequence. I am assuming I use 'apply'. e.g. (apply println ["a" "b"]) ?

23:44 hiredman: depends

23:44 blbrown: forexample, using 'println' as an example

23:44 hiredman: (apply println ["a" "b"]) is the same as (println "a" "b") if that is what you want

23:46 blbrown: OK, bad example

23:46 hiredman: not really

23:46 (apply + [1 2 3 4]) is the same as (+ 1 2 3 4)

23:46 you may want map

23:47 (map println ["a" "b"]) is like (println "a") (println "b")

23:47 except map is lazy

23:47 so you need to wrap it in doall or dorun

23:48 (if you are running it for side effects)

23:48 there is also doseq

23:48 cooldude127: hiredman: or in the case of println, probably dorun

23:48 oh nvm

23:48 you said that already

23:48 lol

23:48 hiredman: which I rarely use, but is like a foreach loop

23:48 :P

23:49 ,(doseq [i (range 10)] (print i))

23:49 clojurebot: 0123456789

23:50 hiredman: ,(dotimes [i 10] (print i))

23:50 clojurebot: 0123456789

23:52 blbrown: ,(doseq [i ["a" "b"]] (print i))

23:52 clojurebot: ab

Logging service provided by n01se.net