#clojure log - May 05 2009

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

0:08 ctdean: laters folks, and grats on the v1.0 release

1:37 hiredman: clojurebot: make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive

1:37 clojurebot: Ack. Ack.

1:38 hiredman: er

1:38 nuts

1:38 clojurebot: make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php yet another article about picking c or c++ for performance being naive

1:38 cp2: nuts!

1:38 you're gonna love my nuts

1:39 slap your troubles away

1:39 hiredman: ...

1:39 cp2: what ?

1:39 hiredman: I have to keep pasting urls or I'll never beat lisppaste8

1:40 cp2: heh

1:41 hiredman: interesting article

1:47 hiredman: the comments are also interesting and lively

1:48 cp2: yeah, i read a couple

2:05 replaca: hiredman: did you have better luck with the new json doc?

2:06 hiredman: oh, sorry I have not tried

2:07 yes, it works

2:10 danlarkin: three cheers for clojure-json!

2:13 hiredman: clojurebot: three cheers

2:13 clojurebot: Excuse me?

2:14 hiredman: clojurebot: three cheers is <reply>hip hip, hooray! hip hip, hooray! hip hip, hooray!

2:14 clojurebot: 'Sea, mhuise.

2:14 hiredman: clojurebot: three cheers for clojure-json

2:14 clojurebot: hip hip, hooray! hip hip, hooray! hip hip, hooray!

2:29 replaca: ahh, I'd wandered off to fix autodoc bugs.

2:30 Yay, glad to hear it's working.

3:27 jdz: Happy birthday, Clojure!

8:45 Chouser: the value of an agent can change while in a transaction, right?

8:45 rhickey_: Chouser: sure

8:45 Chouser: (dosync (= @foo @foo)) is guaranteed true of foo is a ref, but not if foo is an agent.

8:45 AWizzArd: right

8:46 Chouser: ok, thanks.

8:46 * Chouser uses 'let'

8:46 * AWizzArd also uses let for atoms and agents to make a snapshot and work with that.

10:00 AWizzArd: If I want to retry something that can throw an Exception a few times, how can this be then done idiomatically? Currently I try to recur inside the catch, but that is not allowed.

10:16 __mac: Define "a few times". If it's not many, you could just call the function again instead of using recur?

10:22 tWip: If you're retrying something (I'm guessing IO) so many times that it blows the stack... something is wrong

10:24 AWizzArd: a few times, such as 3

10:24 Trying to connect to a listener, sending an email, whatever.

10:24 __mac: Then just call it regularly would be easiest solution I guess?

10:24 Passing a try count or something like that

10:24 AWizzArd: Probably a macro could be nice here (retry 3 ...) where ... is the body.

10:25 danlarkin_: dotimes

10:26 you could wrap that, possibly

10:26 or look at it, anyway

10:26 __mac: Isn't that always a fixed number of times?

10:31 AWizzArd: Yeah, I would want to break out of the dotimes if the action succeeds.

10:32 cgrand: AWizzArd: what do you want to do if the nth retry fails? propagate the exception?

10:33 AWizzArd: yes

10:37 cgrand: you're right: a macro seems the way to go

10:39 cheating: (defmacro retry [n & body] `(try-or ~(repeat n `(do ~@body))))

10:39 __mac: Look at with-open in core. It does self-recursion with a catch on each level

10:40 AWizzArd: btw, I just discovered an area where Clojure is a bit too static:

10:40 __mac: Or rather a finally but it's the same concept

