#clojure log - Nov 19 2009

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

0:04 tomoj: well M-x clojure-mode on your erc buffer is not the way to do it :)

0:42 rahulkmr: I have been exploring clojure for past 1 week now. I still have a very fundamental doubt. How do I do standalone .clj files? I can do a "java clojure.lang.Script foo.clj args" but everytime I do this, it does a dynamic compilation and the startup time is high. I run at repl but I don't see how it can be used beyond interactive usage. i can generate java classes but the syntax seems convoluted and it feels like forcing the lang to behave otherwise

0:44 I don't know about the implementation but won't it be beneficial for stand-alone scripts to generate the compiled class file when I run "java clojure.lang.Script foo.clj" first time and look for it's presence thereafter. The dynamic compilation is significantly slow for something even as trivial as "hello world" script. For scripts which are long running, it doesn't matter much as I believe that with type hints and metadata, the app runs quite fast. But

0:46 I was thinking something on the lines of Python. Python generates .pyc(python compiled) files from .py and it decreases the startup time. Since clojure runs on jvm, can't the .class file be produced first time I run the script without the explicit gen-class magic?

0:47 danlarkin: rahulkmr: compiling to java bytecode is a tiny fraction of the delay you're seeing. Most of it is JVM startup time

0:47 which is not a clojure issue, so to say

0:49 rahulkmr: danlarkin: Pardon my ranting, but I was talking more from a clojure end-user point of view. If it's so, why do I see a large diff between some java .class file exec and clojure stand alone script execution? Since the compilation time is low and the majorhead is bringing in jvm in memory, ideally the diff between executing "java Hello" and "java clojure.lang.Script hello.clj" should give me a rough estimate of time taken to dynamically compiling clojure?

0:52 On a related note, how do you do your clojure scripts? When I began, I expected something like I write a .clj script in clojure and some compiler will produce .class file. But now, I see the options are to run standalong clj scripts or AOT. What is the preferred method? My exposure to clojure is quite limited. The only thing I have done with it is read "Programming clojure" and write some toy scripts.

0:54 bryte: I keep an emacs slime session available for scripts, but since I live in emacs this is just as convenient as having a compiled script to run 90% of the time.

0:54 The other 10% I use a different language

0:55 _ato: rahulkmr: there's nailgun, but it's not perfect

0:56 http://martiansoftware.com/nailgun/index.html

0:56 startup time is a problem for all JVM languages :(

0:56 rahulkmr: bryte: That's more of how do you do development. Say I write a clojure code to parse apache log files and want to deploy it on some server. What's the prefered method? In my short stint with clojure, I couldn't get an idea about deploying code

0:56 _ato: Yes, I know about nailgun. I set up vimclojure last night.

0:57 _ato: So, regarding startup time, that looks like it is counter productive for short, repeatedly invoked scripts

0:57 It does make sense for long running tasks on which initial dynamic compilation and jvm overheads can be ignored

1:01 If this topic has been already extensively discussed, can someone point me to the discussion? I can't find anything related on usenet. That may be coz my search terms are generic.

1:03 Regarding nailgun, it seems far from production ready. It's good for development but can I use it for actual deployment?

1:03 bryte: rahulkmr: Well if it can be scheduled within clojure or have clojure parsing a scheduling file that seems like a possibility you could try. I have no experience with nailgun.

1:04 technomancy: there's no one-size-fits-all solution for the problem, but startup time can be improved by specifying the -client JVM on the java command-line if you're on 32-bit

1:04 fanatico: rahulkmr: You can always run put the JVM in client mode, which is tuned for faster startup. What kind of machine are you running it on?

1:04 hah, what technomancy said.

1:04 technomancy: but there's no denying the JVM is bad for stuff that needs to launch quickly. you couldn't write (for instance) git on the JVM.

1:05 michael_teter: Hi. I'm very new to Clojure, and I'm having trouble making multi-line strings work.

1:05 should I be able to say (def x ""

1:06 line1

1:06 line2

1:06 "")

1:06 Or am I misunderstanding?

1:06 danlarkin: michael_teter: you're missing something. Don't double quote the string, just single quote it

1:06 michael_teter: oh!

1:07 Thanks

1:09 rahulkmr: fantico: technomancy: I get it. I am running it on a 32-bit rhel 5 box. So the possible solns are "java -client" (though that limits some resources but it doesn' matter since we are talking short, repeatedly invoked scripts) and nailgun for devel

1:09 fanatico: A lot of the JVMs optimizations are based on the execution profile of the code (hence the name HotSpot), which won't be run if the script dies quickly.

1:10 rahulkmr: bryte: nailgun is a project which aims at making startup times slow by loading jvm in it's ng server module and ng -client communicates with the ng-server to run the programs(something like that). The concept looks novel and good for dev work but they themselves claim about security and other shortcomings on their page

1:12 Further, running nailgun on some production node means running additional setup which I personally don't like. I prefer s/w to be packaged as much as possible with min deps on external entities.

1:14 fanatico: JVM defaults to -server if you have two or more physical processors, and two or more GBs of RAM.

1:14 rahulkmr: fanatico: Yes, I do know about JVM optimization(I used to program java in college:)). I was under the impression that clojure can replace my day to day needs as well as complex projects requiring concurrency. But looks like my Python/Bash isn't going to be replace(not that I was going to do that anyway:)). Anyways, right tool for the right job.

1:18 fanatico: The machine I am running on is uni processor(though, dual core). So, I take it it doesn't qualify the server-class criteria - For Java SE 6, the definition of a server-class machine is one with at least 2 CPUs and at least 2GB of physical memory.

1:19 fanatico: Too bad :-/ As you said before, square peg and a round hole. Clojure isn't an ideal scripting language.

1:21 rahulkmr: fanatico: This is just my dev box. I am not writing any production code yet. The production servers are what situation demands but I am yet to see something with a single cpu:-). Thanks for all the help in exploring clojure.

1:23 technomancy: _ato: lein-clojars isn't downloading from clojars, do I have to install manually?

1:25 _ato: also: I moved deps-if-missing to the shell script, so lein-clojars won't compile anymore... just a heads-up!

1:43 kzar: I'm trying to map a vector with a function that takes 2 parameters. The second parameter is always the same. I could map the vector with a (fn that calls the function and adds the second parameter but is there a better way?