10:40 AWizzArd: (def x (if-not (resolve 'x) 0 (inc x)))

10:41 when the compiler discovers the (inc x) it will complain that it doesn't know x. Although that part of the code can never be reached as long x isn't bound.

10:42 I guess that is an underlying Java mechanism, which is conservative in its static type checks.

10:42 well, JVM mechanism

10:44 rhickey_: AWizzArd: you expect it not to compile code that might not be reached due to a runtime state?

10:45 AWizzArd: The general mechanism is okay in principle. Anyway, if it were more dynamic here that would result in perfectly correct code.

10:45 rhickey_: Clojure resolves names at compile time - that makes it fast, waiting until runtime would be slow

10:46 AWizzArd: During tests with load-file in the repl it would init the var for the first time, and on reloads have a different strategy.

10:46 Raynes: Well, that was stupid.

10:47 I did this in a Scala console in NetBeans: (1 to 1000000000).foreach(println)

10:47 :\

10:47 AWizzArd: But I understand that compilers are not advanced enough and prefer the case that is easier to implement.

10:48 ... and compiler writers prefer ...

11:00 lisppaste8: __mac pasted "retry macro suggestion" at http://paste.lisp.org/display/79703

11:01 __mac: AWizzArd: Posted retry suggestion :)

11:01 eh I mean "pasted" ofc

11:03 AWizzArd: __mac: looks good

11:04 __mac: It will always run the body once, so n = 1 means one REtry not one try

11:06 That was fun. First clojure code I have written in a long time. Been awfully busy in java land :( hopefully the people around me will soon see the light

11:21 AWizzArd: ,(* 1 2 3, 1 2 3, 1 2 3, 1 2 3, 1 2 3)

11:21 clojurebot: 7776

11:39 AWizzArd: Is there something like (binding [*out* /dev/null] ...) Binding *out* to nil results in a NPC.

12:00 cemerick: AWizzArd: a no-op printwriter is a simple thing

12:05 kadaver_: how do I regex "\\"

12:06 i want to pass \ to split

12:06 , (.split "path\to\file" "\\")

12:06 clojurebot: java.util.regex.PatternSyntaxException: Unexpected internal error near index 1 \ ^

12:06 kadaver_: , (+ 3 4)

12:06 clojurebot: 7

12:06 kadaver_: , (.split "path\to\file" "\")

12:06 clojurebot: EOF while reading string

12:07 kadaver_: , (.split "path\to\file" "/")

12:07 clojurebot: #<String[] [Ljava.lang.String;@d961db>

12:07 kadaver_: , (.split "path/to/file" "/")

12:07 clojurebot: #<String[] [Ljava.lang.String;@1ce49c9>

12:07 drewr: ,(into [] (.split "foo\\bar\\baz" "\\\\"))

12:07 clojurebot: ["foo" "bar" "baz"]

12:07 kadaver_: so i want to do it with backslash

12:07 Chouser: ,(seq (.split #"\\" "foo\\bar"))

12:07 clojurebot: ("foo" "bar")

12:08 drewr: Hm, I'm surprised those both worked.

12:08 kadaver_: how can you do it with reversed args?

12:08 ,(into [] (.split "foo\\bar\\baz" "\\"))

12:08 clojurebot: java.util.regex.PatternSyntaxException: Unexpected internal error near index 1 \ ^

12:08 Chouser: #"" produces a regex.Pattern object, which has a split method

12:08 kadaver_: ,(into [] (.split "foo\\barbaz" "\\"))

12:08 clojurebot: java.util.regex.PatternSyntaxException: Unexpected internal error near index 1 \ ^

12:08 kadaver_: why \\\\?

12:08 drewr: Chouser: Ah, you're right.

12:08 kadaver_: ,(seq (.split #"\\" "foo\\bar"))

12:08 clojurebot: ("foo" "bar")

12:08 kadaver_: ,(seq (.split #"\\" "foo\\bar\\file"))

12:08 clojurebot: ("foo" "bar" "file")

12:09 Chouser: kadaver_: #"" has different quoting rules than "", specifically for this kind of pattern.

12:10 AWizzArd: cemerick: how does a no-op printwriter look like?

12:10 Chouser: in a #"" a backslash and whatever follows it are put directly into the pattern, so the regex engine sees \\ and knows that's a literal backslash.

12:10 AWizzArd: It seems the constructor of those printwriters always need an argument.

12:11 Chouser: in "", a backslash is interpreted by the reader, so \\ becomes a single \ inside the string. But the regex engine interprets \ and whatever follows it, for patterns like \s and \w. So in order to get the regex engine to see \\ you have to say "\\\\"

12:11 it's like emacs. terrible.

12:11 cemerick: AWizzArd: probably just a proxy of java.io.PrintWriter, with overrides of all of the print*/write methods to do nothing.

12:12 AWizzArd: oh, I hoped for a very short solution

12:12 cemerick: maybe *out* could be a writer, which would make things simpler, but IIRC, *out* is a printwriter.

12:12 AWizzArd: (binding [*out* (EmptyWriter.)] ...)

12:12 cemerick: well, that's what it would look like once you write EmptyWriter :-)

12:13 AWizzArd: sure

12:13 Under Linux one can maybe have a (PrintWriter. "/dev/null")?

12:13 But I don't know if Window also has such a null device.

12:13 cemerick: oh, printwriter takes a Writer itself, so it actually is quite easy. Writer only has three abstract methods.

12:14 Holcxjo: DOS had a nul: device..

12:15 chessguy_work: clearly, DOS was the best OS ever

12:16 unlink1: You must never have used Windows 3.11. Far more win than DOS.

12:16 chessguy_work: oh man, i was so mad when windows 3.11 came out

12:16 of course, i was like 8 at the time

12:17 drewr: Chouser: Emacs's regexps quote that way for a reason.

12:17 AWizzArd: It seems that under Windows (binding [*out* (java.io.PrintWriter. "NUL")] (println "Hallo")) does the job.

12:17 cemerick: heh

12:17 just making a no-op writer seems way simpler than worrying about the proper /dev/null device/path/etc

12:18 AWizzArd: cemerick: probably

12:19 at least Apache has it already: http://commons.apache.org/io/apidocs/org/apache/commons/io/output/NullWriter.html

12:20 kadaver_: so anyone want to swap code with me and comment on each otehrs code? I have a 400 LOC mp3player that I'd like to be, well cleaner. it's pretty modular and easy to change but the could is a bit ugly imho.

12:20 chessguy_work: so, i was reading "on lisp" the other day, with all the crazy ` and `, and ,@ stuff. does clojure have that kind of quoting/unquoting for macros?

12:21 AWizzArd: chessguy_work: yes

12:21 chessguy_work: is the syntax the same?

12:21 i can't find a reference for it

12:21 AWizzArd: , is in Clojure ~ and ,@ is in Clojure ~@

12:21 clojurebot: java.lang.Exception: Unable to resolve symbol: is in this context

12:21 AWizzArd: basically they are nearly compatible

12:21 * chessguy_work pats clojurebot on the head

12:22 AWizzArd: anaphoric macros are a little bit different in Clojure

12:22 chessguy_work: how so?

12:22 AWizzArd: the symbol you want to make available in the body must get a ~' in a let

12:22 but the advantage is that Clojure macros are more hygienic by default

12:23 chessguy_work: err, what does hygienic mean? sorry, new to the macro scene. i've heard that word before, but never seen it defined

12:23 AWizzArd: In CL it could be `(let ((it ,object)) ,@body) while in Clojure it should be `(let [~'it ~object] ~@body)

12:24 It means that Clojure would complain when you do `(let [something ~object] ...)

12:24 So, you can not accidently overwrite vars

12:24 chessguy_work: oh so variable capture is a little harder to do by accident?

12:24 AWizzArd: exactly

12:24 You must gensym them first. In Clojure this is easier. Just append a hash.

12:25 `(let [my-var# ~object] ... (println my-var#) ...)

12:25 unlink1: Anyone know of a Java syntax highlighter for Clojure which has terminal output?

12:26 Sort of like pygments.

12:27 cgrand: unlink1: pygments on Jython :-)

12:28 unlink1: Good point. I'll just use python and unix pipes.

12:28 i.e. pygmentize

12:28 orero: hi. I'm trying to understand the purpose of clojure.contrib. can someone tell me what's the difference between contrib and any other third-party libraries?

12:29 unlink1: contrib is a collection of semi-officially sanctioned libraries which are candidates for inclusion in core

12:29 orero: unlink1: does that mean most of contrib will end up in the core someday?

12:30 AWizzArd: orero: no

12:30 replaca: orero: look here for an overview: http://code.google.com/p/clojure-contrib/wiki/OverviewOfContrib

12:30 chessguy_work: i think what it means is that they are "candidated for inclusion in core"

12:30 just a guess

12:31 AWizzArd: A limited set of parts of contrib will go into core, maybe it will be like this for many years.

12:31 But typically those tools will stay in Contrib.

12:31 kadaver_: java.sql.SQLException: Failed to start database 'C:/clojure/progs/mp3player/mp3.db', see the next exception for details. (NO_SOURCE_FILE:0)

12:31 ok how do I see the enxt exception?

12:32 orero: AWizzArd: was there anything in contrib that ever moved to core?

12:33 hiredman: yes

12:33 orero: so essentially, contrib is like any third-party library without the licensing issues if Rich wants to take it and put in the core, right?

12:34 danlarkin: and it's sorrrrrt of like a standard library

12:35 orero: ok, thanks.

12:36 chessguy_work: ,users

12:36 clojurebot: java.lang.Exception: Unable to resolve symbol: users in this context

12:37 chessguy_work: i'd be curious to track the number of users in this channel. i bet it's increasing rapidly

12:38 danlarkin: it was, then it slowed down a month or two ago

12:38 chessguy_work: interesting, wonder why that is

12:40 hiredman: ~max users

12:40 clojurebot: Huh?

12:40 hiredman: ~max people

12:40 clojurebot: max people is 164

12:40 unlink1: clojure -e "(source $1)" | pygmentize -l clojure

12:41 danlarkin: very nice

12:42 unlink1: A useful companion to (if (= (count *command-line-args*) 0) (println "usage: clojuredoc name") (let [arg (first *command-line-args*)] (let [v (resolve (symbol arg))] (if v (print-doc v) (println (format "no documentation found for '%s'" arg))))))

12:42 t345: I like it that Clojure naturally parses XML and possibly also JSON into a tree to be consumed and am researching how to achieve the following

12:43 I want to query any url aka web services and present the tree in a way to a Java using developer so that he can select nodes from the tree

12:43 then he can tell me which nodes he is interested in and I will return the value/node if asked

12:44 this is going to be used in an Eclipse RCP based telephony application modeler/builder

12:44 the developer of such an application shall be able to assign the selected nodes to variable which are used in the telephony application

12:45 any idiomatic proposals?

12:47 parsing xml into a tree is easy, I just need to find a way to support http proxies, too, but that's another topic and not related.

12:48 what representation would be best for consuming from Java? or should I just implement a callback-based API which delivers more and more nodes and so on.

12:48 * t345 is thinking loud and probably SPAMing the channel

12:49 danlarkin: why don't you just return whatever you parse from the xml, why make it overcomplicated?

12:50 t345: danlarkin: let's recheck what structure it is when consumes from Java....

12:51 danlarkin: huh?

12:52 t345: danlarkin: the list/tree I get if I eval (clojure.xml/parse "http/....")

12:52 danlarkin: if I retrieve that when I call the clojure code from Java. what will be the reprentation. that's what I'm checking

13:04 danlarkin: t345: and what is your conclusion?

13:04 t345: danlarkin: not sure yet

13:04 hiredman: ,(class (into {} (map vector (range 20) (range 20))))

13:04 clojurebot: clojure.lang.PersistentHashMap

13:05 t345: danlarkin: it's a type from clojure.lang naturally

13:07 danlarkin: yes, a map

13:07 t345: danlarkin: PersistentStructMap which is defined in core.clj

13:08 danlarkin: not exactly

13:08 t345: it's in the jvm part I guess

13:08 checking

13:08 unlink1: What can I do to reduce the startup time of Clojure

13:08 danlarkin: it doesn't matter where it's defined

13:08 t345: danlarkin: it's a Java source file

13:08 danlarkin: makes sense

13:09 unlink1: I'd like to use it for command line scripting, but a minimum of 1 second execution time essentially makes it unacceptable for that purpose.

13:09 danlarkin: I'm just suggesting that you return the map instead of invent a convoluted callback scheme which serves the same purpose as a map but with less usefulness

13:10 hiredman: unlink1: nailgun

13:10 t345: danlarkin: is it always this specifc map type or do I have to rely on it being of a super type?

13:10 danlarkin: t345: rely on the interface

13:11 t345: danlarkin: yep, IPersistentMap

13:11 hiredman: ,(ancestors (class {}))

13:11 clojurebot: #{java.util.concurrent.Callable clojure.lang.AFn clojure.lang.IObj clojure.lang.IFn java.lang.Runnable java.lang.Object clojure.lang.Associative clojure.lang.IPersistentMap clojure.lang.Counted java.io.Serializable clojure.lang.APersistentMap clojure.lang.IPersistentCollection java.lang.Iterable clojure.lang.Obj clojure.lang.IMeta java.util.Map clojure.lang.Seqable}

13:11 t345: danlarkin: thanks so far

13:11 kadaver: me I still don't get why anyone would use Clojure over Haskell.

13:12 gnuvince: kadaver: why is that?

13:12 rsynnott: they're not very similar languages, at all

13:12 kadaver: eh

13:12 hiredman: gnuvince: because no one will talk to him about his mp3player

13:12 kadaver: clojure is a weak haskell

13:12 gnuvince: hmm

13:13 hiredman: so he is resentful and trolling for attention

13:13 gnuvince: kadaver: ok

13:13 kadaver: haskell does everything clojure does much better

13:13 t345: kadaver: I use it to have a saner language for all the $DAYJOB stuff I have to do ontop of the JVM

13:13 kadaver: and did it long before clojure

13:13 t345: kadaver: that's a pointless discussion

13:13 danlarkin: don't feed the troll! run!

13:13 gnuvince: Haskell's Jon Harrop it seems

13:14 t345: gnuvince: how do you come to that conclusion? curios

13:14 danlarkin: hahaha, google actually has a suggested search of "Jon Harrop troll"

13:15 gnuvince: t345: Jon Harrop is well known to barge in on the Lisp and Haskell communities, and pimp OCaml for no particular reason.

13:15 unlink1: nailgun is pretty awesome actually.

13:18 t345: danlarkin: actually

13:18 danlarkin: I don't have to be asked which nodes to return

13:18 Raynes: What kadaver said applys to just about every Haskell person I've talked to. They all think Haskell is superior to Lisp in general. It's annoyingly arrogant.

13:19 t345: danlarkin: that can be done in the rcp app

13:19 danlarkin: t345: just return all nodes, the java program should "ask" the map itself

13:19 t345: Raynes: Haskell's type system is meant to solve anything, prevent babies being killed and produce endless amounts of water with lazy infinite types

13:20 danlarkin: had the insight a minute ago when I asked myself how be asked what to return

13:20 danlarkin: so beatiful

13:20 danlarkin: I can now concentrate on how to configure the http proxy for the underlyng http code.....

13:21 gnuvince: Raynes: there's a difference between somebody prefering Haskell over Lisp and having actual reasons than just going on about how Haskell does everything better than Clojure.

13:24 kadaver: jump on the love bandwagon

13:27 opqdonut: i'm coding clojure at work and would much rather be hacking haskell ;)

13:28 imo clojure's biggest problem is that it tries to embrace purity but pure code somehow still becomes very verbose and clunky

13:28 also there are some minor annoyances, like not being able to tell from which struct-map template a map was made

13:29 would be useful in emulating algebraic data types (another feature i miss)

13:30 unlink1: Any way to get nailgun to listen on a UNIX socket? I don't want any user on the machine to be able to attach to my server.

13:30 opqdonut: but a great language still, and much nicer in gluing stuff together than haskell

13:35 unlink1: ha. Before you download it, be aware that it's not secure. Not even close. Although there are means to ensure that the client is connected to the server from the local machine, there is not yet any concept of a "user". Any programs that run in Nailgun are run with the same permissions as the server itself. You have been warned.

14:30 jonafan: congrats on 1.0

14:30 cp2: thanks, i worked so hard on it :)

14:31 jonafan: me too

14:32 Raynes: gnuvince: I prefer Clojure, but I don't hate on Common lisp.

14:35 kadaver: frame.add(new BasicArrowButton(BasicArrowButton.NORTH));

14:36 how would I create that?

14:36 BasicArrowButton.NORTH

14:36 oh wait

14:44 twism: quick questoion (maybe)...

14:44 how would you create a simple REPL script

14:44 ?

14:45 the most basic loop read print back to *out* (no eval needed)

14:46 hiredman: ,(doc clojure.main/repl)

14:46 clojurebot: "([& options]); Generic, reusable, read-eval-print loop. By default, reads from *in*, writes to *out*, and prints exception summaries to *err*. If you use the default :read hook, *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 d

14:47 twism: hiredman: im not going to use it to eval clojure

14:48 let me rephrade the question

14:48 rephrase*

14:48 how would i get user input from a clojure script

14:48 hiredman: same as java

14:48 *in* is bound to System.in by default

14:48 actually

14:49 twism: ah

14:49 hiredman: *in* is bound to System.in wrapped in a LineNumberingPushbackReader

14:49 but whatever

14:49 twism: (defn run [& args]

14:49 (loop [input (read-line)]

14:49 (print input)

14:49 (recur (read-line))))

14:50 hiredman: (map println (repeatedly read-line))

14:50 twism: god

14:50 i have along way to go

14:51 an that would work if i started the script using clojure.main?

14:51 and*

14:52 hiredman: ,(doc read-line)

14:52 clojurebot: "([]); Reads the next line from stream that is the current value of *in* ."

14:52 heltav: java.lang.NullPointerException (NO_SOURCE_FILE:0)

14:52 what is the cause of such an error normally? not the most helpful errormessage...

14:53 hiredman: twism: not really

14:53 read-line doesn't block

14:54 so you don't want to use it like that

14:54 heltav: trying to call a method on something that is nil

14:54 twism: just found that out when it kicked me out

14:54 hiredman: ,(.toString nil)

14:54 clojurebot: java.lang.NullPointerException

14:54 hiredman: ,(nil 1)

14:54 clojurebot: java.lang.IllegalArgumentException: Can't call nil

14:54 hiredman: oh

14:57 twism: hiredman: thanks for all the help... what do i need to do to have read-line block?

15:03 duncanm: if i have a Java API that takes a List<Foo> is there a way to convert an ISeq into one of those?

15:06 heltav: hmm i have big let, can you somehow println in a let?

15:07 stuhood: heltav: println returns nil, so you can bind the result of println to a variable you don't care about

15:07 hiredman: twism: last time I dealt with it I just used a blockingqueue

15:07 opqdonut: let [_ (prn someting)]

15:07 or something to that effect

15:07 hiredman: or you can use doto

15:07 (let [x (doto (something) prn)] ...)

15:08 stuhood: ~def c.l.PersistentList

15:09 duncanm: if the object extends ASeq, then it will implement the List interface for you. have you tried just passing in the seq?

15:12 hiredman: http://gist.github.com/107140 my gui repl thing, uses a blockingqueue and clojure.main/repl

15:14 twism: hiredman: thanks man

15:17 hiredman: clojure.main/repl is kind of annoying, it takes a map, but doesn't

15:18 so you call it like (clojure.main/repl :read some-read-function :print some-print-function)

15:18 cp2: schroedinger's repl

15:18 hiredman: instead of (clojure.main/repl {:read some-read-function :print some-print-function})

15:19 because obviously it just does something like (defn repl [& args] (let [args1 (apply hash-map args)] ...))

15:19 twism: i was just looking at that and was thinking of leveraging that instead of rolling my own read-evl-print-loop

15:19 hiredman: which *someone* thinks is cute

15:19 cp2: hah

15:46 t345: is there MAven support for clojure? or ideally something cool like Scala's simple-build-tool

15:47 durka42: for the most part ant and maven work as per java

15:51 t345: I use Mave at dayjob. the dependency stuff is good but it's slow as a tool to call often

15:51 Ant is, well not bad, but also using too much RAM and stuff for the job it does

15:51 anyway, no problem

16:13 what is the difference between clojure.jar and clojure-slim.jar? is that latter only missing the sources?

16:15 drewr: t345: Yes.

16:16 t345: hard to imagine as clojure-slim is 526k and clojure is 1400k

16:16 wow

16:16 stuhood: drewr: what does that mean in terms of runtime performance? should -slim load faster? or do they both contain the compiled versions

16:17 t345: clojure-source.jar is 278k

16:18 there's another difference, think

16:18 stuhood: I don't think so

16:18 drewr: stuhood: No runtime perf difference. Just a matter of how big you want your distribution to be.

16:19 The JVM will load the compiled classes and not look at the cljs. It's merely for reverse engineering convenience.

16:20 t345: is it enough to supplu clojure-contrib.jar within -cp to be able to use it from the repl?

16:20 I am failing to do so

16:22 marklar1: is it possible to compile and load multiple files in slime when some files :use others? I keep getting FileNotFoundExceptions for their .class files, so I'm guessing it has something to do with the classpath

16:36 stuhood: marklar1: do you have *compile-path* on your classpath?

16:38 t345: there is speed difference between using clojure-slim or clojure

16:39 the repl starts up faster with clojure and is slower with clojure-slim

16:39 might have to do with some of the inner classes not being there and probably first bein generated

16:39 interesting

16:39 marklar1: stuhood: no, I don't. I'll look into that, thanks

16:42 stuhood: t345: ah yea... i think we had things mixed up

16:43 t345,drewr: based on the contents of the jar, the -slim jar is smaller because it contains the source of 'core.clj, main.clj', etc, rather than all of the .classes that those files compile to

16:43 t345,drewr: so -slim loads slower because it executes those files at runtime, rather than doing AOT compilation

16:45 classic speed/size tradeoff

16:46 drewr: stuhood: Ah, you're right. I had it backwards.

16:48 eee: can you index into strings the way you can in python?

16:49 "abcdefg"[5] == 'f'

16:49 Cark: ,(get "abc" 2)

16:49 clojurebot: \c

16:50 eee: oh cool

16:50 now what's the easy way for a n00b to find that?

16:50 so I can help myself more

16:50 thanks for the help, too

16:51 Cark: get works for maps, a vector is a map of indexes to characters

16:51 a string is "kind of like" a vector =P

16:51 eee: cool

16:52 Cark: i mean a vector is a map of indexes to elements =/

16:52 eee: i knew that at one point

16:52 but took a break

16:52 so get is for maps

16:53 stuhood: eee: anything with a key and value: which includes vectors and strings

16:53 eee: makes sense

16:53 nice generalization

16:54 er abstraction

17:13 I wonder when to use (dorun) vs. (doseq)

17:13 Cark: how about doall =P

17:14 eee: ok

17:14 i have a let

17:14 that called a function

17:14 and got back a list

17:14 and I want to run through the pairs in that list

17:14 and put them in a structure

17:14 oh, and I guess that's also a problem because the structure is immutable

17:15 Cark: a reduce or a map then

17:15 eee: oh

17:16 i don't want to return a list

17:16 i have my own java datastructure that i wrote for clojure

17:17 twism: qq.. is there a way to turn a clojure function to its source?

17:17 eee: twism, it's java byte code

17:17 not java

17:17 twism: hmm

17:17 i think i've seen it done before

17:18 eee: i think i need reduce

17:18 Cark: eee : so you use reduce, start with your empty data structure

17:18 eee: or areduce

17:18 ok

17:18 twism: (fn [x] (+ 5 x)) -> "(fn [x] (+ 5 x))"

17:18 Cark: if it gets too hairy, use loop and recur

17:19 twism: (magic-fn (fn [x] (+ 5 x))) -> "(fn [x] (+ 5 x))"

17:19 eee: already in a loop-recur

17:19 twism: i coulda sworn i've seen this doen before

17:19 eee: but I think it is straight wd

17:20 so if my function is (.insert heap "abc" 3)

17:21 where "abc" 3 is the pair to insert

17:21 Cark: ah you need destructuring

17:21 eee: i need to like quote that or put a hash on the front?

17:22 i'll just have a list of pairs

17:22 for the destructuring part

17:22 i'm just at the syntax part right now.

17:22 Cark: (reduce #(.insert %1 (first %2) (second %2)) (MyStructure/EMPTY) (get-pairs))

17:23 something like that =P

17:24 eee: wow

17:26 wow you didn't even need a let to get the pairs

17:27 twism: a macro that does this is cool too

17:29 eee: so awesome how java can sit right in the clojure code

17:30 t345: eee: sample?

17:31 eee: did I read it correctly that you mixin java syntax? or are you taling about calling java functions?

17:31 eee: that's all I meant

17:32 (let [loaded-heap (reduce #(.insert %1 (first %2) (second %2)) heap (get-transitions current-state))]

17:33 twism: got it.. bind StringWriter to *out* and pr the function as a list (since everything is a list)

17:34 t345: what's wrong about (clojure.contrib.json.read/read-json "http://www.google.com/ig/api?weather=Berlin")

17:34 ozzilee: Hey all. I'm writing an aplication wherein I want a function to do one thing during development, and something different when deployed. I'd like to select the behavior at compile-time with a macro, rather than at evaluation, but I'm not sure how to go about it.

17:34 t345: I have clojure-contrib.jar in -cp but I never can get further than java.lang.ClassNotFoundException: clojure.contrib.json.read (NO_SOURCE_FILE:3)

17:35 Chouser: ozzilee: ah, I've been meaning to blog on that.

17:35 eee: what about just a switch in the main

17:35 ozzilee: Chouser: Well hurry up! :-)

17:35 Chouser: yeah, not gonna happen right now. Let me see if I can remember what I did...

17:36 you need a macro to call like (if-devel foo bar), right?

17:37 ozzilee: Chouser: Yeah, something like that would be ideal.

17:37 Chouser: then: (def devel true) (defmacro if-devel [a b] (if devel a b))

17:38 it looks almost like you don't need if-devel, since it's so simple, but really you do.

17:38 t345: ok the url is not json but that's not the point :)

17:39 Chouser: heh, I suppose you could write ifdef

17:40 ozzilee: Chouser: Hmm. Okay, I think I can run with that, thanks :-)

17:40 Chouser: (defmacro ifdef [i t e] (if (resolve i) t e))

17:41 (def devel? true) (ifdef devel? foo bar)

17:41 eee: crud . . . what i really need is ............ #(.insert %1 %2 (get-score %2))

17:42 Chouser: ...but then you'd have to comment out (def devel? ...) rather then setting it to false.

17:42 just like #ifdef in C

17:42 ozzilee: Chouser: Hmm. I have a namespace that only exists in development mode, I suppose I could write a macro that looks for that namespace, yeah?

17:43 Chouser: sure

17:44 ,(find-ns 'devel)

17:44 clojurebot: nil

17:55 eee: how do I get to the snippet web thing

17:55 to make asking my question easier?

17:59 ozzilee: eee: paste.lisp.org

18:00 replaca: lisppaste8: url?

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

18:01 eee: i tried this

18:01 http://pastebin.com/d743be6be

18:02 so my problem is that

18:02 loaded-heap

18:02 doesn't exist

18:02 because that reduce

18:02 just made it

18:02 so I can use let

18:02 ahead of time

18:03 but is there something fancy I can do?

18:05 replaca: eee: what is the result you're looking for? are you recurring on three variables?

18:05 eee: yeah

18:05 the second

18:05 and third

18:05 dependent on the first

18:05 can you do that?

18:06 or do I need to do the reduce in a let?

18:06 replaca: that's kind of what let's all about

18:06 eee: ok

18:06 replaca: so yeah, you need to wrap recur in a let and do the reduce there

18:07 eee: got it

18:07 replaca: but maybe you only want to recur on the heap itself

18:08 and just compute min and max at the top of the loop

18:08 (unless you already have them coming in)

18:08 eee: i'll show yah

18:08 lisppaste8: eee pasted "a-star" at http://paste.lisp.org/display/79728

18:08 eee: http://paste.lisp.org/display/79728

18:09 wow, it knew

18:10 replaca: yeah, that looks good

18:10 eee: thanks

18:14 i can really see the power of this

18:16 you can't really convince people that clojure is a good thing. it looks foreign. folks just have to try it

18:17 and you guys are great

18:17 talk to ya later

18:28 triddell: Compojure question: Does anyone know if it is still necessary to create routes to serve static files in the latest compojure?

18:29 dnolen: i think it is but it's pretty easy, just make a folder called public (where you start compojure) and add this route:

18:29 (GET "/*" (or (serve-file (:* params)) :next))

18:29 i put it as my first route.

18:31 triddell: dnolen: ok, thanks

18:32 dnolen: np

18:36 triddell: dnolen: I'm trying out compojure on google app engine and the app engine dev server wouldn't serve the static files... but including a public folder and this route worked!

18:37 dnolen: triddell: great! :)

18:38 triddell: but I don't think this route will be necessary when the app is run on the appspot servers (according to the blog post I'm working from) in case someone else refers to this answer, thanks again :-)

18:39 unlink1: I'd like to introduce a new field to clojure.lang.RT corresponding to the current working directory, so that that can be set by the client (say as a command line option). This would allow loading scripts via nailgun to work as expected.

18:41 or at least as a parameter to loadResourceScript

18:41 Then clojure.NGMain (or whatever) could set this appropriately

19:41 dysinger: bowchicka

20:02 eee: hi

20:03 i'm sending in functions as parameters. now to use the function-params, do I have to do anything special or just make them the first arg of a parenthetical?

20:03 Chouser: just as you say

20:04 eee: cool

20:04 so I think I just made a-star generic

20:04 now just gotta learn about namespace

20:05 Chouser, do you know anyone that does clojure talks, including for pay?

20:06 Chouser: Well, Rich does Clojure talks. I don't know if when or how much he might charge.

20:06 Is that what you mean?

20:06 eee: yeah

20:06 some folks I know are interested

20:07 you talk to him a lot?

20:07 Chouser: I've done a Clojure talk, as have Stuart Halloway, Shawn Hoover, and a few others.

20:07 Do I talk to Rich a lot? Not particularly. Mostly what is logged here. :-)

20:08 eee: where are you?

20:08 eee: ok, so I've logged that I'm interested

20:08 Chouser: There's a clojure tutorial set on youtube, I think, as well as on peepcode (I think).

20:09 powr-toc: Does anyone else find that there biggest barrier to getting stuck-into clojure is assembling the basic project structure and dependencies together?

20:10 eee: TOTALLY

20:10 no real IDE yet

20:10 if it doesn't work with eclipse, it ain't ready

20:10 but it's getting there

20:10 follow the steps on the wiki

20:10 and get that rlwrap going

20:10 Chouser: powr-toc: If you don't try to AOT compile, I've found there's hardly anything at all to set up.

20:11 eee: i never got as far as vim-clojure . . .wish I had. I like vim

20:11 powr-toc: I'm not after an IDE... I think it's just that when I hack for fun I don't want to have to continually jump through the hoops of setting up each project, its startup scripts and dependencies

20:11 dnolen: meh, things are really that much different with Python on Ruby, and personally I think setting up project structure is at least as easy as it is in Python.

20:11 really aren't that much different, I mean.

20:12 eee: dude, py-dev for eclipse vs. clojure-dev?

20:12 clojure is way harder

20:12 powr-toc: dnolen: but with ruby including a library is usually as simple as sudo gem install, and then you can just require it

20:12 eee: but still way awesome

20:14 powr-toc: now I'm not claiming that I want ruby gems... Perhaps just some simple tooling to help aggregate dependencies together onto a classpath

20:14 eee: no, I have to say powr-toc is right. lisp and clojure have terrible entries

20:14 dnolen: powr-toc: yes library management would be nice, I agree, still waiting for someone to do this ;)

20:14 eee: i couldn't get a lisp going to a satisfactory level for advanced AI on the weekend before the class so I dropped

20:14 powr-toc: dnolen: I don't even want anything that complicated

20:15 hiredman: you take the jars you want, put them in a directory, put all the jars in that directory in your classpath, done

20:16 Chouser: The java ecosystem has some good options in library management -- someone just has to tie one or more of them into Clojure well.

20:16 eee: yup . . . that part is easy. getting code completion, etc. isnt

20:17 unlink1: List out all the jars you ever want to have on your classpath, pass them to the nailgun server, and forget about it.

20:17 eee: (addressing hiredman)

20:17 powr-toc: unlink1: that's unsustainable and reeks of the old days of having a CLASSPATH env var :-\

20:18 hiredman: eee: emacs and vim both have very satisfactory code completion

20:18 unlink1: I was being tongue-in-cheek, but in fact, that is how you have to use nailgun.

20:18 powr-toc: unlink1: well I guess that's why I don't use it =)

20:18 eee: i haven't gotten it working yet

20:18 hiredman: powr-toc: uh, what do you mean "reeks of the old days"

20:19 unlink1: powr-toc: Is there really an alternative?

20:19 dnolen: powr-toc: yeah, I'd be happy if there was just a shell script that checked a server for available libraries and just downloaded them plus the jars. dump them into a .clojure directory, update a plaintext file of classpaths and be done with it. would make deploying my projects on Slicehost less repetitive.

20:19 Chouser: unlink1: surely you can use java.ext.dirs and just drop new .jars into the given directory?

20:19 dnolen: sounds like a project for Clojure AppEngine ;)

20:19 dysinger: There is starting to become some broken windows in clojure-contrib tests

20:19 eee: is there a CLojure App Engine?

20:19 hiredman: Chouser: has java.ext.dirs always been reliable for you?

20:19 dnolen: yeah, Clojure runs on Google App Engine now.

20:20 Chouser: hiredman: with one exception, yes.

20:20 * Chouser tries to remember the exception...

20:20 eee: is there a link to that effect?

20:20 hiredman: ...

20:20 powr-toc: hiredman: well in the early days of Java people used to say you should set a CLASSPATH environment variable for your system... That's generally acknowledged as being a very bad habbit

20:20 eee: there's a lot I just googled it

20:20 dnolen: eee: http://elhumidor.blogspot.com/2009/04/clojure-on-google-appengine.html

20:20 is the best one.

20:21 dysinger: currently a half dozen blow ups and failures running the clojure-contrib tests :/

20:21 Chouser: hiredman: yeah, I can't remember. There was one .jar that I had to add to my classpath manually, but usually it isn't necessary.

20:22 hiredman: dysinger: feel free to fix them

20:22 eee: cool

20:22 dysinger: the person who broke them should feel even more free to fix them ;)

20:22 hiredman: Chouser: any idea why it is like that?

20:23 powr-toc: dnolen: unlink1 hiredman: I think I'm probably just moaning for the sake of it, but keeping ontop of this stuff is a problem... And I suspect it's why libraries like compojure and incanter ship with everything in the box

20:23 Chouser: hiredman: no. I should have noted the .jar at the time so that someone could track down the cause. But I didn't.

20:23 <-- failed

20:24 eee: powr-toc, it's important

20:24 i agree

20:25 coworkers wanna start messing around but the environment isn't as inviting as python, and it needs to be a goal

20:25 i think bundling clojure with a tiny vm might be a good idea, so it installs like python

20:25 hiredman: dysinger: if people who care about tests are unwilling to fix them, why should people who care less about tests?

20:26 powr-toc: so heres my process... 1) svn/git pull a project, 2) figure out what ant target I should run (if any) 3) run it 4) repeat for all dependencies 5) package dependencies into a project directory 6) finally think about coding

20:26 eee: http://jamvm.sourceforge.net/

20:26 dysinger: hiredman: not following you on that thought process

20:26 hiredman: powr-toc: the real problem there is lack of distributable jars

20:27 eee: jars aren't the same as "site-packages" in python

20:27 dysinger: It doesn't appear that clojure-people are too worried about tests - clojure has zero tests and over the the last 6 weeks I have seen bit-rot set in on the clojure-contrib tests

20:27 eee: or maybe they are ... is they a lib folder in jvm dir for global jars?

20:27 powr-toc: hiredman: yes, you've hit the nail on the head! This problem seems a smaller one in java beacause I just download the jar file into a projet lib dir

20:28 hiredman: dysinger: you obviously care about the tests, I don't particularly, so if you complain about broken tests my solution is: if you care about broken windows, fix them

20:28 eee: yes

20:28 dysinger: how can you not care about tests hiredman ?

20:28 hiredman: it is very easy

20:29 I assure you

20:29 dysinger: if you don't write serious code I guess it would be

20:29 eee: so i wanna some day recompile http://jamvm.sourceforge.net/ where it launches right into a repl

20:29 that'd be the shizznl

20:30 then you could just download clojure . . .instead of downloading java and then clojure

20:31 maybe it could even include waterfront, or whatever that IDE is (I never got it to compile)

20:31 hiredman: if you really care so much, fix the tests, it is much more constructive then joining irc and bemoaning their brokeness

20:32 dysinger: hiredman I am looking at the tests - and I am also communicating that the tests are broke

20:32 I'll do as I please

20:32 telling me to fix the tests is constructive for you ?

20:33 plz go back to your previous conversation

20:33 not caring that unit tests are breaking and making a point to say you don't care about tests makes me not take you seriously

20:34 hiredman: *shrug*

20:38 unlink1: Clojure has no tests?

20:39 gnuvince_: unlink1: there are some in clojure-contrib

20:39 unlink1: but core has none?

20:39 hiredman: the core tests are in contrib

20:39 dnolen: nope, we Clojurians are the living unit tests.

20:42 unlink1: What unit of Clojure are you responsible for testing?

20:42 And what command do I execute to get you to test after I've made a change?

20:43 eee: it's a matter of priorities

20:43 i think that makes sense

20:44 unlink1: Where I'm from, tests make developing in the first place easier.

20:44 eee: for me that's true. in the heap i'm writing, I'm trying to add more and more tests

20:44 but it's also true

20:44 that the community will find bugs

20:45 when they try to do stuff that should make sense

20:45 unlink1: It's true that the community will find bugs in the source tree published by Rich Hickey.

20:46 eee: and Rich should be slowly pulling things in from contrib . . . .which will be another pair of eyes

20:46 unlink1: But they won't find bugs in my local modification of clojure. I have to test that by hand.

20:46 eee: and then the community will eventually find bugs there, too

20:47 oh yeah

20:47 very true

20:47 unlink1: Which discourages third-party contributes.

20:47 *contributions

20:47 eee: but

20:47 very very hard to write 100% covering tests

20:48 so . . . false sense of security?

20:48 unlink1: Nobody expects tests to give 100% coverage.

20:48 They are understood to be a tool that aid the detection of regressions.

20:49 If you don't have them at all, you have no such tool.

20:49 eee: i guess forking clojure isn't really in the plan

20:50 also

20:50 .

20:50 unlink1: Or 3rd party contributions?

20:50 eee: there seem to be a lot of those

20:50 rhickey_: what tests are failing?

20:50 ant -Dclojure.jar=/the/path/to/my/clojure.jar test

20:52 eee: ok so there are tests in the core after all that

20:52 :0

20:56 is the simplest namespace just, like (ns dir.structure) ?

20:57 and in that, is "structure" the file you are in, or the dir you are in?

20:57 and is it basically like a package so that everything in a dir is in a namespace?

20:58 (or for a beginner, I can use it that way?)

20:58 dnolen: eee: simplest namespace is just (ns foobar)

20:59 eee: which is a dir?

20:59 dnolen: just the file

20:59 eee: oh

20:59 i want to put two files in a folder under "src"

20:59 one called "clj-algorithsm"

21:00 and one called "solve_15_puzzle.clj"

21:00 dnolen: for two files you should probably add a folder to src

21:00 eee: (the first should have read, "clj_algotihms.clj")

21:00 i did

21:00 dnolen: src/foo/* -> foo.* if src is on your classpath.

21:00 eee: oh I'm confused

21:01 folder is "clj_algorithms"

21:01 files are "a_star.clj"

21:01 and "solve_15_puzzle.clj"

21:02 so my namespace is (ns clj_algorithms)?

21:02 dnolen: clj-algorithms.a-star and clj-algorithms.solve-15-puzzle seems like the proper ns to me.

21:02 eee: well, clojure-dev doesn't seem to allow dashes in titles

21:03 only underscores

21:03 i mean in files

21:03 so the files and the ns doen't need to match up?

21:03 dnolen: yes, that's the same for everyone I believe.

21:03 underscores becomes dashes

21:03 eee: i see

21:04 and my 15 requires the a-star?

21:06 dnolen: yes if that's how you have it setup.

21:08 eee: (ns clj-algorithms.solve-15-puzzle (:require [clj-algorithms.a-star :as a-star]))

21:09 dnolen: looks ok to me, hopefully you can test that line and get a nice happy nil value in return and not an error.

21:09 eee: i'll try

21:10 it wasn't happy

21:10 dnolen: darn

21:10 eee: (ns clj-algorithms.a-star :import persistent_heap PersistentHeap)

21:10 dnolen: and src/ is on your class path?

21:10 eee: that is what I tried first

21:11 java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Keyword (a_star.clj:3) 1:1 user=> #<Namespace clj-algorithms.a-star> 1:2 clj-algorithms.a-star=>

21:11 hiredman: (ns clj-algorithms.a-star (:import (persistent_heap PersistentHeap)))

21:11 eee: oh

21:12 then there's a typo in the docs

21:12 http://clojure.org/libs

21:12 i looked at "example lib"

21:12 hiredman: persistent_heap should maybe be persistent-heap

21:13 eee: there is no typo

21:13 (ns clj-algorithms.a-star (:import persistent_heap.PersistentHeap))

21:13 eee: in the example that in parens isn't ther

21:13 hiredman: uh

21:14 I am looking at it, and they are

21:14 eee: oh yeah

21:14 sorry

21:14 hiredman: (ns com.my-company.clojure.examples.my-utils (:import java.util.Date) ...

21:14 eee: infernal parens

21:14 :)

21:14 thanks

21:16 hiredman: you missed rhickey_ asking which tests are broken

21:17 eee: rhickey_ ant -Dclojure.jar=/the/path/to/my/clojure.jar test

21:17 awesome.

21:17 is a-star in the contrib yet?

21:21 this language makes me hate going to work b.c. we don't use it there

21:22 but at this point, I'd still need you guys in a chat window :)

21:26 ,(!= '1 '2)

21:26 clojurebot: java.lang.Exception: Unable to resolve symbol: != in this context

21:26 eee: ,(not (= '1 '2))

21:26 clojurebot: true

21:26 eee: really?

21:30 why isn't there a !=, clojurebot?

21:30 :)

21:30 hiredman: ,(not= 1 2)

21:30 clojurebot: true

21:30 eee: ah

21:30 not to bad

21:30 hiredman: ,((comp not =) 1 2)

21:30 clojurebot: true

21:31 dnolen: (def != not=)

21:33 eee: is this the best way to do this?

21:33 (if (first goal-s)

21:33 i used to just do (if goal-s

21:34 infinite loop now

21:36 hiredman: (if (seq goal-s)

21:36 eee: ok

21:36 i see in the docs now

21:37 good ol google

21:37 sorry

21:37 seemed cool that you could go (if goal-s

21:38 hiredman: you might want to just switch calls to rest to next

21:38 eee: ok

21:38 that's the lazy way

21:38 right?

21:39 hiredman: rest is fully lazy, which is why you have to call seq on what it returns

21:39 eee: oh

21:39 hiredman: next is not lazy for the first item (but it is for the rest)

21:40 eee: now I can do (if goal-s

21:40 you figured out i was using rest

21:47 dysinger: ,(eval (eval '(list + 1 2 3)))

21:47 clojurebot: DENIED

21:47 dysinger: ,(eval '(list + 1 2 3))

21:47 clojurebot: DENIED

21:51 dysinger: I wonder why (eval (eval '(list + 1 2 3))) works in 20090320 but not 1.0

21:54 hiredman: dysinger: works here

21:54 Clojure 1.1.0-alpha-SNAPSHOT

21:55 dysinger: hmm I'll try 1.1

21:59 hiredman: works on 1.0 here too

22:00 eee: ,(find '("a" "b") "b")

22:00 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.util.Map

22:01 eee: ,(get '("a" "b") "b")

22:01 clojurebot: nil

22:01 hiredman: ,(doc find)

22:01 clojurebot: "([map key]); Returns the map entry for key, or nil if key not present."

22:01 hiredman: makes sense yes?

22:01 eee: i want to know wat position

22:02 hiredman: ,(.indexOf '(a b) 'b)

22:02 clojurebot: 1

22:02 eee: ,(.indexOf '("a" "b") "b")

22:02 clojurebot: 1

22:02 eee: nah, that's gotta be in clj

22:02 hiredman: it is clj

22:03 eee: ,(index '("a" "b") "b")

22:03 clojurebot: java.lang.Exception: Unable to resolve symbol: index in this context

22:03 eee: ,(clojure.set.index '("a" "b") "b")

22:03 clojurebot: java.lang.ClassNotFoundException: clojure.set.index

22:03 hiredman: use indexOf

22:03 eee: ,(clojure.set.index (clojure.set ("a" "b")) "b")

22:03 clojurebot: java.lang.ClassNotFoundException: clojure.set.index

22:04 eee: grrrr

22:04 hiredman: ,(.invoke (fn [] 1))

22:04 clojurebot: 1

22:04 eee: what's that showing

22:05 hiredman: that function application is just a method call

22:05 eee: it's kindof a deal breaker at work to drop back to java for stuff like that

22:05 hiredman: oh please

22:05 "drop back into java"

22:05 eee: they hate java

22:05 that's their quote

22:05 hiredman: they are ignorant

22:05 danlei: i have (defn position [coll item] (.indexOf coll item)) in my tools ...

22:05 hiredman: most likely redneck hick racists

22:06 eee: check it into core danlei

22:06 (if that is possible)

22:06 hiredman: they should grow and overcome their ignorance

22:06 dnolen: and if you don't need the behavior of .indexOf as an fn you can always write a macro: (defmacro index-of [coll x] `(.indexOf ~coll ~x))

22:06 hiredman: clojure is *HOSTED* on the jvm

22:06 danlei: eee: well, usually the philosophy over here is, that if some functionality already exists in java, it is not wrapped. i just always type position automatically, so i defined it ...

22:07 hiredman: that was part its design

22:08 eee: (ducking) and if I need a hammer I can mold one out of iron ore?

22:08 j/k

22:08 danlei: dnolen: why should one use a macro here?

22:08 hiredman: clojurebot: literal [3] clojure

22:08 clojurebot: a very attractive hammer with a nice heft to it

22:10 hiredman: eee: you want to wrap a perfectly good hammer in a layer of plastic and label it "gravity driven energy delivery device"

22:10 eee: is .indexOf in C#?

22:10 starts with capotol I

22:10 in C#

22:11 so host dependent

22:11 dnolen: daniel: personal pref really, one less fn call if you're not planning on using it as an fn.

22:11 eee: which is fine for, like gui stuff or something insane

22:11 i bet it's in contrib somewhere

22:11 danlei: dnolen: prem..., well ok. :)

22:11 dnolen: daniel: very :)

22:12 daniel: mostly I attribute it to laziness.

22:12 dysinger: hiredman

22:12 Clojure 1.1.0-alpha-SNAPSHOT

22:12 user=> (= (eval (eval (quote (list + 1 2 3)))) 6)

22:12 java.lang.ExceptionInInitializerError (NO_SOURCE_FILE:0)

22:12 user=>

22:13 is this not what you see ?

22:13 dnolen: no so much index-of but (defmacro parse-int [str] `(Integer/parseInt ~str))

22:14 eee: google search ain't finding that nice marked up doc page for contribs yet

22:14 can't find the docs for contribs

22:14 hiredman: dysinger: nope

22:14 I see 6

22:14 on 1.0 and 1.1

22:14 dysinger: here's 20090320

22:14 tim-dysingers-macbook-pro:~ tim$ clj

22:14 Clojure

22:14 user=> (= (eval (eval (quote (list + 1 2 3)))) 6)

22:14 true

22:14 user=>

22:14 eee: http://code.google.com/p/clojure-contrib/wiki/OverviewOfContrib

22:15 hiredman: dysinger: well that is not the test case you pasted earlier

22:15 anyway

22:15 dysinger: 1.1 are currenty 2 commits apart

22:15 hiredman: I get 6

22:15 dysinger: 1.1 and 1.0

22:15 hiredman: on both

22:15 dysinger: you shouldn't get 6 you should get true

22:15 hiredman: I get six for the inner expression

22:16 so of course I get true for the outer expression

22:16 dysinger: how could your 1.1 be different than mine ?

22:16 hiredman: you are doing it wrong?

22:16 dysinger: that's cute

22:16 hiredman: check you classpath

22:16 your

22:17 ant clean then rebuild

22:17 eee: would be cool if the contrib "includes?" returned the index instead of just true

22:17 dysinger: hiredman "check my classpath" lol

22:17 hiredman: yeah, make sure you are using the right jar

22:18 eee: how do you request a feature change to contrib?

22:18 dysinger: I am lightyears ahead of "the right jar"

22:18 hiredman pastie your (System/getProperties) for me

22:19 hiredman: I have done this on two machines, one with openjdk7 and one with diablo-jdk1.6

22:20 dysinger: so let me see your system properties from a machine where 1.1 evals that above

22:20 hiredman: why?

22:21 dysinger: because it says a lot

22:22 hiredman: uh

22:22 lisppaste8: url

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

22:22 hiredman pasted "properties" at http://paste.lisp.org/display/79736

22:23 hiredman annotated #79736 "second machine" at http://paste.lisp.org/display/79736#1

22:25 danlei: eee: btw, looking at it again, if you want to use position (defn position [coll item] (.indexOf (seq coll) item)) might be better. (position "abc" \c)

22:25 lisppaste8: hiredman annotated #79736 "third" at http://paste.lisp.org/display/79736#2

22:26 dysinger: can anyone else besides hiredman verify that (= (eval (eval (quote (list + 1 2 3)))) 6) works on 1.0/1.1-SNAPSHOT ?

22:26 danlei: dysinger: => true

22:26 dysinger: wtf

22:27 eee: ok thanks danlei

22:27 * dysinger puzzled

22:27 clojurebot: true

22:27 dnolen: what are expecting to see dysinger?

22:27 I see true as well.

22:28 dysinger: I get exception

22:28 eee: as long as indexOf works for all seqs

22:28 hiredman: ~works on my machine

22:28 clojurebot: http://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png

22:28 dnolen: dysinger: where are you pulling your sources from? svn or github?

22:28 dysinger: user=> (= (eval (eval (quote (list + 1 2 3)))) 6)

22:28 java.lang.ExceptionInInitializerError (NO_SOURCE_FILE:0)

22:28 user=>

22:28 svn

22:28 hiredman: how are you starting clojure?

22:29 dysinger: emacs

22:29 but also tried java -jar clojure.jar XXX.YYY

22:29 eee: whatever version I have, it works

22:29 hiredman: where xxx.yyy is?

22:29 dysinger: ok I believe you -

22:29 eee: returned true

22:29 * dysinger goes off to try to fix

22:36 eee: i don't even know how to ask this

22:37 do you have to quote all the way down?

22:37 so like I want to send a list of lists to a function param

22:37 do you just quote the outside?

22:37 hiredman: "send"

22:37 eee: or '('("a" "b") '("c" "d"))

22:37 hiredman: just the outside

22:38 eee: the outside keeps anything from being evaled?

22:39 '(a b) '(c d))

22:39 or expanded or whatever

22:39 lisppaste8: danlei pasted "position" at http://paste.lisp.org/display/79737

22:39 eee: ,'(a b) '(c d))

22:39 clojurebot: (a b)

22:39 eee: ,'(a b) (c d))

22:39 clojurebot: (a b)

22:39 eee: ,'((a b) (c d))

22:39 clojurebot: ((a b) (c d))

22:39 eee: ,a

22:39 clojurebot: java.lang.Exception: Unable to resolve symbol: a in this context

22:40 eee: ,'((a b) ())

22:40 clojurebot: ((a b) ())

22:41 eee: ,(let [q '((a b) ())] (first q))

22:41 clojurebot: (a b)

22:41 eee: ,(let [q '((a b) ())] (second q))

22:41 clojurebot: ()

22:45 danlei: hiredman: concerning that .indexOf returns a magic number (and yes, i consider this ugly), do you really think that something like "position" in core would be such a bad idea?

22:46 hiredman: yes

22:46 danlei: hm

22:46 eee: i found (includes?)

22:46 you could just have that return the pos

22:46 instead of true

22:46 hiredman: it is errecting a barrier between clojure and the environment it was built to inhabit

22:47 eee: also (includes?) is unnecessary by that argument . . .and so is a lot that is wrapped in core

22:47 danlei: well, but its a useful abstraction. position is more general, and more lispy. but i do see your point, don't wanna argument here.

22:47 hiredman: eee: correct

22:47 eee: but, it's more resilient to not assume it will always be java

22:48 and

22:48 assuming jvm is not the same as assuming java

22:48 i think it's low priority to wrap some things, I agree

22:48 and Rish points out that it's a pain to come up with docs when java already did it

22:49 technomancy: danlarkin: can you explain the difference between clojure-json and clojure.contrib.json?

22:49 eee: but . .. we be talkin about pos here, not some crazy gui thing

22:49 technomancy: apart from the fact that yours uses keywords keys and contrib uses string keys...

22:49 danlei: in this case, it's (in my opinion) not just wrapping. dealing with magic numbers in lisp code is not idiomatic, in my opinion. but thats maybe just personal preference, so i'll just put it in my toolbox and shut up now. :)

22:49 danlarkin: technomancy: the technical differences?

22:50 eee: yeah, I'll somewhat shut up, too.

22:50 hiredman: eee: clojure collections are all java Collections

22:50 technomancy: danlei: it's not just you; dealing with magic numbers is ridiculous

22:50 eee: but I try to represent python folks considering clojure

22:50 technomancy: danlarkin: I mean did you write yours before there was one in contrib, or did you write yours because the contrib one was too slow, or what?

22:50 eee: which isn't necessarily me . . . so having a strong argument is best

22:52 technomancy: danlarkin: btw, re the http lib; I split out the "get/post/put" etc functions into its own namespace so the main thing in http/client.clj is just the request functions

22:52 clojurebot: functions are maps

22:52 technomancy: clojurebot: thanks for sharing.

22:52 clojurebot: for is not used enough

22:53 technomancy: clojurebot: are you descended from Eliza?

22:53 clojurebot: Huh?

22:53 hiredman: eee: clojure is built on java/the jvm it was purpose built for that, a similar language on other architectures will be that, a similar language, but not clojure

22:53 technomancy: clojurebot: did you say "huh" because of your childhood?

22:53 clojurebot: Pardon?

22:53 danlarkin: technomancy: I wrote it before there was one in contrib, also clojure-json uses constant memory for encoding and (I think) contrib.json can overflow the stack with big JSON files (or it used to at least?), and clojure-json can do indenting, and have custom encoder functions for types it doesn't know about, etc

22:54 technomancy: danlarkin: cool; sounds handy

22:54 eee: i guess i'm making an extension of the java argument, compile once, run anywhere

22:55 danlarkin: oh, not to mention that clojure-json correctly deals with all json I've thrown at it, while contrib.json has some bugs

22:55 eee: jvm is written for it's host so java byte code doesn't have to be

22:55 technomancy: danlarkin: I just get the feeling that contrib has a serious neglect issue.

22:55 hiredman: eee: clojure compiles to jvm bytecode

22:55 eee: likewise it'd be cool to have a language that didn't care what vm it ran on

22:55 pipe dream for some things . .. but pos isn't a pipe dream

22:55 seems like a good goal

22:56 * technomancy thinks someone needs to take strong ownership of contrib, clarify its purpose and clean it up

22:56 eee: as fundamental as "next"

22:56 or "first"

22:56 * technomancy glances at Chouser

22:56 eee: or "nth"

22:56 hiredman: it needs to be split

22:56 eee: i agree there

22:56 it needs to be split

22:56 if we are talking about contrib

22:56 hiredman: possible some kind of super package pulling most of contrib into one jar

22:57 technomancy: totally

22:57 eee: core-staging

22:57 technomancy: yeah, some kind of "candidates for contrib" would be useful

22:57 eee: or "core-candidates"

22:57 technomancy: then a "standard library" section

22:58 then "deprecated" where we can move libraries whose tests don't pass.

22:58 =)

22:58 eee: ,(nth '(1 2 3) 2)

22:58 clojurebot: 3

22:59 eee: if nth is there, it's inverse should be

22:59 pos

22:59 :)

22:59 danlei: just ask rich about it, when he is around

22:59 technomancy: I think the reluctance to put stuff in core makes more sense once you realize core.clj is _one_ file

22:59 replaca: danlarkin: are you currently a contributor (i.e. have signed a CA)?

23:00 danlarkin: replaca: yes

23:00 technomancy: and it's 4152 lines long

23:00 replaca: danlarkin: So we can just ptopose in the group that clojure-jsan replacee the current jsaon code

23:00 Puzzler: Quick question: In the SLIME Repl, I can't get println to work when it is called from a newly-spun thread. Any suggestions?

23:01 eee: i wonder what the impact of such a large file is

23:01 replaca: danlarkin: would you be in favor of that?

23:01 danlarkin: sure! breaking change to those using the current contrib.json, but quite alright with me

23:01 replaca: well, there's a discussion, but we know that's broken

23:02 there doesn't seem to be much reason to have competing versions

23:02 danlei: Puzzler: there was (slime-redirect-inferior-output), but i don't think that works atm

23:02 technomancy: danlarkin: breaking just because of string keys and different function names, or is it more?

23:02 danlarkin: but yeah, I'd submit it for inclusion. this is one instance of choice is not helpful.

23:02 danlarkin: technomancy: and if they were relying on the broken behavior of current contrib.json

23:03 replaca: Probably we should write up a group posting about JSON

23:04 Stuart wrote the existing one (are you here Stuart?) but I don't know if he's attached to it or not

23:08 technomancy: danlarkin: would love to get your feedback on the "resourcefully" branch if you could take a look.

23:08 I think there's a place for a higher-level API around the client

23:09 hiredman: http://mail.openjdk.java.net/pipermail/discuss/2009-April/001648.html "When the Sun goes down what happens to the OpenJDK"

23:11 eee: do lists always make you insert at the beginning?

23:11 i tried cons and conj

23:11 hiredman: yes

23:11 dnolen: vectors will add at the end.

23:12 eee: want my new stuff at the end

23:12 hiredman: that is a property of lists

23:12 danlei: eee: cons, by definition, conj, because it's cheapest for lists

23:12 eee: ok ok

23:13 but how do I know I'm dealing with a vector from a function

23:13 danlei: btw, there is no *guarantee* that conj will always add at the end of a vector, is it?

23:13 eee: seems hard

23:13 hiredman: ,(doc conj)

23:13 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

23:14 eee: uhg

23:14 danlei: hiredman: so, what *does* guarantee adding at the end?

23:14 eee: exactly

23:14 dnolen: daniel: it will always add the end, unless the vector gets coerced into something else

23:14 hiredman: danlei: conj will always add at the end of vectors

23:14 dnolen: if for some reason it gets coerced you can always bring it back with (into [] ...)

23:15 arohner: and you can tell what obj you have by doing (class obj), but I would be careful of making decisions based on that

23:15 ,(class [])

23:15 clojurebot: clojure.lang.PersistentVector

23:15 danlei: dnolen: thanks, i use vec btw

23:15 hiredman: ~def vec

23:16 danlei: in practice, it's clear to me, that conj will add at the end of a vector. maybe it's just nitpicking ...

23:17 eee: so now I DO have to quote the inner lists

23:18 ,(let [q ['(a b) '()]] (second q))

23:18 clojurebot: ()

23:18 eee: ,(let [q ['(a b) '()]] (first q))

23:18 clojurebot: (a b)

23:19 hiredman: eee: you can quote the vector

23:19 ,'[(a b)]

23:19 clojurebot: [(a b)]

23:19 eee: in my code, that was barfing . . guess it wasn't that

23:20 ,(let [q '[(a b) ()]] (first q))

23:20 clojurebot: (a b)

23:21 danlarkin: technomancy: it looks good, with-cookies would be very handy

23:21 technomancy: danlarkin: with-cookies could go into client.clj too

23:22 you like the idea of splitting the two namespaces?

23:23 danlarkin: oh, I'm slightly confused then I guess, what's the idea behind splitting the namespaces?

23:24 technomancy: just that one's an API for lower-level stuff and resourcefully is more centered around interacting with REST services

23:24 since you weren't too sure about adding get/put/post/delete etc to client

23:25 eee: this transition function is gonna hurt my brain tonight. that's a whole nother chapter for me

23:25 thanks for all the explanations and help

23:25 danlarkin: so resourcefully.clj would be for defining wrapper methods get/post...etc around client.clj's request function?

23:25 technomancy: right

23:28 danlarkin: I'm still not convinced of the need for a function that wraps another just providing one argument... although if that's what people want...

23:28 technomancy: we'll play with it; see how it feels

23:29 * technomancy heads off; will talk tomorrow

Logging service provided by n01se.net