1:43 _ato: ,(map #(+ % 4) [1 2 3])

1:43 clojurebot: (5 6 7)

1:44 _ato: I don't think there's anything better than that if it's the second parameter that's fixed

1:46 kzar: _ato: Cool thanks

1:55 chouser: Clojure on JVM startup time is very annoying for command-line driven scripting tasks.

1:55 Yet another reason to look forward to clojure-in-clojure.

1:56 tomoj: why does the jvm take so long to startup anyway?

1:57 chouser: I really don't know.

1:58 What I do know is that I have no right to be awake at the moment. Good night!

4:26 Kjellski: How can I get some more detailed information about why a proxy implementing an interface is failing its cast to the target interface?

4:27 yason: Kjellski: what do you get, then? Usually I just see an exception that some method wasn't found

4:27 Kjellski: yason: Something like: ... de.haw_hamburg.otto_j$my_sip_listener__1 cannot be cast to javax.sip.SipListener (otto_j.clj:62) ...

4:29 I did a (proxy [SipListener] [config] (method1 ....

4:31 hiredman: whats on line 62?

4:32 Kjellski: hiredman: my call to the funciton defining that proxy...

4:32 hiredman: can you pastebin the code and the exception?

4:32 Kjellski: Sure, sorry...

4:38 hiredman: got it... thanks for forcing the rethink...

4:39 hiredman: *shrug*

4:49 nipra: How can I change the pwd? anything similar to CL *default-pathname-defaults*?

4:50 _ato: nipra: unfortunately you can't change the pwd, it's one of those crazy JVM restrictions :(

4:51 nipra: _ato, hmm... Ok.

4:52 _ato: I think the java folks decided to not allow it due to thread safety issues (if one thread changes the current directory how does that affect the others?)

4:54 nipra: if you're trying to run another program with a different working dirctory from your clojure code, clojure.contrib.shell_out has options for setting it

4:57 nipra: Nested #()s don't work. Is that a limitation because (fn ..) inside #() works.

4:57 _ato, Thanks! will try.

4:57 _ato: that is indeed a limitation of the #() syntax

4:58 nipra: hmm..

4:58 _ato: the reason why it's not allowed is Clojure wouldn't know whether % refers to the arguments for the outer or inner function

4:59 so you have to change one of them to (fn ..) and name the arguments

5:01 nipra: _ato, yes. e.g. (count (filter #(every? (fn [a] (= a :h)) %) (partition 2 1 [:h :t :t :h :h :h]))) :-)

5:01 ,(count (filter #(every? (fn [a] (= a :h)) %) (partition 2 1 [:h :t :t :h :h :h])))

5:01 clojurebot: 2

5:01 nipra: cool

5:01 ,(count (filter #(every? #(= % :h) %) (partition 2 1 [:h :t :t :h :h :h])))

5:01 clojurebot: Nested #()s are not allowed

5:02 _ato: ,(count (filter (partial every? #(= % :h)) (partition 2 1 [:h :t :t :h :h :h])))

5:02 clojurebot: 2

5:03 _ato: ^ another way is to use partial

5:03 nipra: _ato, yeah.. I'm reading Programming Clojure :-)

5:03 It's fun.

5:04 hiredman: ,((comp count filter) (partial every? (partial = :h)) (partition 2 1 [:h :t :t :h :h :h])))

5:04 clojurebot: 2

5:06 AWizzArd: Can I typehint a field in a deftype to be a native long?

5:06 Is #^long doing that?

5:07 hoeck: ,(->> [:h :t :t :h :h :h] (partition 2 1) (filter #(every? #{:h} %)) count)

5:07 clojurebot: 2

5:07 hiredman: AWizzArd: I think so

5:20 nipra: ,(#{:h} :h)

5:20 clojurebot: :h

5:20 AWizzArd: How can I typehint an object as a (Clojure) persistent collection?

5:20 nipra: ,(#{:h} :t)

5:20 clojurebot: nil

5:20 nipra: hmm..

5:20 hiredman: AWizzArd: they all implemented various interfaces

5:20 AWizzArd: What common type do maps (of all kinds), vectors and sets have?

5:21 Chousuke: AWizzArd: IPersistentCollection I think.

5:21 AWizzArd: ok, so it should be one of those

5:21 hiredman: ,(map class [[] {} #{}]

5:21 clojurebot: EOF while reading

5:21 Chousuke: that won't help :P

5:22 hiredman: ,(doc clojure.set/union)

5:22 clojurebot: "([] [s1] [s1 s2] [s1 s2 & sets]); Return a set that is the union of the input sets"

5:22 AWizzArd: ,(instance? clojure.lang.IPersistentCollection clojure.lang.PersistentHashMap)

5:22 clojurebot: false

5:22 hiredman: hmmm

5:22 Chousuke: (map (comp #{clojure.lang.IPersistentCollection} ancestors class) [[] {} #{}])

5:22 ,(map (comp #{clojure.lang.IPersistentCollection} ancestors class) [[] {} #{}])

5:22 clojurebot: (nil nil nil)

5:22 Chousuke: hmm

5:22 AWizzArd: hm

5:22 hiredman: AWizzArd: correct

5:23 a class is not an instance of anything but Class

5:23 Chousuke: I wonder if I'm just remembering the instance name wrong.

5:23 AWizzArd: ah ok, right

5:23 ,(instance? clojure.lang.IPersistentCollection [])

5:23 clojurebot: true

5:23 AWizzArd: ,(instance? clojure.lang.IPersistentCollection {})

5:23 clojurebot: true

5:23 AWizzArd: k, that looks good

5:24 hiredman: ,(apply clojure.set/intersection (map (comp set ancestors class) [[] {} #{}])))

5:24 clojurebot: #{java.lang.Object clojure.lang.IMeta clojure.lang.Obj java.io.Serializable java.lang.Iterable clojure.lang.AFn java.util.concurrent.Callable java.lang.Runnable clojure.lang.IFn :clojure.contrib.generic/any clojure.lang.IEditableCollection clojure.lang.Seqable clojure.lang.Counted clojure.lang.IObj clojure.lang.IPersistentCollection}

5:24 hiredman: ancestors may already return a set

5:24 Chousuke: it does.

5:28 AWizzArd: Let's say I have a (deftype player [name points position]), what foo do I then need so that (foo Player) ==> ::player?

5:28 hiredman: type

5:28 AWizzArd: thx

5:30 hmm, I get a class returned: (type player) ==> user$player__2226

5:32 hiredman: you need to create a player

5:33 (type (player))

5:33 (type (player some-name some-points some-position))

5:34 I assumed that player was the datatype and Player was an instance

5:35 AWizzArd: ah okay, for a concrete player instance this works

5:35 But can one also go there from the deftype itself?

5:36 hiredman: why?

5:37 AWizzArd: I want it, for an index. Saying: instances of the type ::player sit in here.

5:37 Programatically it is more elegant to say: create this index for this certain type vs. creating a dummy instance and get its type

5:38 hiredman: or just use ::player

5:38 AWizzArd: Well yes, maybe this is indeed possible, and if yes this would be the best of course.

5:38 hiredman: maybe?

5:38 the type for the datatype player is ::player

5:39 AWizzArd: I just don't know yet how my code will evolve.

5:39 I think I can directly put ::player into the sources.

5:40 hiredman:

6:32 Licenser: hmm how can I force clojure to wait 1 ms?

6:33 Chousuke: you can force the current thread to wait with Thread/sleep

6:34 but of course that won't affect other threads.

6:36 Kjellski: What does that mean? "Exception in thread "main" java.lang.Exception: namespace 'de.haw-hamburg.otto-j' not found after loading '/de/haw_hamburg/otto_j' "

6:36 Licenser: Chousuke: that is fine, I need it for a remote command to finish

6:40 Chousuke: Kjellski: your file is missing a namespace declaration?

6:40 hoeck: Kjellski: or your ns decl uses underscrores instead of dashes

6:43 Kjellski: okay... I´ll try that..

6:44 Chousuke: Namespaces are actual objects so you need the (ns ...) declaration to create one for Clojure to access after it loads the file

6:47 mrSpec: Where should I paste some clojure code to show it to you?

6:48 Chousuke: lisppaste8: url

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

6:49 mrSpec: thanks

6:54 Licenser: hmm I'm fideeling with clojure & ssh, any thoughts on this: https://gist.github.com/d0facb6eab4bc5c758d1

6:55 lisppaste8: mrSpec pasted "load image" at http://paste.lisp.org/display/90719

6:55 mrSpec: It is my first clojure program, I'd like to change image when user click on the button, Could you tell me why it loads new image, instead of reloading old one?

7:00 djpowell: urgh, clojure is wrapping my checked exceptions

7:01 is there a good reason for that? couldn't it just declare everything to throw Exception? that's what I tend to do with the pesky things

7:02 AWizzArd: technomancy: which branch of your clojure-swank is the newest and supports most features?

7:07 __Joker: Hi there, is there any tutorial apart from clojure.org for a starter who does not know lisp ?

7:07 Licenser: yes a very good one actually

7:07 http://java.ociweb.com/mark/clojure/article.html

7:15 hoeck: mrSpec: because you add the new picture to the frame instead of replacing it

7:16 mrSpec: hoeck: yes :/ but how can I replace it?

7:19 __Joker: Licenser : Thanks :)

7:20 hoeck: mrspec: or just swap the new image into the jpanel, wait a minute, I'm going to annotate your paste

7:20 mrSpec: hoeck: ok, thanks

7:39 lisppaste8: hoeck annotated #90719 "updating the image" at http://paste.lisp.org/display/90719#1

7:41 hoeck: mrSpec: there ^^^, updated the image only and called redraw after doing so to ensure the frame is updated with the new image contents

7:44 mrSpec: hoeck: Thanks!

7:45 btw. do you know some good tutorials about clojure + swing?

7:45 I know lisp, but have some java problems while learning clojure

7:46 hoeck: mrSpec: nothing more than googling clojure + swing, sorry

7:47 fogus_: mrSpec: http://blog.n01se.net/?p=30

7:47 hoeck: mrSpec: but if you basically understand lisp, C-syntax, javadoc and the sun swing tutorials are enough, IMO

7:47 mrSpec: fogus_: o, thanks

7:48 hoeck: mrSpec: personally, I prefer using pivot (http://incubator.apache.org/pivot/ :)

7:48 mrSpec: yeah, I'll start doing swing tutorials

7:49 havent heard, I'll read read about it :)

8:40 esj: guys, is there a way to coerce lazy-seq to return something of a particular datatype ? Specifically, I'm looking to build a lazy list, such that consing happens on the front.

8:41 chouser: technomancy, _ato: I don't know anything about maven repos, but does anything in the maven/lein/clojars stack address trust issues around who has the ability to upload jars in my dependency tree?

8:41 AWizzArd: esj: maybe (into ...) can help, depending on what you need

8:42 chouser: esj: 'cons' always happens on the front, it's 'conj' that's more polymorphic

8:42 esj: AWizzArd, yeah, I tried this and killed the laziness :(

8:42 chouser: yeah, it would.

8:43 you should be able to use 'cons' to add to the left side of a list without touching the laziness of the 'rest' part.

8:44 AWizzArd: ~max people

8:44 clojurebot: max people is 218

8:44 esj: http://pastie.org/705840

8:44 are my paltry attempts

8:46 chouser: esj: 'conj' on a lazy-seq is the same as 'cons'

8:46 esj: are you trying to guarantee it's a lazy seq?

8:46 _ato: chouser: once a groupId is first used with Clojars only the initial uploader (or people they add to the group) can push jars to that group. For me that's enough security.

8:46 esj: definitely want lazy

8:46 _ato: Maven does have a mechanism for signing jars

8:46 I haven't looked into it yet though

8:46 chouser: _ato: ok

8:48 esj: chouser: I'm not getting consing to the LHS, definitely its coming onto the right.

8:49 chouser: ,(cons 'x (range 5))

8:49 clojurebot: (x 0 1 2 3 4)

8:49 cemerick: esj: cons always adds on the left

8:50 ohpauleez: esj: conj may be on the right or the left. Right for vectors, left for lists and seqs I believe

8:50 cemerick: the (into '() some-seq) will just reverse the seq

8:50 ohpauleez: but as said, cons will always push on the LHS

8:50 esj: one sec please

8:50 cemerick: and into is not lazy

8:50 _ato: you can of course also use your own repository if you trust nobody and want to vet everything that goes into. I believe this is what a lot of larger companies that use maven do.

8:52 cark: hello

8:53 ohpauleez: hi

8:53 esj: okie kokie.... here is the behaviour I observe

8:53 http://pastie.org/705852

8:53 adding to my confusion

8:54 i think my clojure has gone dyslexic on me

8:54 cemerick: I don't see anything particularly wrong there

8:55 esj: but the consing is onto the RHS ?

8:55 chouser: esj: 'builder' is recursing in the 'rest' position, so you're adding to the right. This is normal for lazy-seqs.

8:55 _ato: but take 4 takes the first 4 elements from the left

8:56 esj: yeah, this is sensible, and I understand why it builds it that way

8:56 chouser: esj: you want to get a new value each time you call (first aa) ??

8:57 esj: essentially I want the sequence to be built out to the LHS

8:57 do I need to switch the (cons a b) to (cons b a) ?

8:58 _ato: lazy sequences don't build out the LHS

8:58 otherwise (first some-seq) would not actually be the first element

8:58 chouser: esj: did you see my question? I don't think we understand what you're trying to do.

9:00 esj: chouser: sorry. Yes, I saw your question, and understand what you're saying (that each element of the list is defined as some value with the 'rest' on the RHS). Needless to say I'm feeling increasingly silly. What I'm trying to do is build a lazy queue.

9:01 cemerick: well, you've got your queue, you just need to let go of the head as you pull each element off of it with first

9:01 esj: as I'm filling it with a promise I need some way to determine what the most recent value is, as its lazy, there is no (last or (count.

9:01 so thought something that build a LIFO queue would allow me use (first to get that most recent value

9:03 cemerick: esj: a lazy seq + first is a FIFO. You want something like a vector + pop

9:03 esj: cemerick: I have multiple consumers of this queue, so was worried about shortening the queue in case they didn't all see it first.

9:04 chouser: esj: ah, a lazy queue! you have several options.

9:04 esj: cemerick: yes, exactly. So what I'm looking for is the lazy-seq equivalent to build the vector

9:05 as lazy-seq produced an interface (ISeq) I thought i coerce it, hence my initial question.

9:05 chouser: clojure.core/seque, clojure.contrib.seq-utils/fill-queue, and http://clj-me.cgrand.net/2009/11/18/are-pipe-dreams-made-of-promises/

9:06 cemerick: that was a nice piece of work by cgrand

9:06 chouser: hm, if you've got multiple consumers I'm not sure any of those will fit.

9:06 cemerick: yeah. He beautiful code puts my fill-queue to shame.

9:06 His

9:06 ohpauleez: chouser: why not fill-queue?

9:07 happens in another thread, blocks when needed, etc

9:07 esj: chouser: thanks for the links.

9:07 cemerick: chouser: is it a complete replacement for fill-queue? I haven't looked at the latter in some time.

9:07 esj: ohpauleez: I've made fill queue work, but it gives me random java exceptions

9:08 chouser: cemerick: pretty close. fill-queue can have a limited queue size, so the producer can block if the queue is full -- pipe doesn't support that

9:08 esj: probably due to misuse from yours truly

9:08 _ato: esj: how are the multiple consumers supposed to work? should on consumer popping prevent the others from seeing that item or should they all see every item?

9:08 ohpauleez: weird, that's what I would have suggested to us

9:08 esj: _ato: they should all see every item

9:09 _ato: it sounds like pipe might be a fit then

9:09 chouser: cemerick: also pipe has the producer close it manually, fill-queue calls a producer fn and closes it for you when you return from the fn.

9:10 esj: oh! if they all see every item, then all these options are back on the table.

9:10 esj: ohpauleez: if I try to acces the queue before the first element has hit, it doesn't block me, but exceptions.

9:10 chouser: esj: what's your producer look like? 'seque' would be my first option unless it doesn't fit somehow.

9:11 ohpauleez: I see that now, sorry esj. I thought it blocked on consumer not producer. My b

9:11 chouser: fill-queue should block both

9:11 esj: ohpauleez: I think it should do so, but i'm not observing that for the first element. For subsequent elements it is working.

9:11 chouser: esj: may just be a bug. looking now.

9:12 esj: let me pastie what I'm seeing.

9:12 Licenser: if I fire off multiple actions into threads with future the programm will wait untill all are done before exeting right?

9:13 chouser: Licenser: it'll probably wait until you manually shutdown the agent pools

9:13 Licenser: yuck

9:13 chouser: :-)

9:14 Licenser: My thing is I've a set of tasks that can be carried out in paralell since they are entirely unrelated from eachother

9:15 ohpauleez: esj: Also, you can do (Thread/sleep 1000) to save some keystrokes if you like

9:15 Licenser: now I thought just putting them into a future and have the program exit when all are done :P

9:15 chouser: (first (fill-queue (fn [fill] (Thread/sleep 1000) (fill :a))))

9:15 This works for me -- 'first' blocks for a second and then returns :a

9:17 weissj: can someone point me in the right direction w emacs/slime - how do i do paren matching and show different levels of paren in different colors? also if someone knows a color theme that's black bg with not too many widely differing colors?

9:18 the-kenny: weissj: I think there is a script for the color-thing.. just search on emacswiki.

9:19 esj: chouser: here is how I kill it http://pastie.org/705892

9:20 ohpauleez: thanks.

9:20 ohpauleez: esj: np

9:20 esj: you can do that with all static method calls

9:21 the-kenny: weissj: Emacs displays the matching paren to the paren were the cursor is positioned.. I'm googling for a way to color the parents..

9:21 _ato: search for "rainbow parens" and you'll find heaps of stuff

9:22 eg http://lemonodor.com/archives/001207.html

9:22 weissj: the-kenny: i got paren matching turned on now, thanks. _ato thanks, searching

9:24 _ato, not finding much with 'emacs 'rainbow parentheses'" on google. just for vim

9:24 chouser: esj: hm... I don't get an exception there.

9:25 esj: chouser: interesting !

9:26 chouser: it takes 2 seconds because of how run-sum is written

9:30 _ato: weissj: hmmm you're right. there's lots of examples of screenshots and lost of people saying they hacked something together that does it but no code

9:32 there's various different paren modes here but none of them are your classic rainbow parens :/ http://www.emacswiki.org/emacs/ParenthesesAppearance

9:35 ohpauleez: Does anyone in here use rainbow parens?

9:35 chouser: esj: you might try clean re-builds of clojure and contrib. if you still get that exception, maybe paste the whole thing and we can try to figure it out.

9:36 esj: chouser: ok, let me do that, and I'll get back to you all.

9:37 st3fan: how do i explin the difference between a list and a vector to people?

9:38 on one slide :)

9:38 chouser: just say what they're good at.

9:38 lists add/remove on the left. that's it.

9:38 st3fan: lists are more like linked lists while vectors are direct addressable?

9:39 liwp: st3fan: a list is a linked list with O(n) access, a vector is like an array with O(1) access (with some caveats)

9:39 _ato: http://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Singly-linked-list.svg/408px-Singly-linked-list.svg.png

9:39 chouser: vectors add/remove on the right, plus allow fast lookups and updates by numberic index.

9:39 st3fan: yeah that is good enough

9:39 i don't want t complicate things too much for this intro :)

9:39 chouser: make sure you use the word "numberic" It's important. :-P

9:40 liwp: :P

9:40 st3fan: ok :-)

9:40 is numberic a real word?

9:41 the-kenny: "numberic - A spelling mistake often made by those whom can't spell."

9:41 st3fan: yeah

9:41 cgrand: cemerick, chouser: yes, pipe doesn't introduce an inversion of control unlike fill-queue, the producer(s) must close the pipe itself(themselves).

9:41 st3fan: just making sure it is not some lisp term that i need to know haha :)

9:41 * chouser can't spell.

9:48 esj: chouser: fixed ! Thanks.

9:50 chouser: esj: oh good. Just a clean build?

9:51 esj: chouser: yeah, nothing more.

9:51 Maddas: st3fan: the difference between a list and a vector is the difference between a duffel bag and a suitcase

9:51 (ok, an infinitely long duffel bag...)

9:52 (never mind, maybe the analogy is not that good after all)

9:53 esj: Maddas: I've had one or two infinitely heavy duffel bags in my time...

9:53 * Maddas travels light so the constant overhead is more important :)

9:56 Maddas: You know you haven't slept enough when you find yourself entertaining the thought of writing a guide to okasaki's paper explaining all results by analogy to travel equipment.

9:59 djpowell: sounds like the monads as spacesuits tutorial

10:00 the-kenny: ,(contains? [:foo :bar :baz] :foo)

10:00 clojurebot: false

10:00 the-kenny: I think I understood contains? wrong...

10:00 _ato: ,(contains? [:foo :bar :baz] 1)

10:00 clojurebot: true

10:00 _ato: ,(doc contains?)

10:00 clojurebot: "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."

10:00 stuartsierra: the-kenny: contains? works on sets and maps, not sequences

10:00 _ato: it's a very isleadingly named function

10:01 cemerick: dysinger: is this clj-interface by esessoms the jinterface bit you were talking about earlier this week?

10:01 the-kenny: stuartsierra: Okay. Thank you

10:01 djpowell: http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html is the best monads tutorial I've seen

10:01 cemerick: too bad I can't read haskell

10:16 stuartsierra: it's pretty readable even with a casual acquaintance with haskell

10:26 st3fan: so in 1.1, will Datatype+Protocols+MultiMethods be a good replacement for CLOS?

10:26 or at least a pretty powerful way to do OO in Clojure?

10:38 stuartsierra: It's a different approach from CLOS, but should be equally powerful

10:38 It's a different approach from almost every OO design I've seen.

10:44 chouser: protocols and multimethods don't really fit together (yet anyway)

10:45 thay can each make use of the same deftype objects. Maybe that's enough.

10:45 Anything you can do with protocols you can do more slowly with multimethods I think.

10:59 lpetit: chouser: do we have an idea of the performance gain one could have. An example : pprint currently is said to be slow (by its author himself). I guess it's partly due to the use of multimethods when the algorithm may extensively use recursive calls to multimethods. Should we expect a substanticial performance gain by porting it to protocols, that would make to port worth the pain ?

11:00 chouser: that's a pretty comprehensive question.

11:02 I think protocol methods come very close to the speed of a direct java method call. I think rhickey said that protocol methods appear to be faster than the manually created clojure.core polymorphic fns (conj, count, seq, etc.) that we have now.

11:04 lpetit: chouser: wow

11:04 chouser: multimethods on the other hand always call the dispatch function first, then do a (possibly cached) inheritance test that even when cached has to do a map lookup, and then finally a "plain" function call.

11:05 lpetit: ok

11:06 chouser: what I don't know is how much of pprint's time is spent on multimethod dispatch vs. normal algorthmic complexity, nor whether it uses features of multimethods that protocols don't provide, nor whether its speed is critical enough to warrant porting to protocols. :-)

11:09 lpetit: ok, I guess I'll have to ask tom then :)

11:17 AWizzArd: Is APersistentMap the common super type of all clojure maps?

11:17 Will it continue to be? I would like to typehint something as APersistentMap.

11:20 Chousuke: AWizzArd: use IPersistentMap instead

11:21 AWizzArd: ok good

11:28 polypus: is clujure compiled to bytecode directly, or first translated to java which is then compiled to bytecode? just curious.

11:28 AWizzArd: directly

11:28 polypus: by clojure i mean user programs

11:28 AWizzArd: also

11:29 polypus: thx

11:30 AWizzArd: What happens when I typehint a slot S of a deftype T and then *not* store instances of S in instances of T?

11:30 stuartsierra: an exception

11:31 oh, with deftype, don't know

11:31 but it should throw an exception

11:31 AWizzArd: for me it does throw one if I have (deftype foo [#^int i]). (foo 10) ==> ok, (foo \x) ==> Exception

11:32 but if I use #^clojure.lang.IPersistentMap instead it doesn't complain

11:32 stuartsierra: it probably will complain as soon as you call a function on it

11:33 AWizzArd: (class (:i (foo "hello"))) ==> String

11:33 stuartsierra: eh, maybe not

11:34 AWizzArd: rhickey: should hints in a deftype result in (final) fields that really have this type?

11:39 weissj: can someone help me understand slime/swank. i want to have it start up and read all the clojure source i already have, i tried executing this emacs lisp to change the classpath, restart slime with slime-repl-sayoonara, slime. but the REPL doesn't have any clue about my namespaces.

11:39 http://paste.lisp.org/+1Y0G

11:40 stuartsierra: slime/swank won't load code, just add directories/jars to the classpath

11:41 you still need to require/use the namespaces you want

11:43 weissj: stuartsierra: ok, i still can't require/use them

11:44 Could not locate jon/auto/clojure_ng__init.class or jon/auto/clojure_ng.clj on classpath:

11:44 [Thrown class java.io.FileNotFoundException]

11:44 stuartsierra: Java doesn't support the "~" expansion in paths; that may be a problem also

11:47 weissj: stuartsierra: it does actually seem to expand ~. but my execution of that block of emacs lisp to set the swank classpath doesn't work:

11:47 user> (map #(.getFile %) (-> (ClassLoader/getSystemClassLoader) .getURLs))

11:47 ("/home/weissj/workspace/clojure/clojure-1.1.0-alpha-SNAPSHOT.jar" "/home/weissj/workspace/swank-clojure/src/main/clojure/" "/home/weissj/workspace/swank-clojure/src/main/clojure/" "/home/weissj/workspace/clojure-contrib/clojure-contrib.jar")

11:47 the stuff i added isn't there

11:48 do i have to restart swank separately from slime? or does restarting slime do this

11:48 stuartsierra: you have to restart swank/Clojure/Java to change the classpath

11:48 weissj: stuartsierra: how do i do that within emacs

11:48 stuartsierra: kill the *inferior-lisp* buffer and restart slime

11:49 weissj: ah ok

11:51 the-kenny: Isn't there a function if clojure to programatically add classpaths?

11:51 weissj: sigh, that still didn't load my classpath. i guess executing that block of elisp doesn't do what i want? http://paste.lisp.org/+1Y0G

11:51 chouser: ~add-classpath

11:51 clojurebot: add-classpath is bad, avoid it. I mean it!

11:51 chouser: the-kenny: ^^

11:53 stuartsierra: weissj: I don't know enough about swank-clojure internals to know what you to tell you. I use Maven to manage dependencies and start swank now.

11:53 the-kenny: clojurebot always bashes my suggestions :(

11:55 stuartsierra: the-kenny: it's true, though. add-classpath doesn't really work

12:15 dysinger: cemerick: that clj-interface code on github looks like a copy of the simple code in the google group under "files"

12:16 there isn't really anything more to it.

12:16 I just started from scratch as I didn't need full inter-op

12:28 technomancy: weissj: re-invoke M-x swank-clojure-project to have the classpath updated with new jars put in lib/ etc.

12:28 hiredman: AWizzArd: possibly deftype only cares about primitives

12:28 weissj: technomancy: i'll try that thx

12:29 technomancy: assuming you're using swank-clojure-project to begin with, which you should. =)

12:30 weissj: technomancy: i guess i'm not since emacs can't find that

12:30 the autocomplete gives me only swank-clojure-import

12:30 defn: lol my friend just solved a project euler problem in excel

12:30 esj: no !

12:30 technomancy: weissj: http://github.com/technomancy/swank-clojure/blob/maven/README.md <= install instructions for the latest

12:32 defn: esj: it's true

12:32 and quite funny

12:32 he solved the #11 grid problem with excel

12:33 weissj: technomancy: oh yeah i've seen this, it won't work for me, i have to use an existing project which doesnt' follow their convention. classes are in bin/

12:35 technomancy: that's nutty. you can try symlinking, but otherwise just try to talk them into doing things the right way. =)

12:36 weissj: technomancy: that would involve telling them that i'm using clojure and i'm not doing that :)

12:37 i suppose a symlink

13:05 grammati: #rails

13:05 oops

13:15 cemerick: dysinger: ah, I see your tweet about it now

13:16 and, it's AGPL, which is bizarre. And probably not legit, if it is pulled from a public forum.

13:18 dysinger: cemerick: my thoughts exactly

13:19 I look at the code and it's exactly the same IMO

13:19 just the package was changed and license added

13:19 lame-o

13:19 cemerick: strange

13:20 dysinger: GPL lame - AGPL lamer

13:20 even the (comment code at the bottom is the same

13:20 Licenser: gee and I wonder why I get highlighted :P

13:20 * cemerick waits for the pitchforks ;-)

13:22 cemerick: it was so fortunate that rhickey has managed clojure's license the way he has. Those important early choices...

13:23 dysinger: anyway the jinterface is easy - you don't need that library - just the jinterface docs from erlang. It's easy.

13:23 the jar file comes with erlang

13:23 cemerick: yeah, I just noticed the name, and thought for a moment a collaborator of yours had pushed out whatever you're working on

13:24 dysinger: what I am doing is pushing strings from clojure through erlang to another clojure repl

13:24 so I don't need all the other conversions.

13:57 jweiss: technomancy: "You can also start the server directly from the "java" command-line launcher if you use "swank.swank" as your main class." i am not sure waht launcher you're referring to, i don't think you mean just plain java

14:03 dysinger: jweiss: it means put a manifest in your jar with the main class being swank.swank then launching your jar with java -jar XXXX.jar

14:03 jweiss: dysinger: except there is no swank.swank class, just swank.swank.clj.

14:05 dysinger: there is

14:06 Tim-Dysingers-MacBook-Pro:~ tim$ cd src/swank-clojure/

14:06 Tim-Dysingers-MacBook-Pro:swank-clojure tim$ ls target/classes/swank/swank.class

14:06 target/classes/swank/swank.class

14:06 Tim-Dysingers-MacBook-Pro:swank-clojure tim$

14:06 KirinDave: dysinger: Trying to get swank-clojure working?

14:07 jweiss: dysinger: not for me

14:07 [weissj@hiredgoons jon-2.0]$ find /home/weissj/workspace/swank-clojure/target/classes/ -name "*swank.class"

14:07 [weissj@hiredgoons jon-2.0]$

14:07 dysinger: you have to compile it.

14:07 mvn compile

14:07 KirinDave: it's been working for a long time (swank)

14:07 jweiss: dysinger: doesn't mvn install do the compile? i got a jar file and classes

14:08 KirinDave: Ahh you're helping someone else.

14:08 dysinger: what are you trying to do jweiss ?

14:08 (the end goal)

14:09 jweiss: dysinger: i went down this path because i couldn't get swank to use the right classpath from inside emacs, so i'm trying to start swank myself with the right classpath

14:09 KirinDave: jweiss: There is a simple variable to setq.

14:10 dysinger: step 1 - install swank-clojure, clojure-mode from elpa, step 2 - M-x swank-clojure-project

14:11 jweiss: dysinger: that will NOT work for me. i have 2 separate eclipse projects, one depends on the other. swank-clojure-project cannot work for me unless i start writing mvn scrpits, which i'm not going to do.

14:12 dysinger: jweiss: what build system?

14:12 oh you just said "no maven"

14:12 jweiss: dysinger: right :)

14:12 dysinger: so you just have eclipse with IDE project dependencies ?

14:12 jweiss: dysinger: 2 projects each with their own /lib and /classes

14:13 the 2nd proj is a dep of the first

14:13 that's why i wanted to just set the classpath, start swank via cmdline and be done w it

14:14 but somehow my build of it doesn't have the main class

14:14 dysinger: I stopped using eclipse 5 years ago so I'm not sure how to help. You need all your libs and classes in the classpath + swank and then you can run swank.swank as a main clj script/class

14:15 jweiss: dysinger: like i showed you, swank.swank.class is not there

14:16 not sure why

14:19 dysinger: i think my mistake was following this: http://riddell.us/tutorial/slime_swank/slime_swank.html

14:20 dysinger: where are you getting your swank from ?

14:20 jweiss: that uses someone else's

14:20 i didn't realize that until just now

14:20 so i'm starting over

14:21 * technomancy really needs to update his blog post about swank-clojure and send out a message to everyone who has a "using swank-clojure" blog post on the first page of google hits

14:23 jweiss: sorry for the confusion :(

14:25 dysinger: jweiss: it does work

14:25 Tim-Dysingers-MacBook-Pro:swank-clojure tim$ java -cp target/dependency:target/classes swank.swank

14:25 clojure.core=> Connection opened on local port 4005

14:25 #<ServerSocket ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=4005]>

14:25 You can also just put (swank! 4005) in your code

14:25 jweiss: dysinger: yeah, i believe you, i was cloning the wrong git repo

14:27 dysinger: ok NOW i'm back on track. much easier when you have the right repo :)

14:27 dysinger: then in emacs it's M-x slime-connect

14:43 jweiss: dysinger: ok i think i'm almost there. i think i'll try the (setq swank-clojure-classpath

14:43 but what's the format? a list, or a string with : separators, or what

14:43 dysinger: that's the hard ay

14:43 way

14:43 M-x swank-clojure-project

14:43 sets it on the fly

14:43 jweiss: dysinger: i wish that would work but i have those 2 eclipse projects with their own jars

14:43 dysinger: oh but you don't have a build system that works across your two projects

14:44 jweiss: i'd rather just save a snippet of elisp and just exec it when i need to

14:44 dysinger: M-x customize-group swank

14:44 then save it.

14:44 actually M-x customize-group swank-clojure

14:44 sorry

14:46 jweiss: dysinger: but this will permanently alter the cp so that i have to change it again for any other project

14:46 i don't want that

14:46 i'd rather store some elisp with my project and exec it when i am working w it in emacs

14:46 technomancy: jweiss: incanter has something like that; you could use it as an example

14:59 jkkramer: technomancy: with lein, in project.clj, if your project name has multiple words, is there a "correct" separator? I used a dash (defproject foo-bar ...), and `lein jar` generated a file like foo-bar.jar, which is different from how .clj files are named (with underscore). not sure if it matters.

15:00 scgilardi: the underscore is important for files within classpath (under the classpath roots). Jar files are classpath roots so they don't need to follow that convention.

15:01 jkkramer: ok

15:01 so hyphenation is probably fine then

15:03 technomancy: jkkramer: that's correct

15:09 liebke: technomancy: If I want to upload all of Incanter's dependencies to clojars.org using Leiningen, do I need to create a project for each using defproject?

15:11 _ato: liebke: some of them will probably already be in maven central, eg: http://mvnrepository.com/artifact/colt/colt

15:12 liebke: I actually need parallelcolt, and a bunch of other things

15:12 technomancy: liebke: yeah, you can search jarvana.com for them; the majority should be uploaded to central already

15:12 liebke: okay, let me check

15:13 _ato: liebke: _mst's already uploaded the latest JFreeChart to clojars: http://clojars.org/search?q=jfreechart

15:13 technomancy: (jarvana is like mvnrepository search except with better than 50% uptime)

15:13 _ato: but other than that, yeah you can make a project.clj for them and generate a pom with "lein pom" and then scp it along with the jar to clojars@clojars.org:

15:14 liebke: okay, that's what I'll need to do with more than a few of them

15:14 _ato: I recommend putting jars written by something else that you've uploaded under a person group, so define them with something like (defproject org.clojars.username/parallelcolt ...)

15:14 _mst: liebke: it's sickenly simple to do :)

15:15 (I'm coining "sickening simple" as the unofficial slogan of clojars :)

15:15 _ato: that's so that if they do get uploaded to maven central at some point, there won't be any confusion about which is the official version

15:16 ugh.. I can't type this morning. s/something else/someone else/ s/person group/personal grouop/

15:16 liebke: Yeah, I wanted to avoid the naming confusion too, although I wanted to upload the dependencies under the incanter name space instead of org.clojars.liebke.

15:18 kzar: So I've fucked up my recursion logic somewhere causing stack overflows. I'm trying to debug what's going on so I chucked a println at the start of the problem function. Nothing gets printed though, I would have expected thousands of lines?

15:18 _ato: liebke: that's fine

15:18 scgilardi: try (flush) after your println

15:18 liebke: okay, as long as you're okay with it

15:19 kzar: scgilardi: Good idea, didn't help though :(

15:22 hiredman: println should, unless you are doing something weird, flush

15:22 if you are using println, print is a different story

15:22 kzar: are you doing this via slime?

15:22 kzar: hiredman: Yea

15:23 jweiss: technomancy: i think i am almost there. i got (setq swank-clojure-extra-classpaths

15:23 (append (swank-clojure-default-classpath) (list "blah" "blah1")))

15:23 to load all my java deps. but the clojure sources aren't there. does that need to be a separate variable?

15:24 hiredman: kzar: you will need to consult someone who uses slime (not me) but slime from what I have been able to gather from people in the channel looking for help has some weird io wiring

15:24 jweiss: ie, swank-clojure-library-paths ?

15:24 technomancy: jweiss: swank-clojure-default-classpath should include ~/.swank-clojure/clojure.jar etc., so if that's included it might be enough

15:24 kzar: hiredman: Oh that sounds like a pain in the arse

15:25 _mst: usually I find (do (.println System/err "foo") (.flush System/err)) has a better chance of not being grabbed by slime

15:25 jweiss: technomancy: what i mean is, i included my clojure sources (in my own project), but on the repl, it doesn't see them. it does see all the java libs.

15:25 kzar: hiredman: Thanks for the warning, hmm I'll ask "googly" as my roomate calls it

15:25 _mst: (such output should land in your *inferior-lisp* buffer)

15:26 technomancy: jweiss: depends on what "blah" "blah1" etc. is replaced with I guess? is your clojure project's src/ directory in there?

15:26 jweiss: technomancy: correct

15:26 "/home/weissj/workspace/automatjon/jon-2.0/src/

15:27 technomancy: but when i start typing (use 'j then TAB, no autocomplete, if i type out the ns name, and finish the use, there's no ns-publics there

15:28 technomancy: autocomplete only works on code that's already loaded.

15:28 kzar: _mst: Oo thanks

15:28 jweiss: technomancy: how do i load all that code?

15:28 technomancy: jweiss: use or require

15:29 wait, so you called use on it, but the ns is empty?

15:29 that doesn't sound like a swank problem

15:30 jweiss: technomancy: ah, i see, when i tried the use command, i fat-fingered the name. so your explanation about autocomplete means everything is working. thanks.

15:30 technomancy: cool

15:32 kzar: _mst: Is there a way of stopping code that's running if it doesn't cause a stack overflow? C-g doesnt' seem to work

15:32 _mst: does C-c c-b do anything for you? It's been a while since I upgraded my slime/swank-clojure

15:33 kzar: _mst: yea that worked :) thanks

15:34 ordnungswidrig: does anybody now which is a working clojure/clojure-swank/slime-combination? I'm somewhat lost.

15:35 technomancy: ordnungswidrig: go with what's on elpa; install instructions here: http://github.com/technomancy/swank-clojure/blob/maven/README.md

15:36 ordnungswidrig: technomancy: no branch of slime needed?

15:36 technomancy: ordnungswidrig: not if you use elpa

15:37 ordnungswidrig: technomancy: and debian unstable slime works?

15:38 technomancy: btw. is clojure-test-mode working/usable/needed?

15:38 technomancy: ordnungswidrig: oh, I don't know about slime from apt-get. I think if you use elpa it will have higher-priority though.

15:38 ordnungswidrig: ok

15:38 technomancy: clojure-test-mode works for me... that's all I will say.

15:38 it might be dependent on project layout

15:39 gravity: technomancy: kudos for lein! It's exactly what I've been wanting!

15:49 kotarak: Could someone reproduce the problem I have with defprotocol and def? http://tinyurl.com/yhqmvud

15:50 technomancy: where does the name leiningen come from? I know a village "Altleiningen" ("Old Leiningen")

15:50 But I somehow don't believe, that that's related. ;)

15:51 the-kenny: There's a town in Germany called "Leiningen"

15:51 kotarak: As is above mentioned village.

15:51 polypus: Leiningen vs the ants

15:53 _ato: http://en.wikipedia.org/wiki/Leiningen_Versus_the_Ants

15:54 polypus: a short story. http://en.wikipedia.org/wiki/Leiningen_Versus_the_Ants

15:55 was just reading about it this morning

16:01 spuz: _ato: just saw clojars, looks very nice :)

16:01 also good job on squeezing another pun out of Clojure :)

16:02 I'd like to know though, where are the libraries hosted, and can we rely on them always being there?

16:03 kotarak: I believe Alex does this on spare time, no?

16:03 kzar: I wish we could get closure on these puns

16:03 hiredman: http://daeken.com/designing-a-net-computer <-- ho hum, lisp machine

16:10 _ato: spuz: they're hosted on a Linode.com VPS which in my experience so far has very good uptime

16:10 liebke: technomancy: I've got one java class that needs to be compiled first in Incanter, can I specify that in Leiningen?

16:10 _ato: if the repository grows in size substantially I'll probably move them to S3

16:11 spuz: _ato: what about bandwidth and storage costs?

16:13 _ato: spuz: there's a soft 200 GB a month for bandwidth which I think should be fine unless the Clojure community suddenly gets much larger, again if it becomes a problem I'll move to S3. If it starts becoming really expensive (and it'd take a *lot* of traffic for that) I'll probably ask if anyone wants to sponsor it

16:13 spuz: _ato: sounds good :)

16:19 kzar: so (if '() true false) returns true, what's the best way to test if a sequence is empty?

16:20 danlarkin: call seq on it

16:20 froog: ,(empty? '())

16:20 clojurebot: true

16:20 Chousuke: using seq is often more idiomatic though.

16:21 Maddas: ,(if (seq '()) true false)

16:21 clojurebot: false

16:22 kzar: ,(doc "seq")

16:22 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.Symbol

16:22 kzar: ,(doc seq)

16:22 clojurebot: "([coll]); Returns a seq on the collection. If the collection is empty, returns nil. (seq nil) returns nil. seq also works on Strings, native Java arrays (of reference types) and any objects that implement Iterable."

16:23 kzar: I'm unclear what it meens by "Returns a seq on the collection", what's the difference between a seq and a collection?

16:23 danlarkin: laziness is your issue

16:23 Chousuke: a seq is just a view on a collection

16:24 kzar: danlarkin: always has been

16:24 danlarkin: :)

16:24 lazy evaluation, I mean

16:24 kotarak: kzar: a seq is an abstract view on the collection.

16:25 kzar: so seqs can be infinite, eg. (iterate inc 0)

16:25 kzar: seq and lazy sequence are interchangable?

16:26 patrkris: cgrand: hey. any idea why (html-resource "test.html") would give NullPointerException with enlive?

16:29 danlarkin: kzar: no

16:30 you can't test a lazy seq for truth though

16:30 because in order to test it, you have to evaluate it, and then that breaks the rules of keeping it lazy

16:30 that is my understanding

16:30 fanatico: kzar: http://clojure.org/lazier explains the new model.

16:34 kzar: thanks I'll read that

16:36 solussd: when extending a class in the (ns macro using (:genclass :extend), do I specify the parent class like this? org.something.package.theclass ? or do I need to :import it first?

16:38 liebke: Looking through the source for Leiningen, it doesn't appear to be able to compile Java classes in a project yet, can anybody confirm this?

16:39 kotarak: solussd: org.something.... you have to qualify everything not in java.lang.

16:42 solussd: thanks

16:48 ordnungswidrig: If have a complex decision tree which shall be parametrized by functions that each represent a simple decision and basically return true/false. How would you model it? A map of functions, multimethod or, now new protocols?

17:06 jweiss: anyone know if there's context help in the source editor for clojure-mode or is that only for swank

17:06 (emacs)

17:07 ordnungswidrig: jweiss: context help regarding what exactly? Doesn't C-h help you?

17:08 jweiss: ordnungswidrig: i mean like tab completion for vars defined at least in this file

17:08 or say, classes in the classpath if i'm doing java interop

17:12 ordnungswidrig: jweiss: I think you have to refer to swank. completion is usually C-c TAB

17:12 jweiss: ordnungswidrig: aha! thats what i was looking for, thanks

17:13 ordnungswidrig: jweiss: C-h b shows you the key bindings for the buffer

17:15 kzar: Is there any way to get more useful debug information? It's giving me the name of my function that caused there error but not the problem line / call

17:18 cgrand: patrkris: what is your file layout? html-resource (or rather the classloader) does not find the resource named "test.html"

17:19 patrkris: cgrand: i just run the clojure repl in the same directory as the file i'm trying to load

17:19 cgrand: i can get it working by passing ia java.io.FileReader to (html-resource ...)

17:19 fyuryu: anyone wants to test leiningen on Windows?, I translated the bash script to powershell

17:21 works on my machine (tm)

17:21 cgrand: if you want to use (html-resource "test.html") "test.html" have to be on your classpath

17:22 patrkris: cgrand: aaah... sorry, missed that... if I have the directory that contains test.html in the classpath, is that enough?

17:22 cgrand: it should (I have a little doubt since test.html has no "namespace")

17:23 patrkris: cgrand: ok, thanks

17:26 cgrand: patrkris: must go, send a mail to the google group if you have any other problem with enlive.

17:26 patrkris: cgrand: sure, thanks

17:29 scottj: Does enlive work when you need to login to a website or handle stuff with javascript, or is htmlunit still the way to scrape those kinds of sites?

17:35 dnolen: scottj: ? it's just a templating library.

17:38 scottj: I read a blog post that showed how enlive could be used to scrape, and it looked pretty easy for basic websites, but I was wondering if it connected well with something else (i.e. htmlunit) to handle scenarios w/ js and login

17:45 dnolen: scottj: again it's just a general html templating library. It's for manipulating html. it doesn't handle login per se, though it can certainly help in rendering a login page with the right css and js included in the page <head> tag.

17:58 {newbie}: Do you guys think it is good idea to simulate a low level and thus highly mutable environment with clojure

17:58 (I need to make a simulation of virtual memory)

18:01 _ato: {newbie}: sure. You can always just use arrays instead of clojure collections (of course arrays won't be thread safe, but for a low level simulation you probably don't want it to be thread safe as real memory isn't automatically thread safe)

18:02 {newbie}: _ato: the simulation won't be multi threaded of course

18:02 so thread safety is not an issue

18:02 _ato: although if you want a simulation where you cheaply backtrack and trace changes and the like, clojure's vectors might actually be quite handy

18:03 {newbie}: _ato: there wil be no backtrack

18:03 just chaging pages

18:07 kzar: What's the best way to debug problems with clojure code if you use Emacs? It doesn't seem to give you as much information as with SBCL

18:07 fanatico: kzar: http://georgejahad.com/clojure/cljdb.html

18:08 haven't used it yet, though, so hopefully someone here knows it a little better.

18:09 froog: I haven't tried cljdb either yet, but there's a git repo as well: http://github.com/GeorgeJahad/cljdb

18:12 kzar: I was just reading about it, it seemed like I would have to tell it which file has my code and implicitly the file would have to be all neat, up to date and saved. I don't know if that's right but if so it would kind of mess up my way of working. I like to just mess around in a buffer and eval something here n' there while I'm figuring out how stuff is going to fit together

18:14 Hmm I'm giving it a blast anyway

18:22 fyuryu: technomancy: ping

18:28 kzar: Do you know how to add command line arguments to the clojure process that slime starts? I want to specify a port to attach a debugger

18:36 ordnungswidrig: kzar: (setq swank-clojure-extra-vm-args '("-agentlib:jdwp=transport=dt_socket,address=8021,server=y,suspend=n"))

18:43 kzar: ordnungswidrig: That doesn't seem to work :( I checked swank-clojure.el and it seems to use that variable so I don't see the problem

18:44 I evaled that and it set the variable, I killed inferior-lisp and did M-x slime again. It started up but a quick telnet to 8021 said it's closed and I looked at the java process and I don't see those extra arguments

18:46 ordnungswidrig: kzar: hmmm, I remember I had problems with that, too. I switched to staring the process manually or by maven

18:48 kzar: ordnungswidrig: I guess ultimately I will need to start the process with a script because I'm going to use it for webdev. It would be cool to have it all working locally on my laptop though in case I want to play with clojure when I don't have net access

18:48 ordnungswidrig: kzar: Nothing prevents you from having it locally.

18:51 kzar: ordnungswidrig: Oh yea that's true I could have a script to run clojure locally and then connect with slime-connect?

18:52 ordnungswidrig: of course.

18:54 (swank.swank/start-server "/tmp/swank.port" :port 4005 :dont-close true)

18:54 then M-x swank-connect RET localhost RET 4005 RET

18:55 kzar: ordnungswidrig: Cool thanks

19:32 When I google for swank clojure I see two githubs, technomancy's and jochu's. I installed swank from clojurex and I can't figure out which one it uses. How can I figure out which one is being used by clojurex so that I can report a bug?

19:33 cheddar: kzar, did your install do a git clone of the directory?

19:33 if so, you can do a

19:33 git remote -v

19:33 in the directory and it will tell you where it was cloned from

19:34 kzar: cheddar: Cool that worked

19:34 cheddar: Hello clojure peeps. I'm using clojure.lang.Script from the command line and it seems to run everything fine, but never exits. Any ideas about what I might be doing to make it not exit? (I'm hoping this has happened to someone else)

19:37 Chousuke: cheddar: you might need to execute shutdown-agents at the end of your script

19:38 cheddar: ah, so agents will keep the vm alive? I was wondering about that

19:38 I'm using the http.agent stuff from contrib

19:38 so that's most likely what it is

19:40 yup, that seemed to work

19:40 thanks

20:21 quidnunc: How do you use clojar as a user

20:27 cgordon: I'm trying to understand namespaces. Why is it that "in-ns" is recommended for use from the REPL, and not "ns"? I think I understand the difference between the two, but I can't answer that question, so I must be missing something.

20:28 chouser: some of the reasons are philisophical. I think the major techincal reason is that 'ns' brings in all the names from clojure.core, regardless of any earlier 'ns' that may have restricted that.

20:29 'in-ns' doesn't -- it creates the namespace if it doesn't exist, but otherwise only does to it what you specifically request.

20:29 cgordon: hmm, but "ns" would only bring them in for the namespace you specifically switched to

20:30 Chousuke: I think ns redefines any possibly existing namespaces

20:30 chouser: right, but if you were switching to a namespace that had renamed a core function, for example, using 'ns' to switch to it could overwrite things like that.

20:30 cgordon: so maybe you're saying that if I start with "(in-ns 'foo)", then switch to "(in-ns 'user)", then later go back to foo, but accidentally type "(ns foo)", I would inadvertently pull in a bunch of extra stuff?

20:30 chouser: cgordon: right

20:31 cgordon: don't tell rhickey, but sometimes I switch namespaces at the repl using 'ns', just to save a few keystrokes.

20:31 cgordon: aha, that makes a lot of sense

20:31 so it's really a matter of keeping it straight in your head

20:31 :)

20:32 this may be blasphemy, but it feels like Clojure namespaces were designed to be identical to Perl's packages

20:32 they even use the same keywords: use, require

20:34 lisppaste8: kzar pasted "server.clj" at http://paste.lisp.org/display/90761

20:34 kzar annotated #90761 "error" at http://paste.lisp.org/display/90761#1

20:34 kzar: So I'm trying to start clojure with a swank server from a script. If I run clj and type the 4 commands in it works fine. If I save those commands to server.clj and run clj server.clj I get an error "java.lang.IllegalAccessError: Context classloader is not a DynamicClassLoader (server.clj:0)"

20:34 It doesn't seem to make any sense

20:35 chouser: namespaces were designed first with fns like in-ns, import, refer, and load. Lib support was added later to do those things in combinations with things like ns, use, and require.

20:42 cgordon: kzar: seems to be a problem with the (add-classpath...) line

20:43 kzar: cgordon: Yea, but when I run it from clj repl it works fine

20:43 cgordon: if I remove that, and run your script after just setting CLASSPATH (on the command line), it works

20:43 kzar: cgordon: I paste the lines of server.clj into a repl and it works fine but if I run clj server.clj to load it I get that error.

20:44 cgordon: kzar: yep, I got that, and I'm sorry I can't be more help, but I can get the script to work by removing the "add-classpath" line and setting the CLASSPATH on the command line

20:44 I'm looking at the documentation for add-classpath now

20:44 clearly there is something about the REPL that changes its behavior

20:44 kzar: cgordon: I can't remove that line because my clj command doesn't add swank for me so without it I get an error that it doesn't know what swank is

20:45 cgordon: kzar: charles-gordons-computer:~/Projects/clojure cgordon$ CLASSPATH=/Users/cgordon/lisp/clj/swank-clojure/src/main/clojure/ clj-env-dir swank.clj

20:45 Connection opened on local port 4005

20:45 my clj command doesn't add swank either

20:48 kzar: cgordon: I don't understand that last part, what's that?

20:48 cgordon: sorry, that didn't paste very well. That is the command line I used to run your server.clj

20:48 the last bit is the output (which opened a connection)

20:49 (require 'swank.swank)

20:49 (swank.swank/start-server "/tmp/swank.port" :port 4005 :dont-close true)

20:49 that is the server.clj I used

20:51 lisppaste8: cgordon annotated #90761 "source of exception" at http://paste.lisp.org/display/90761#2

20:52 cgordon: kzar: I found the source of the exception in clojure/lang/RT.java

20:52 still trying to understand why it is throwing

20:52 kzar: cgordon: Yea I'm brand new to clojure and I haven't ever done any java so that doesn't mean much to me :(

20:53 cgordon: I tried to emulate your command, I didn't really understand it, is this right?

20:53 CLASSPATH=/Users/kzar/clojure/swank-clojure/src/main/clojure/ clj server.clj

20:53 cgordon: kzar: the add-classpath function is very simple, and just calls out to clojure.lang.RT.addURL, which is doing some Java magic to load the appropriate class file

20:53 kzar: I'm also new to Clojure, and not much of a Java expert :)

20:55 did that work?

20:55 I found the documentation for Thread.getContextClassLoader, but it's greek to me

20:55 http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.html#getContextClassLoader%28%29

20:56 it does say that it depends on the initial context (the parent thread), so that would explain why it works differently under the REPL

20:57 kzar: cgordon: No, setting CLASSPATH doesn't seem to have an effect for me. I can't see any mention of it in the clj bash script either

20:57 cgordon: is your clj bash script overwriting CLASSPATH?

20:57 twbray: Wrote up latest cut at Clojure in Wide Finder: http://www.tbray.org/ongoing/When/200x/2009/11/18/Clojure-Parallel-I-O

20:57 cgordon: can you paste it?

20:58 kzar: cgordon: http://github.com/citizen428/ClojureX/blob/master/clj

20:58 cgordon: It doesn't seem to be

20:59 cgordon: kzar: try changing this "CP=$PWD:$CLOJURE:$JLINE:$CONTRIB" to this "CP=$PWD:$CLOJURE:$JLINE:$CONTRIB:$CLASSPATH"

21:00 kzar: cgordon: Hmm no that doesn't help

21:01 beutdeuce: how do i check if an element is part of a list

21:01 cgordon: twbray: I read your first post on Clojure with a lot of interest. I'm new to Clojure (and Lisp in general), and ran into nearly all the same problems you did (particularly with namespaces!)

21:01 twbray: looking forward to the latest WideFinder; I've been following it since you did one on Erlang

21:02 kzar: hrm, well, I'm not sure what to say. I am using "clj-env-dir", which I got from following these instructions: http://riddell.us/tutorial/clojure/clojure.html

21:02 kzar: cgordon: If I echo $CLASSPATH from the script it's blank. Wierd because if I echo it from the shell before and after I run the script it's not

21:02 cgordon: oh, that is odd

21:04 kzar: maybe cheat and add "CLASSPATH=/Users/kzar/..." at the top of the clj script? Just to see if it works?

21:09 kzar: cgordon: Wow yea that works

21:09 cgordon: kzar: great!

21:09 kzar: I'm completely confused as to why it isn't getting the CLASSPATH from the shell

21:09 kzar: cgordon: Thanks for your help, I'm getting a headache so I'm gona go eat some food... been staring at this for hours now

21:10 cgordon: kzar: no problem :)

21:10 kzar: cgordon: I'm going to figure that out and then learn how to commit patches to git and try and get your change added to clojurex

21:12 cgordon: Oh whoops I'm supposed to set the classpath in a .clojure file. I'll have a look at it later anyway http://mark.reid.name/sap/setting-up-clojure.html

21:12 cgordon: thanks for the help, it was starting to really piss me off heh

21:13 cgordon: kzar: yeah, that was a weird one

21:34 beutdeuce: can someone please help me figure out why am i getting an out of bounds when i shouldn't? thanks: http://pastie.org/707046

21:39 _mst: beutdeuce: your 'recur' form isn't dependent on the above condition--it runs no matter what

21:39 beutdeuce: oh right

21:40 thanks

21:40 _mst: no problem

21:44 beutdeuce: hmm, where would i place the tail recursion call then?

21:45 well, i could use a do block

21:45 _mst: I think you want the recur form to be in the 'else' position of your if

21:46 and then make the 'cond' the second argument of your recur

21:46 sort of turning the whole thing inside out

21:47 beutdeuce: hmm, right, that makes more sense

21:47 _mst: I'm also not sure the 'contains?' on lists will quite do what you want; you might be better off using sets like #{"man" "ate"} instead

21:48 beutdeuce: k, i will try that. Why though? just curious

21:49 _mst: ,(contains? '("hello" "there" "world") "hello")

21:49 clojurebot: false

21:50 beutdeuce: hmm, why is that?

21:50 chouser: 'contains?' is for keys in an associative collection.

21:50 beutdeuce: oh,k

21:50 chouser: ,(contains? {:h 1, :n 2} :n)

21:50 clojurebot: true

21:50 beutdeuce: what would be the equivalent of nth for sets?

21:51 _mst: ,(contains? #{"a" "the" "an"} "the")

21:51 clojurebot: true

21:51 _mst: or just:

21:51 ,(#{"a" "the" "an"} "the")

21:51 clojurebot: "the"

21:51 chouser: hash sets don't keep things in any particular order, but you can walk through a seq on a set if you want to

21:52 ,(nth (seq #{5 6 7}) 1)

21:52 clojurebot: 6

21:53 beutdeuce: hm, k

21:54 hmm, *command-line-args* returns a list. How do i make a set of the (rest) of the list?

21:54 if i try to do that, i get a set of a list of the rest

21:54 i just want a set of the rest

21:55 chouser: ,(set (next '(1 2 3 4)))

21:55 clojurebot: #{2 3 4}

21:55 beutdeuce: ah, k, so i use next. i assume thats the set equiavalent of rest?

21:57 hmm, that doesnt retain the order of the elements which is important

21:57 chouser: no, rest and next both operate on seqs.

21:57 beutdeuce: no, sets don't maintain order

21:58 _mst: ah hang on, so don't want to treat your user input as a set anyway, do you? I meant to suggest treating your article/verb/noun lists as sets

21:59 beutdeuce: oh, ok

21:59 _mst: since all you ever want to do is test whether a given word appears in one of those lists

21:59 beutdeuce: yes

21:59 mhm

21:59 Qvintvs: based on this code: http://pastebin.com/m6c8cb97f, what does it seem like the result of (myparse [:subject]) to be. I'm trying to get it to be [:subject], but I keep getting nil.

22:01 beutdeuce: Qvintvs: lol, hey

22:01 Qvintvs: beutdeuce, hehe, hey

22:29 are people as lost as i am or is no one here? :/

22:33 djork: what is the difference between a map entry and a vector with two entries

22:35 since they pr the same output

22:35 chouser: Qvintvs: only the final expression in a 'when' clause is returned

22:35 _ato: djork: they're different java classes, I haven't tried it but I assume you can't use assoc and such on a map entry

22:35 chouser: ,(when true :this :that :the :other)

22:35 clojurebot: :other

22:36 chouser: hm. I'd never tried before, but it appears you *can* assoc on a mapentry.

22:36 you just get a vector back.

22:37 Qvintvs: chouser, hm, how could I rearrange that so that the result of the (if (= (first list) :subject)... statement is returned?

22:38 chouser: Qvintvs: 'cond' might work well for you here.

22:41 Qvintvs: chouser, i'll look into cond, but what's the issue with this version: http://pastebin.com/m1387a91b ?

22:43 lisppaste8: kzar annotated #90761 "Solution" at http://paste.lisp.org/display/90761#3

22:50 chouser: Qvintvs: what's the final expression of the 'when'?

22:50 Qvintvs: chouser, huh? I don't see a when in that version

22:51 chouser: oh. right, sorry.

22:51 same thing applies to fns

22:52 the function returns the value of the final expression in its body.

22:52 Qvintvs: ahhh, so it will always return the result of (if (empty? list) nil) ?

22:52 chouser: exactly

22:52 which, if the list is empty, will be nil. Otherwise, it will be nil.

22:52 Qvintvs: but if I use cond, it will return the value of the expression following the first test case that is true?

22:53 chouser: yes

22:57 Qvintvs: chouser, thx, got it working now :)

23:02 chouser: great

23:04 danlarkin: _ato: what's the state of the art on lein/clojars integration, does the plugin still exist?

23:04 I can't find it now

23:32 piccolino: This is probably a dumb question, but is there some function that will let you take a file or string that contains Clojure code, and parse it into its data structure form? (like so you could pass it to eval)?

23:32 danlarkin: (read-string (slurp "/path/to/file"))

23:33 piccolino: Oh awesome, thanks.

23:33 I was looking in clojure.org/evaluation and didn't see anything.

23:35 tomoj: are you really just passing it to eval?

23:35 piccolino: No, I wanna mess with it first.

23:36 tomoj: ah

23:49 technomancy: _ato: (and whoever else cares) http://groups.google.com/group/leiningen <= go join!

23:49 kzar: I've got Jswat attached to my clojure process and emacs connected via swank but when I eval dodgy code nothing happens in jswat and emacs displays the same info as before

23:52 oo looks snazzy

23:55 _ato: technomancy: ooh, ooh, I'm in. :)

23:55 technomancy: _ato: there's also a #leiningen channel, but it's just me and danlarkin

23:55 cgordon: stupid question: is it possible to have a "var" that isn't bound to a symbol?

23:56 technomancy: cgordon: sure; declare

23:56 cgordon: technomancy: cool, thanks

23:59 hmm, alright, another dumb question: why would I need forward references?

Logging service provided by n01se.net