#clojure log - Mar 05 2010

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

0:01 joshua-choi: And I use a plain text editor: sometimes TextEdit; lately TextWrangler. I've been trying NetBeans-Enclojure lately, but it makes my laptop pretty hot even idly.

0:01 technomancy: anecdotally: everyone I know who uses clojure uses a repl

0:02 dnolen: technomancy: heh :) yes I suppose I meant REPL oriented development. compile a little bit. type expr a REPL, correct, repeat.

0:03 joshua-choi: How do you do it? When you modify a library's code, what do you do in a REPL? Just evaluate test expressions? Doesn't that get tedious without factoring them into a test file?

0:03 danlarkin: how can you not write clojure interactively? it's like... giving up half the benefit of a lisp? crazy!

0:04 joshua-choi: I'd love for someone to write a tutorial for the *philosophy* of REPL-driven Clojure development. I'd read it voraciously.

0:04 Raynes: joshua-choi: You just play with stuff. You can use an REPL as a debugging tool by evaluating pieces of code until you find hte problem. You can write expressions just to see what they'll do, look up documentation, etc.

0:04 the*

0:05 joshua-choi: Can you evaluate pieces of code other than top-level functions?

0:05 Raynes: It's not just static test expressions.

0:05 You can evaluate any code.

0:05 Have you ever used an REPL before?

0:05 joshua-choi: Yeah, but just a standalone one, like clojure.main.

0:06 When I tried using it, I'd (require my-library) (do-something top-level-fn), but I'd reload and re-evaluate over and over again.

0:07 Whenever I changed my library. Right now I figure that just running a test script in my terminal is less tedious. But there's got to be something that I'm missing.

0:07 Raynes: It's not just for evaluation test expressions. You can try out anything in an REPL, like I said, just to see if it works. Find out what things to, and know if something is going to work /before/ you write it.

0:07 evaluating*

0:07 do*

0:07 Wow, I can't type today. :\

0:08 joshua-choi: You mean, running bits of code and then putting them together?

0:08 How do you deal with lexical contexts?

0:08 And isn't it annoying to copy and paste code you put in REPLs in your actual library code?

0:08 Raynes: Not really...

0:08 joshua-choi: Mmm. Maybe using an actual IDE would make it better.

0:09 Raynes: You can def code that you want to save for use in later code. Also, the last expression evaluated is saved in *1, and so on until *3.

0:09 Meh, IDEs don't have anything to do with it. I think you might just be missing the point. Maybe this is something you need to do before you'll understand the reason behind it.

0:10 joshua-choi: Yeah. I feel like I need to figure this out, and that it'd make me a lot more productive.

0:10 I'm just using a text editor and a terminal.

0:10 Well, here's one thing: how do you deal with reloading libraries?

0:11 I'd have to paste "(require [blah.blah :as blah])" every time I changed my library even a little bit.

0:11 Raynes: Stuff like Emacs and other IDEs make it easier to load code into the REPL with keybindings.

0:11 joshua-choi: Do you just not modify your actual Clojure file often?

0:11 I see.

0:12 rickmode: joshua-choi: sounds like you need to embrace Emacs + SLIME + Swank

0:12 joshua-choi: I'm very afraid of Emacs.

0:12 rickmode: it's a bit of a mind bender at first, but it'll pay off quick

0:13 I'm using Aquamacs which mashes up Emacs with the usual mac os'isms

0:14 joshua-choi: Perhaps. When I mucked in Emacs for the first time, it wasn't the bindings that were that hard—it was the buffers. I'd do something accidentally, and something really weird and apparently destructive happens to my screen.

0:14 Aquamacs?

0:14 rickmode: but you'll hit some fun wonky stuff getting swank-closure set up properly with the stable version of aquamacs

0:14 joshua-choi: There's a Cocoa version of Emacs?

0:14 rickmode: Aquamacs is built on top of Emacs

0:15 there's a couple... aquamacs seems the most user-friendly (to me at least)

1:00 DeusExPikachu: joshua-choi, I use emacs/slime but I use a repl only for really short one liners. Stuart Halloway's trick of having a temp buffer and just evaluating stuff from there is soo much better then trying to navigate the history of the repl. Also the keybindings are different in the slime-repl rather then a full blown slime / clojure-mode / paredit buffer

1:03 think of emacs as firefox with a bunch of tabs, but to switch between the tabs, use the key sequence C-x b. Most of emac's behavior is nondestructive, just switch back to the old buffer, nothing happened to your data

3:02 robink: Is it possible to have a JVM run quickly on a machine without hardware float?

3:06 TheBusby: or a broader question, does the JVM run quickly on any machine that isn't a desktop PC or server? Based on experiences with Android I wouldn't say it was very quick on an embedded device...

3:07 hiredman: well, android isn't a jvm

3:07 Fossi: do you really mean a jvm on android?

3:07 TheBusby: it's a platform partially built on top of a jvm

3:08 Fossi: it's got it's own vm, dex

3:08 and it's gc sucks ;D

3:08 especially for clojure ;)

3:09 TheBusby: sorry, I consider a virtual machine that runs Java to be a JVM

3:12 hiredman: TheBusby: it doesn't even use java bytecode

3:12 TheBusby: and a turing machine doesn't use electricity

3:12 hiredman: we aren't talking turing machines

3:13 TheBusby: I was hoping you'd see the connection

3:13 jvm's don't necessarily have to use bytecodes, or be stack based

3:13 I guess sun may have a different definition for their trademark though

3:13 hiredman: TheBusby: the jvm spec says different

3:14 TheBusby: and xerox says that only machines made by them can be called "xerox machines", same with cleanex

3:14 hiredman: well, it at least says it has to implement bytecodes that operate on a stack

3:15 TheBusby: the jvm is not just a brand, it has a spec, which is what allows others to make jvms

3:15 TheBusby: I understand your point hiredman, and I know what you're trying to say

3:15 I just don't agree

3:16 hiredman: you seem to be confusing java the language with the jvm

3:17 calling the dalvik vm a jvm is like calling an arm cpu a x86 because if you run an x86 binary through the right translation programming it will run on an arm machine

3:17 TheBusby: no I just think than JVM is the acronym for any java virtual machine, and that one of those is the branded "jvm" we all know and love

3:18 hiredman: there are others too

3:18 TheBusby: hence "one of those"

3:18 hiredman: but the dalvik vm is not one of those

3:18 it's not a matter of branding

3:19 the architecture is completely different from any jvms

3:19 TheBusby: correct

3:19 I was simply saying that I consider the term JVM to encompass all java virtual machines, not just the ones that meet the sun VM spec. I realize there can be significant differences

3:20 hiredman: as I said, that is ridiculous

3:20 like saying an arm cpu is a x86

3:20 gregh: a VM that doesn't meet the Sun JVM spec is simply *not* a JVM

3:20 TheBusby: so you call it a "java virtual machine", but you can't use the acronym?

3:21 adityo: hey did you guys read this http://bit.ly/d040Aw, and who is codemonkey

3:21 hiredman: no

3:21 it's not a java virtual machine

3:21 TheBusby: what would you call it then?

3:22 hiredman: a dalvik virtual machine

3:22 TheBusby: I think that's fine too

3:23 this is all semantics really

3:23 and I realize my use of JVM is unclear

3:23 hiredman: is an x86 a jvm? I mean you could translate java bytecode into machine code (this is exactly what the jit does)

3:23 TheBusby: I understand your point, which is why I mentioned turing machines earlier

3:24 hiredman: yes

3:24 you obviously don't understand my point

3:24 TheBusby: it's all semantics and depends on how detailed you want to be

3:24 gregh: and how easily you need to communicate with other developers

3:24 it's not "just semantics"

3:25 TheBusby: you're right in that it does depend entirely on your audience

3:25 hiredman: to run Java The Language on a dalvik vm, you have to compile to java bytecode and run a translation tool that turns it into dex bytecode

3:26 to say that the dalvik vm is a jvm is equivalent to calling an arm cpu a x86

3:27 TheBusby: I understand what you're saying, I wish you'd believe that

3:27 hiredman: this is totally isomorphic, I demand that if you are going to call dalvik a jvm that from now on you call arm cpus x86 cpus

3:30 TheBusby: so to return the core topic, can you get great performance on embedded platforms?

3:30 hiredman: I doubt it

3:30 TheBusby: ignoring android for the moment, I haven't seen any good examples in the cellphone market in the past 10 years. I haven't been looking too closely either though

3:31 hiredman: the delbik vm doesn't have a good gc regardless

3:31 dalvik

3:31 TheBusby: I know for a lot of embedded applications they require taking advantage of CPU specific calls to handle different things

3:31 gregh: some arm cpus can run jvm bytecodes directly, they're probably better placed to be faster than an interpreter

3:31 hiredman: you might be able to find some kind of openjdk build, but you might be stuck with something like jamvm, which also is not a huge performer

3:31 TheBusby: I can't imagine that's well suited for something like a vm

3:32 hiredman: jazelle?

3:32 TheBusby: depends

3:32 there is jni "stuff"

3:32 TheBusby: hiredman: it certainly depends because you see such a huge variation in platform characteristics across the market

3:32 gregh: yeah, jazelle is what I'm thinking of

3:33 TheBusby: for example, two different platfroms using the same CPU can have wildly different performance relating to memory access

3:33 hiredman: the idea of a jvm in hardware is very interesting

3:34 TheBusby: didn't sun try that 10-15 years back?

3:34 hiredman: azul does it now

3:34 and jazelle is some kind of hybrid if I recall

3:36 TheBusby: In regards to universal compatibiltiy, I haven't seen anything comparable to pure old C with all the types/calls abstracted out to #defines

3:37 I'm waiting for the day that isn't true... :)

4:30 Licenser_: greetings parenthethie friends

4:46 timothypratley: can someone help me out (brain not working): http://code.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/Query.FilterOperator.html

4:46 How do I reference EQUAL from there?

4:47 like com.google.appengine.api.datastore.Query.FilterOperator.EQUAL but with $ and or / in there or something.

4:49 esj: hey Licenser_

4:51 timothypratley: ah nm I remember now.... com.google.appengine.api.datastore.Query$FilterOperator/EQUAL

4:52 esj: really rolls off the fingertips

4:52 timothypratley: :)

5:09 Licenser_: hi esj :)

6:31 powr-toc: I'm using leiningen, and have just updated and lein installed swank-clojure... However changing the dev-dependency to 1.2.0-SNAPSHOT attempts (and fails) to download it; despite the fact that it's already installed locally... any ideas?

6:36 robink: I'm not sure I'd want something handled with c-type #defines.

6:40 powr-toc: doh... I'm mixing up swank-clojure and lein-swank!

7:00 mattc: Clojure and Java newbie question: how can I call a Java constructor with variadic args from Clojure?

7:00 I've tried just passing args, passing them as a vector, a list, a seq constructed from a vector... all give errors e.g. ClassCastException

7:01 esj: apply ?

7:01 that's just a guess

7:01 mattc: apply: "java.lang.IllegalArgumentException: No matching ctor found for class ..."

7:02 rhickey_: mattc: Java doesn't have real variadics. just language sugar for array creation. To use from Clojure. you need to pass the array. you can make the array with into-array or to-array

7:02 esj: dunno, not done much java interop

7:02 mattc: ok I'll give that a go, thanks!

7:02 the-kenny: Is there something like when-comp? Like comp, but with nil-checking

7:03 (I know this is a maybe-monad... but I think c.c.monad is too much for this)

7:03 mattc: you seem to know a bit about clojure ;-) that worked perfectly, thanks Rich.

7:04 the-kenny: mattc: No... rhickey_ is a total newbie in clojure.... ;)

7:04 mattc: "(LocalServiceTestHelper. (into-array [(LocalDatastoreServiceTestConfig.)]))"

7:04 :-)

9:24 powr-toc: Does anyone know how to get leiningen to AOT compile your source? It keeps saying "No namespaces listed for compilation in project.clj"

9:25 bsteuber: lein compile does the job for me

9:25 spariev: powr-toc: you should add :namespaces - a list of namespaces on which to perform AOT-compilation

9:26 see README at http://github.com/technomancy/leiningen

9:26 bsteuber: spariev: is that specific to the new leiningen version?

9:26 spariev: yep, I believe it's specific for 1.1.0

9:27 bsteuber: ic

9:27 spariev: s/for/to/

9:28 must improve my English :)

9:32 powr-toc: spariev: I have that

9:32 spariev: and it still reports the error

9:34 Ok, it means a literal list... it doesn't work for a vector... should that really be the case?

9:36 spariev: not sure, http://github.com/technomancy/leiningen/blob/master/src/leiningen/compile.clj#L16 yere it just checks if it's collection

9:36 try :namespaces :all

9:41 jcromartie: I almost took this Compojure app and said "screw it" and did it in Rails, but then I realized that my data validation rules were way more powerful than they'd ever be in Rails

9:43 powr-toc: spariev: cheers... it seems to work... but now I have some horrible exceptions... I wish clojure's stacktraces were a little easier to debug

9:44 spariev: np, glad I could help

9:45 powr-toc: it's odd... my program seems to run ok... but compiling it causes it to barf

9:45 (during compilation I mean)

10:06 tjg: hi there! i'm listed as a clojure contributor but my membership on the clojure-dev forum is pending, though i applied a couple times... is this expected, or am i supposed to do something else like email a moderator? (i don't mean to rush anyone, just curious.)

10:08 chouser: tjg: how did you apply?

10:09 rhickey: tjg: you should be all set now

10:09 tjg: rhickey: Thanks!

10:10 chouser: I just pushed the googlegroups button to apply, wrote a little note and.. waited. ;)

10:10 chouser: rhickey: is that all you need in general?

10:10 rhickey: tjg: sorry, I had neglected the PO box for a bit, just added a bunch of contributors

10:11 tjg: chouser: oh yeah, and of course snailmailed in the CA to pleasantville. ;)

10:11 rhickey: chouser: yeah, CA, and the apply button asks people to state they've submitted a CA. I still get a lot of applications from people who haven't, dunno what they expect

10:12 * Licenser_ had the chance to run some clojure code on a well equipped Sun X4170 - hell that is fast!

10:12 tjg: rhickey: yeah, my last PO box was terminated because it overfilled since i neglected to check it. ;) good thing I wasn't using it for anything important...

10:12 Licenser_: clojure really really takes advantage of the high number of cores it's incredible

10:13 rhickey: tjg: it would be nice if they didn't put junk/bulk mail in PO boxes - what's the point? My post office has a stack of circulars taken out of PO boxes - such waste

10:14 wthidden: ,(apply (first '(+ 10 10)) nil (rest '(+ 10 10)))

10:14 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: Symbol

10:14 wthidden: so what am i missing?

10:15 zmila: wthidden - paren just after '

10:15 open paren

10:15 rhickey: wthidden: the symbol '+ is not the function +

10:15 wthidden: fhrump.

10:16 i was hoping that was not the case. thanks

10:18 zmila: sorry, i'm wrong about paren

10:20 wthidden: ,(apply (resolve (first '(+ 10 10))) (rest '(+ 10 10)))

10:20 clojurebot: 20

10:20 wthidden: zmila: np.

10:26 powr-toc: How do people structure clojure.test unit tests with leiningen?

10:27 (or more generally clojure.test) ... Presumably the test namespaces and filenames mirror those defined in src/

10:28 joshua-choi: It was always kind of weird

10:28 On the one hand, clojure.test tests seem to be intended to be integrated in vars' metadata

10:28 But a lot of people put tests in separate vars in src/test/ directories

10:29 I think Leiningen goes for the latter...I think.

10:29 Oh, wait; "lein test [TESTS] # run the tests in the TESTS namespaces, or all tests", according to its readme.

10:30 powr-toc: yeah... looking at lein's test source code, they pull in the namespace to test with :use

10:31 joshua-choi: Really? That seems a little fragile, but maybe there's a reason

10:31 powr-toc: joshua-choi: yeah... it does... also I can't get lein's tests to run at all

10:32 oh no... It just has...

10:32 looks like it failed though :-\

10:38 spariev: joshua-choi: just wanted to say "thank you" for FnParse

10:38 joshua-choi: Oh, no problem

10:38 spariev: joshua-choi: it's awesome

10:38 joshua-choi: I'm still writing FnParse 3 though, and it looks quite different

10:38 But FnParse 2 is fine too

10:39 Just warning you though :P

10:42 spariev: can't believe FnParse could be made even better :)

10:44 chouser: rhickey: would it be better for deftype to catch when you define `valAt instead of 'valAt (for example), and not generate conflicting definitions?

10:44 joshua-choi: spariev: If you have questions on it in the future, feel free to message me on GitHub or something

10:44 rhickey: chouser: I'm working on a non-magic solution to that stuff right now

10:45 something like :mixin [(impl-X ...) (impl-Y ...)]

10:45 chouser: rhickey: ok

10:45 ah! sounds nice

10:45 spariev: joshua-choi: oh, thanks

10:45 rhickey: where impl-X and impl-Y generate forms for use in body, that get spliced in

10:46 can be passed names of fields

10:46 or anything else they need

10:46 just trying to figure out how to make the basic cases small, also how to avoid lots of repetition of field list

10:47 since many mixins will need it, also the class name or some recipe for self-construction

10:49 all without replacing one set of magic with another :)

10:49 chouser: heh, right.

12:18 wthidden: can an un-interned symbol have meta data?

12:19 hiredman: symbols are not interned

12:20 ,(identical? 'a 'a)

12:20 clojurebot: false

12:22 wthidden: so symbol 'silly can't have any meta data associated with it, correct?

12:22 hiredman: why not?

12:23 wthidden: then how?

12:23 hiredman: how do you normally attach metadate to something?

12:24 wthidden: not very well it seems at the momement.. would like to do it.. but need to go get lunch first.. be back in 30 min or so.

12:31 drewr: ,(meta (with-meta 'foo {:really 'bar}))

12:31 clojurebot: {:really bar}

12:39 duncanm: is there a variant of str so that (str-varient 1 2 3) => "1 2 3" ?

12:39 cuz (str 1 2 3) => "123"

12:40 chouser: pr-str

12:40 duncanm: thanks

12:40 rsenior: I'm having some difficulty using clojure.contrib.sql to do an insert into a column that does not have a standard integer or character value

12:40 it's a special oracle data type called "SDO_RDF_TRIPLE_S"

12:41 I've been able to do inserts using jdbc, but not clojure.contrib.sql

13:04 MononcQc: I'm thinking of picking up clojure, coming from Erlang (and some scheme) without any java experience. Is Stuart Halloway's book something I should seek out?

13:06 dakrone: MononcQc: I found his book very informative and useful

13:06 and I still refer to it occasionally

13:07 MononcQc: I had heard that clojure changed quite a while since it got out and otherwise it seemed to be very focused for people using Java

13:08 in fact it's pretty much as if every tutorial out there assumes the programmer has Java experience

13:08 stuartsierra: that's true

13:08 Clojure integrates tightly with Java.

13:09 It is not really intended to stand on its own.

13:09 At the very least, you'll need to be familiar with standard JDK libraries.

13:09 dakrone: in my opinion, learning Java from Clojure inter-op is easier than learning Java from Java

13:09 * nDuff thinks so too

13:09 MononcQc: egh, that's a bt annoying then. I wouldn't really feel like learning Java just to learn clojure

13:09 nDuff: easier environment for experimentation

13:10 MononcQc, Java-the-library is not nearly as annoying to learn as Java-the-language.

13:10 dakrone: you're not really "learning" it so much as leveraging a really bit library base

13:10 *big

13:10 technomancy: MononcQc: it's true to a degree; the example project in Programming Clojure doesn't make a lot of sense without prior experience on Java

13:10 MononcQc: yeah. I guess knowing the libs will be useful for whenever I do have to learn the language itself

13:10 technomancy: but I found the rest of the book to be helpful even with zero Java experience

13:10 hiredman: it's not like java is hard to pick up

13:11 chouser: I had barely ever used java before I started learning clojure.

13:11 dakrone: it's possible to avoid Java almost entirely with Clojure, but you'd be missing out on a lot of well-done stdlib sort of functions

13:11 MononcQc: Oh, I'm just relatively busy writing my own book about stuff, so I try to save time where I can ;)

13:11 doesn't mean I won't try and go around that

13:11 dakrone: what are you writing about?

13:11 MononcQc: http://learnyousomeerlang.com

13:12 dakrone: cool

13:13 rickmode: I have a simple question related to this paste: http://paste.lisp.org/display/95972

13:13 MononcQc: I was mainly thinking of learning clojure to see the concepts and then probably work with incanter (I plan on buffing up on stats and whatnot) and Erlang's pretty bad at that.

13:13 But I don't know, I'm kind of thinking R would be fine for the stats too

13:13 defn: Clojure *can* be done without knowing any java, but in the end you'll need Java. The most important thing is to just be able to read javadocs.

13:13 rickmode: Seems like I should using a closure around the sever returned by run-server rather than a global

13:13 defn: If you can do that you'll be able to do most of what you need to do in Clojure.

13:13 rickmode: thoughs?

13:14 nDuff: for my purposes, R's library is more complete than what's available for Incanter presently

13:14 MononcQc: defn, I'm usually alright with reading docs, so it'd not be too bad

13:14 I like docs.

13:14 * nDuff needs ready-to-use curve fitting algorithms, and Incanter appeared to lack them last he looked.

13:15 MononcQc: also the GUI programming seems to be pretty interesting with Clojure, rather than Erlang's WX drivers

13:17 I guess I'll get Stuart's book. Any other interesting guide?

13:19 dakrone: the video presentations by rhickey on blip.tv would be good

13:19 rickmode: I agree - the videos on clojure.blip.tv were great - especially the first two

13:20 technomancy: there's also the peepcode video, which doesn't assume any Java experience

13:20 (disclosure: I wrote it)

13:20 nDuff: there are a few books in the MEAP program from Manning Publications, but they're unfinished as of yet, so not so good for anyone in a hurry.

13:20 Raynes: technomancy: No vested interests here. ;)

13:20 MononcQc: technomancy, that would be interesting to me

13:21 dakrone: technomancy: peepcode charges for those, right?

13:21 MononcQc: well I'm alright with people linking to their own stuff given I linked to my own in Erlang :B

13:21 technomancy: yes, it's $9 for an hour-long video

13:21 dakrone: technomancy: I'm curious, do you get a pretty good % of the proceeds for that?

13:21 technomancy: dakrone: yes, peepcode is very generous as a publisher.

13:21 dakrone: that's good to know

13:22 technomancy: the video from around the clojure 1.0 days, but the only thing that is obsolete is the segment on building your project.

13:22 MononcQc: uh, that sounds important

13:22 technomancy: yeah, but there's a good video on Full Disclojure that does a good job of explaining the up-to-date way to do it.

13:22 and it's free

13:23 MononcQc: I see.

13:23 rickmode: $ lein new my-project

13:23 technomancy: http://vimeo.com/8934942

13:23 dakrone: oh yea, the full disclojure series is good: http://vimeo.com/channels/fulldisclojure

13:23 technomancy: +1

13:23 Raynes: +2

13:24 MononcQc: ah that looks good

13:25 powr-toc: I know you guys are probably gonna beat me up for this... but is there a way to reload namespace from a file? i.e. I want to ship a product with some default configs in a namespace foo.config, but if the user includes a config.clj in that defines a namespace called foo.config, I want to allow the redefinition of the specified vars

13:25 dakrone: and free :)

13:25 chouser: reloading namespaces is nothing to be ashamed of

13:26 pdk: we won't tell your parents

13:26 powr-toc: pdk: lol

13:26 chouser: I think 'load' is what you want, or perhaps 'load-file'

13:26 powr-toc: chouser: ok... how do I stop it bitching about the vars being already defined?

13:26 chouser: I'm using load-file right now

13:26 chouser: hm... something's not right.

13:27 what's the error?

13:28 powr-toc: chouser: "Name conflict, can't def *foobar* because namespace: foo.main refers to:#'foo.config/*foobar*

13:29 rickmode: Any takers on my global question? http://vimeo.com/channels/fulldisclojure

13:29 powr-toc: essentially I want to provide the option of overriding a few configuration constants... And I want to refer to those constants in other namespaces

13:29 rickmode: sorry http://paste.lisp.org/display/95972

13:29 chouser: powr-toc: oh, that's something else...

13:30 rickmode: I'm wondering if there's a more idiomatic way to capture the result of an expression between two function calls

13:30 chouser: hm... hmm... try: (binding [*ns* (find-ns 'foo.config)] (load-file ...))

13:30 MononcQc: thanks for the help.

13:31 chouser: rickmode: yeah, don't use 'def' inside a function like that. Best would be to have whoever calls jstart store the value and pass it to jstop

13:32 but if you're really sure you'll only ever have one *server* per JVM and don't want to make your user do that, you could have *server* be an atom or ref.

13:32 lunch. bbl.

13:32 rickmode: chouser: the use of *server* should be internal something only jstart and jstop care about

13:33 I'm trying to break out my OO thinking....

13:34 powr-toc: chouser: ahh it's ok... I think it works... During refactoring I'd forgot to remove some symbol definitions from my foo.main namespace

13:34 they were clashing

13:34 dakrone: rickmode: I annotated it with a suggestion, but I don't know about the correctness of it

13:34 it's kind of a weird way to do it

13:37 rickmode: dakrone: I was wondering if there was something like (let [foo nl] (defn func1 [] (set! foo "a")) (defn func2 [] (printf foo)))... basically use a closure of some sort to capture something in func1 to be used later by func2. In my case (the compojure case) there is very likely only one *thing* at any one point.

13:37 powr-toc: chouser: is that kinda namespace/config overriding bad style?

13:38 chouser: It's pretty much the first thing that my code does...

13:39 dakrone: rickmode: I was trying to avoid mutating any kind of state in my example

13:43 rickmode: dakrone: well I dont' really need mutable state. what i need is to use the output of one later in another... *and* hold this expression within a file. The alternative would be to force the caller of jstart to do something like (def *server* (jstart)) then later (jstop *server*).

13:44 dakrone: I'm afraid I don't understand, you need the server declared in jstart as well as what else?

13:47 rickmode: really I just want to hold some state internal to one namespace

13:47 private global state ... such that use of jstart and jstop does not expose this internal state

13:48 and it seemed like the use of a global, while possible, might not be the best approach

13:48 dakrone: so, the example I annotated keeps the server between the jstart and jstop functions, but doesn't expose it as a global

13:49 rickmode: dakrone; looking (attempting to grok...)

13:55 dakrone: rickmode: off to lunch, hopefully the annotation is self-explanatory

14:02 jcromartie: OK so one of the best selling games on Steam is Java...

14:02 nteon: how can I check out the Java code gen-class is producing?

14:02 jcromartie: that should be inspiring to anybody wanting to try games in Clojure

14:04 hiredman: nteon: it doesn't produce java code, it generates bytecode

14:04 hoeck: nteon: use sth. like http://java.decompiler.free.fr/ on the generated .class files

14:13 jcromartie: where's somnium when you need him

14:15 rickmode: dakrone: i see where you solution is going, however evaluating your version of jstop causes the server to start since it defines itself as the evaluation of jstart

14:24 nteon: hiredman, hoeck: thanks, that of course makes sense. I suppose my problem is that I want to make the equivalent of a static method in clojure which I can call from java

14:28 hiredman: sure

14:29 you just add :static true to the metadata of the method signature in the gen-class form

14:32 hoeck: nteon: maybe this helps too: http://berlinbrowndev.blogspot.com/2009/03/java-clojure-interoperability-calling.html

14:50 konr: I've got a (defn play-mp3 [file]). How can I call it to play an mp3 file inside the jar, and how can I include such mp3 file?

14:51 jcromartie: konr: just include it in the jar, and use resource loaders to find i

14:51 it

14:53 konr: jcromartie: hmm, but how can I include it using lein, for example?

14:53 tomoj: lein will automatically include everything in resources/

14:54 jcromartie: resources

14:54 ^what tomoj said

14:54 standard java junkz

14:55 classes and resources

14:55 tomoj: then you can use (.getResourceAsStream (clojure.lang.RT/baseLoader) "filename")

14:55 jcromartie: hm, maybe a (resource name) function could make it into clojure core at some point

14:56 tomoj: at least contrib

14:56 konr: thanks, guys!

14:57 tomoj: a function for serving up resources from a root based on a path and not allowing functions outside the root would be nice too

14:57 er

14:57 not allowing resources outside the root to be returned, I mean

15:03 joshua-choi: That's weird

15:03 According to clojure.org/reader, symbols "can contain alphanumeric characters and *, +, !, -, _, and ?".

15:03 But what about -> and ->>?

15:05 hiredman: ,(let [♥ 1] ♥)

15:05 clojurebot: 1

15:05 chouser: and > < >= <= = == / ?

15:07 hiredman: ,(let [x 1 x

15:07 clojurebot: EOF while reading

15:07 hiredman: er

15:07 ,(let [x 1 x′ (inc x)] x′)

15:07 clojurebot: 2

15:08 * _fogus_ reading http://onclojure.com/2010/03/05/pre-and-post-conditions-a-quest-for-a-nicer-syntax/

15:12 joshua-choi: hiredman: Yeah, I know that currently all non-indicator Unicode characters are allowed in symbols

15:13 But it seems that Rich Hickey made an informal limitation on symbol characters in clojure.org/reader

15:13 But that rule doesn't allow -> and ->>, which is weird

15:14 I needed to know if < and > are allowed in symbols or not; since -> and ->> exist, I guess they are, and there's no danger of < and > becoming indicator characters in the future

15:15 hiredman: joshua-choi: indicator?

15:16 joshua-choi: Like (, [, ^, #, etc.

15:16 Reader macro characters

15:16 hiredman: reader macro I understand

15:16 joshua-choi: I suppose http://clojure.org/reader just needs to be updated

15:17 To allow < and > in symbols too

15:18 * hiredman likes to use <foo> for structs

15:18 joshua-choi: I'm planning to use <foo> in my parser's rules

15:19 By the way, how do you do that IRC thing? "hiredman

15:19 likes to use <foo> for structs".

15:19 hiredman: /me

15:20 * joshua-choi is testing this out

15:20 joshua-choi: Cool

16:37 * joshua-choi thinks clojurebot is very cool

16:38 jcromartie: only the best languages can claim an IRC bot that speaks that channel's topic language :)

16:39 In fact that's pretty much my main criteria for choosing a new language to leanr.

16:39 (joking)

16:49 the-kenny: jcromartie: Then you should choose clojure. It's the language of the future - When clojurebot became skynet

16:49 clojurebot: skynet

16:49 clojurebot: I will become skynet. Mark my words.

16:50 jcromartie: OH GOD NO

16:50 I'm kind of surprised there's no equivalent bot in #ruby

17:01 rads: is there a way to prevent the REPL from printing a line?

17:02 Raynes: (remove #(= \n) s) ;p

17:02 rads: I mean if I'm evaluating a form and I don't want it to be printed out in the REPL

17:03 bsteuber: ,(do 42 nil)

17:03 clojurebot: nil

17:03 rads: bsteuber: that works, thanks

17:20 derefed: does clojure have something similar to python properties?

17:21 hiredman: what are those?

17:23 derefed: something like accessor methods

17:23 like

17:23 I want to be able to retrieve a piece of data from a clojure struct

17:23 jcromartie: you can use keywords

17:23 hiredman: structs are just maps

17:24 jcromartie: ,(:foo {:foo "bar"})

17:24 clojurebot: "bar"

17:24 the-kenny: ,(get {:foo "bar"} :foo)

17:24 clojurebot: "bar"

17:24 the-kenny: ,({:foo "bar"} :foo)

17:24 clojurebot: "bar"

17:24 derefed: but later on, if I decide that the implementation of getting a particular value from the struct should change, I don't want to have to change all the calling code

17:24 the-kenny: Three ways to access the data :)

17:24 jcromartie: ,(-> {:foo {:bar "bat"}} :foo :bar)

17:24 clojurebot: "bat"

17:24 derefed: yeah I know

17:24 I wasn't finished ;)

17:24 hiredman: derefed: then write a function

17:24 derefed: right but

17:24 hiredman: but what?

17:24 derefed: not finished

17:25 gimme a minute lol

17:25 I don't want it to devolve into making an accessor function for everything like in java

17:25 hiredman: java has methods not functions

17:26 derefed: you're splitting hairs

17:26 hiredman: I am not trying to be pedantic there, it is a reminder that clojure is not java

17:26 derefed: I mean in clojure, writing accessor functions

17:27 what I want is the power of accessors without the ceremony of typing each and every one out like in java

17:27 does clojure have something like that?

17:27 dakrone: isn't that what doing (:foo {:foo "bar"}) is?

17:27 derefed: no

17:28 with a bare accessor, yes

17:28 hiredman: dakrone: he wants an additional layer of indirection in case he desides to change the name of the :foo key

17:28 derefed: but later on I may decide to add logic to the retrieval

17:28 hiredman: lisppaste8: url?

17:28 nuts

17:28 dakrone: I'm not familiar enough with python, how does python do it without writing a method?

17:28 derefed: not because I want to change the name, but the logic in the retrieval

17:29 well

17:29 hiredman: derefed: logic should be in functions

17:29 derefed: you still have to write a method

17:29 dakrone: so what's wrong with (defn get-foo [m] (:foo m)) then?

17:29 derefed: but callers don't have to change their code to call that method if they were just grabbing the value originally

17:29 hiredman: right I'm not arguing with that

17:30 for instance

17:30 hiredman: derefed: then go forth and write functions

17:30 jcromartie: I can't seem to serve up a PNG image from compojure

17:30 derefed: in python, say you had a class Foo

17:30 hiredman: jcromartie: are you using the correct mime-type

17:30 jcromartie: I set the Content-Type header but the browser interprets it as a document

17:30 derefed: and an object of Foo, f

17:30 and it had a member variable bar

17:30 jcromartie: it looks like a charset is getting tacked on

17:30 hiredman: derefed: no classes, no objects

17:30 a struct is a map

17:30 derefed: hiredman: I'm talking about python

17:30 jcromartie: :headers {"Content-Type" "image/png"}

17:31 derefed: hiredman: I'm explaining it to dakrone

17:31 in python you could say f.bar = 100

17:31 and it would just set bar

17:31 but later on, you could add a property, or accessor method

17:31 let's say the new setter just adds 10 to the incoming argument before setting bar

17:32 so I write the method to perform the + 10

17:32 but instead of having to change the caller to this: f.setBar(100)

17:32 I can leave it like this: f.bar = 100

17:32 jcromartie: (defn assoc-bar [x bar] (assoc x :bar (+ 10 x)))

17:33 konr: Is it particularly bad to slurp a 10-100MB file? Should I use open it as a Stream?

17:33 jcromartie: because you don't really set, unless it's a ref/var/atom

17:34 derefed: right but what I'm getting at here is that I can go from directly accessing the value to providing a layer of logic WITHOUT having to change what the caller does

17:34 jcromartie: hiredman: I'm getting this header in the actual response: Content-Type:image/png; charset=UTF-8

17:34 rads: derefed: you just use a function

17:34 dakrone: so it sounds like syntactic sugar for doing something like (defn get-foo ...), correct?

17:35 derefed: no

17:35 * joshua-choi too finds it somewhat annoying that keywords as functions are not overridable for types' attributes, but doesn't see a good way out

17:35 hiredman: jcromartie: what makes you think the charset bit is the problem?

17:35 jcromartie: hiredman: because I get the right data back, but the browser/curl interprets it as utf

17:35 derefed: joshua-choi: yeah I think that's what it'd have to be... overridable keyword functions

17:35 dakrone: how is it not? behind the scenes it's doing the same thing calling a function before setting the value

17:36 rads: derefed: (defn get-foo [m] (:foo m)) / if you want to change the logic, you just change the function

17:37 you could write a macro to define it for you but you don't end up needing it too much

17:37 joshua-choi: The problem is, that's not the default

17:37 rhickey: keyword accessors explicitly say - the data is the interface. If you want something else to be the interface, write functions or use a protocol in the first place. If you always want the flexibility to change things, always use functions

17:37 derefed: dakrone: it's not that it makes the programmer avoid typing out the (defn), it's that it makes the caller avoid changing how he retrieves values

17:37 hiredman: if you want a function, write one, maps(structs) are datastructures(containers) meant to be operated on by functions

17:37 derefed: dakrone: it is syntactic sugar, but not for defn I guess is what I mean

17:38 dakrone: okay, so in that case, you're going to end up having to create a function for it

17:38 derefed: rhickey: so there's no sort of shortcut like python does with properties?

17:38 dakrone: I don't think that (having the suger) fits into the kind of paradigm Clojure promotes for that datatype

17:39 derefed: probably not

17:39 I'm still trying to figure out how to do the things I do in clojureworld ;)

17:39 bsteuber: defered: I think you're trying to do what everyone else here does - try to map the clojure world to the concepts you know

17:40 derefed: true

17:40 bsteuber: but actually there is not always a mapping, and in fact you don't need it, because clojure solves the deeper problem differently

17:40 derefed: I guess I just don't know any other way

17:40 jcromartie: so is there a way to NOT set the charset in Compojure?

17:40 because I think it's kinda messing me up here

17:40 hiredman: derefed: a few people have told you to write functions

17:41 over and over

17:41 derefed: right but in my eyes that isn't solving the problem

17:41 I'm interested in seeing how clojure does it differently

17:41 rhickey: for public interfaces, using keywords might not be a good idea. Just because they are there doesn't make them the right thing in all cases. In practice, properties/getters are rarely redefined, but if you do that often you might want a protocol for the outer interface

17:41 derefed: but until a few minutes ago I felt like you guys didn't understand what I meant so I kept going

17:42 bsteuber: maybe you should give us some more details about the problem you actually want to solve using accessors

17:42 I mean, you can give some code snippets or stuff

17:42 derefed: there is no concrete problem

17:42 I'm trying to figure it out before I go in coding

17:43 hiredman: bsteuber: it doesn't reall matter, the answer is write functions

17:43 rhickey: one thing about morphing keywords into getter fns is whether or not the entire map interface morphs as well, e.g. contains?, dissoc etc

17:43 derefed: I just know that I use interfaces a lot and find it convenient to be able to change the logic in the interface

17:43 hiredman: you want to reach into a datastructure and pull out data, write functions

17:43 bsteuber: hiredman: yeah, I think you're right

17:44 but I think for most cases, directly using a keyword is

17:44 fine

17:44 dnolen: derefed: also I wrote this, http://github.com/swannodette/accessors

17:45 rads_: derefed: (defn foo [m] (:foo m)) is equivalent to an accessor with no logic. if you do this a lot, a macro for defining them would be pretty trivial

17:45 dnolen: derefed: however nobody seems interested in this functionality

17:45 it's automatically generates setters and getters.

17:45 you can free provide your implementation for a particular property to override the default

17:45 bsteuber: I'd probably just start with trivial functions and refactor if I happen to change implementation somehow

17:46 derefed: dnolen: yeah, that's basically what I was looking for

17:46 bsteuber: I mean, just use the data structures clojure gives you and don't think of replacing them unless needed

17:47 derefed: bsteuber: right, but I'm just afraid about what will happen when I do need to replace them

17:47 bsteuber: but will you?

17:47 rads_: in practice you don't have to replace them too often

17:47 derefed: and all the code previously written depends on the old stuff

17:47 bsteuber: also, there's refactoring

17:48 derefed: I don't know I've run into it before... I guess it doesn't happen often but it happens

17:48 bsteuber: yeah, but are you really calling this from a hundret places?

17:48 derefed: no but still

17:49 even if you have to change ten places

17:49 doesn't that go against The Right Way?

17:49 seems like it goes against everything I've learned about lispy programming

17:50 rads_: if you expect the interface to change you should use a function, not the keyword, like rich said

17:50 derefed: I agree

17:50 I was just wondering if there was a shortcut like properties

17:50 dnolen's library looks like the answer

17:50 I guess now I'm wondering what you guys do

17:50 hiredman: I write functions

17:51 dnolen: and my accessors library writes those functions for you, it's really a matter of style

17:51 bsteuber: and I don't care unless I'm sure I'll want change it

17:51 hiredman: upon functions, ye until seven orders of functions

17:51 dakrone: it seems like one of those trying design before you have a problem things

17:51 bsteuber: and have unit tests that save my ass in that case :)

17:52 hiredman: dnolen:

17:52 rads_: if you don't need the flexibility of dnolen's library, writing a macro to generate getter functions is pretty trivial

17:52 hiredman: sure

17:52 derefed: hiredman: so do you have to write out get-foo, get-bar, etc. etc. for all the data structure interfaces?

17:52 rads_: I suppose I could do that too

17:53 hiredman: derefed: depends, I think mostly I use keywords

17:54 derefed: have you ever run into a situation where you had to change from keyword access to function access?

17:54 jcromartie: hiredman: looks like it was a deficiency in my understanding of curl, after all :P

17:55 hiredman: derefed: there have been times when I have written functions instead of using keywords

17:56 I think the key point here is clojure datastructures don't have behaviour outside of their datastructuryness

17:56 derefed: good point

17:56 hiredman: your data just flows in and out of them, manipulated by functions

17:57 don't expect the datastructures to do stuff

17:57 derefed: well I think you guys have given me some good stuff to think about... thanks for all your help

17:58 rads_: I do usually write a setter function for changing mutable data

17:58 but since you don't have too much mutable data in clojure you don't need those setter functions often

17:58 * derefed nods

17:59 rads_: and if for example you wanted to add 10 every time you accessed a field, you would just add 10 when you create the data structure

18:01 dakrone: derefed: good luck with your clojure projects, hope you stick with it :)

18:02 derefed: thank you -- oops he left

18:06 bsteuber: btw. is there any way to attach hooks to refs?

18:06 so that thay do something I specify when they change

18:06 I mean obviously I can def my own dosync-with-hook-xy

18:06 but I wondered if there's something builtin

18:08 hiredman: ,(doc add-watch)

18:08 clojurebot: "([reference key fn]); Experimental. Adds a watch function to an agent/atom/var/ref reference. The watch fn must be a fn of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference's state might have been changed, any registered watches will have their functions called. The watch fn will be called synchronously, on the agent's thread if an agent, before any pending sends if agent or ref. Note that

18:10 bsteuber: thx

18:20 * robink is having difficulty building fnparse because it can't find the clojure.lang.Compile class.

18:21 hiredman: last I checked it didn't need building

18:21 you can just jar up the source

18:21 you can also just grap the jar from clojars and forget about it

18:22 robink: Heh, OK

18:22 I'd like to try to build the jar.

18:22 It's good practice (I run Gentoo)

18:23 hiredman: that's too bad :)

18:23 anyway, I think the guy who wrote it uses netbean's build stuff

18:23 so the best bet is for you to go compile netbeans :)

18:23 robink: Heh, hm

18:24 I could try

18:25 hiredman: robink: I'm telling you, jar -cvf fnparse.jar -C src/ . is all you need

18:25 this could all be over, and you could quit shaving yaks right now

18:26 robink: must...shave...yaks!

18:39 hiredman: robink: what benefit do you think you are going to get compiling vs. just jaring up the source? or even just grabing a jar from clojars?

18:45 * joshua-choi did not know that FnParse was on Clojars

18:45 robink: hiredman: Compiling a jar would make it faster than just bundling the source. Grabbing a jar from clojars would work just as well but then I'd be stuck the next time I needed to build a Clojure app with ant.

18:46 hiredman: robink: the speed difference is almost nothing

18:46 and only at load time

18:46 robink: hiredman: It may end up running on embedded hardware.

18:46 hiredman: Load time is still a small factor.

18:46 hiredman: fnparse's ant setup is very different

18:46 robink: Oh, OK

18:46 hm

18:47 hiredman: it is basically a bunch of ant xml generated by netbeans as far as I know

18:47 I don't know of any other clojure project that uses that

18:48 robink: hiredman: Ah, OK

18:48 hiredman: almost everything is using lein these days except for some larger older projects

18:48 rickmode: lein is mean

18:49 robink: I don't like Maven

18:49 hiredman: joshua-choi: you can namespace stuff you upload to clojars so it is possible to publish a jar there even if you aren't the maintainer

18:49 robink: I've been trying to wrestle with it to only use distro-installed dependencies.

18:49 joshua-choi: Just wondering, what version of FnParse did you build?

18:49 robink: git trunk

18:50 hiredman: joshua-choi: it claims to be 2.2.4

18:50 joshua-choi: Okay

18:50 hiredman: I try not to think about it :)

18:51 http://clojars.org/org.clojars.hiredman/fnparse

18:51 joshua-choi: I see; that's nice

18:51 I'm worried though that I'll cause some confusion when I wrap up FnParse 3

18:52 Oh well

18:52 hiredman: well the version number is right there

18:52 joshua-choi: Oh, right, it is :P

18:52 hiredman: and you could push a cannonical fnparse to clojars

18:52 joshua-choi: How does that work? Canonical libraries on Clojars

18:53 hiredman: they aren't namespaced

18:53 http://clojars.org/lein-gae

18:53 * hiredman hangs head in shame

18:54 robink: There we go

18:54 joshua-choi: Oh, I see

18:54 robink: Compiled

18:55 Installed

18:56 hiredman: actually, fnparse is leiniszed these days, so "lein jar" will build and jar it

18:56 robink: Ah, OK

18:59 nteon: heh, leiniszed

19:01 robink: I met the guy who wrote leiningen

19:01 hiredman: I was there :P

19:02 robink: hiredman: Oh! Hi!

19:03 hiredman: I was the one in green

19:03 on the otherside of the guy with the n900

19:04 robink: hiredman: Right. Well immediately opposite the guy with the N900 was Phil, right?

19:04 Were you to Phil's right?

19:04 technomancy: robink: hi. =)

19:04 robink: !

19:04 technomancy: <= phil

19:04 robink: Hi :-)

19:04 Wow, this is cool

19:04 hiredman: no no

19:04 robink: technomancy: Yeah, I know.

19:04 hiredman: OK, I think I remember you now.

19:05 hiredman: not on the otherside of the table

19:05 robink: Oh, gotcha

19:05 Yeah, OK

19:05 technomancy: ascii-art diagram?

19:05 hiredman: robink | n900 | hiredman

19:05 robink: hehe

19:05 I get it

19:06 and then opposite going the same direction (N, not R) was Brian, technomancy, guy-whose-name-i-can't-remember

19:06 and then the guy who showed up later.

19:07 hiredman: the shaver

19:07 robink: No, he was to Brian's...wait, oops

19:08 OK, towards the back of the coffee shop is N, right?

19:09 Oops, that's S

19:09 hiredman: oh, right, the other guy who came later

19:09 robink: Yeah.

19:10 Awesome, lein errored on me.

19:10 Maven just sucks in a dependency if it thinks you don't have it.

19:11 lein is doing exactly what I want it to do. Not sure why the clojure POM file is missing.

19:12 Oh, huh, it's a Maven thing

19:12 Still, leiningen is behaving more like what I want.

19:13 Which is to never (ever) pull in a dep

19:13 technomancy: deps only get pulled in if you explicitly ask for them or if the lib/ dir is empty IIRC

19:14 so you don't have to always remind it to stay offline like you do with mvn

19:14 robink: Oh, good

19:14 Not sure where I get a Clojure POM file.

19:14 technomancy: lein pom

19:14 robink: Hah

19:14 technomancy: what do you need it for?

19:14 robink: Awesome

19:15 When I do 'lein jar' on fnparse, it says it needs the Clojure POM file.

19:15 Clojure was installed by MacPorts, not Maven.

19:15 Same POM error

19:17 Could be an issue with the way fnparse's project.clj is written.

19:18 Ah, fixed

19:18 Ack!

19:18 It's trying to install Clojure!

19:18 hiredman: sure

19:18 if it depends on it, it will grab it

19:18 technomancy: clojure dependencies aren't system-wide like rubygems or apt-get

19:19 robink: I thought it would check the root fs and classpath for something ...oh

19:19 That's...bothersome

19:19 It's going to make writing an ebuild tricky.

19:20 technomancy: yeah, debian builds of JVM tools are notorious for that reason.

19:20 robink: Of course I can just use ant with fnparse, but Compojure is all Maven-based, and Maven definitely wants to pull something in if it thinks it's missing.

19:22 The Java-hosted languages are new to Portage, generally, so there's not a whole lot of infrastructure to support them.

19:23 I imagine eventually it might be possible to have a 'baselayout' or -common ebuild for these guys so that you could hint Maven to where things truly were.

19:23 Maybe folded into the main ebuilds themselves, I'm not sure.

19:23 hiredman: uh, unless it changed very recently compojure is not maven based

19:24 robink: hiredman: No, it's not, but Maven doesn't think it exists.

19:24 hiredman: There has to be a way to tell Maven "Compojure is here!"

19:24 hiredman: Without installing another concurrent copy.

19:25 hiredman: robink: that has nothing to do with maven

19:25 robink: hiredman: Well, no, but it has to do with the build process that ultimately involves Maven.

19:25 hiredman: I think you are conflating lein and maven because lein uses some of mavens machinery

19:26 robink: hiredman: No, I see that Lein is better.

19:26 hiredman: but they are not the same thing

19:26 technomancy: some of the leiningen output makes it looks like it's coming from maven. that should be cleaned up.

19:27 robink: technomancy: OK

19:28 hugod: technomancy: I have a prev/next problem implementation for clojure test mode, and a working run test at point

19:29 technomancy: hugod: nice! I will pull tonight.

19:29 hugod: ok, I'll fork and push to a branch

19:30 technomancy: if you would rather just mail a patch that's fine too

19:30 hugod: ok, can do

19:47 nteon: can anyone suggest a more lispy form for this function? http://fpaste.org/9Y7i/

19:50 ah! ->

19:50 hiredman: ,(assoc {} :a 1 :b 2)

19:50 clojurebot: {:b 2, :a 1}

19:50 _ato: nteon: assoc can take many arguments

19:51 nteon: _ato, yes but in my silly example i need to refer to the value of :time-step in d to generate e.

19:56 _ato: I'd probably just do: http://gist.github.com/323376

19:59 oh wait, are you trying to set the save-step to the previous time-step?

19:59 (in which case your code has a bug)

19:59 nteon: _ato: no, not the the previous

20:01 _ato: I think I like what you outlined in that gist, thanks

20:52 defn: _ato!

20:52 You're back!

20:53 I have a question-- I'm pulling tweets from the "firehose" and I'm wondering if it's possible to conditionally return items during the execution of a function

20:54 in english: im consuming some massive sequence, is it possible to return items which match a condition, and still continue consuming the sequence? how do you do that?

20:55 technomancy: if you return a lazy sequence, the caller of your function can read the first few elements of the seq while later elements are still being processed

20:55 is that what you mean?

20:56 defn: maybe... im trying to understand what you're saying there

20:57 okay, yeah that sounds kind of like what im thinking

20:57 I was just sort of imagining a console where this sequence is being consumed, and whenver it finds something that matches X, it returns that match, and continues to consume

20:57 what you're saying makes sense

20:58 technomancy: if "consuming" has side-effects then you probably don't want to mix it with laziness though

20:58 defn: yes i was just considering that :)

20:58 technomancy: what about sending matching elements to an agent instead of returning them?

20:58 defn: that's a great idea

20:58 thanks technomancy

20:58 technomancy: np

21:03 nathanmarz: anyone know if "fine-grained locals clearing" is available in 1.1? (http://groups.google.com/group/clojure/msg/9b4e268b85c20cd6)

21:05 technomancy: nathanmarz: pretty sure it's not.

21:07 nathanmarz: is the plan to get that into 1.2?

21:07 technomancy: it's in the 1.2 snapshot, yeah

21:07 nathanmarz: cool

21:07 gratzi

21:22 konr: Is there a function that prints a number like 1234567.89 as 1,234,567.89?

21:23 hiredman: ,(doc pprint)

21:23 clojurebot: "([object] [object writer]); Pretty print object to the optional output writer. If the writer is not provided, print the object to the currently bound value of *out*."

21:25 konr: hmm, cl-format does the trick too... should have checked before: (cl-format nil "~:d" 1234567.89)

21:53 tomoj: suppose you inherit a bunch of clojure code that's written with variable names in some foreign language

21:54 defn: suppose the internet has translators available

21:55 tomoj: can you automatically correctly rename them? not doing automatic machine translation, but just prompting you for a translation once per unique name needing to be translated?

21:55 defn: i highly doubt it

21:55 consider rand vs random

21:55 tomoj: how is that a problem

21:55 defn: rand-var vs random-variable

21:55 tomoj: I still don't understand how that is a problem :(

21:56 defn: rand isnt a word in either language?

21:56 tomoj: yeah, so what

21:56 defn: so how do you automatically rename that

21:56 tomoj: if "splurgenfrach" means "random" and they just write "splurg", that's ok

21:56 hiredman: I don't think you understood what he said

21:56 tomoj: I don't think so either

21:56 hiredman: he wants a refactoring tool

21:57 tomoj: I mean, now I can't really think of any big problems

21:57 but I feel like there would be tricky issues

21:57 defn: 80/20

21:58 hiredman: it woudl be tempting to read in the code as a datastructure and manipulate symbols

21:58 but you would lose formating when printing it back out

21:58 defn: im going to be the naysayer and say that it's completely impossible to write a good tool for that

21:58 tomoj: hmm

21:58 I think losing formatting might be OK

21:58 defn: the edge cases will continue to erupt

21:58 hiredman: defn: I think you could write a tool that did a decent job

21:59 tomoj: as long as you can walk the data structure and the raw code in parallel

21:59 defn: maybe...

21:59 tomoj: need a new reader to do that?

21:59 hiredman: :D

21:59 I happen to have a read written in clojure

21:59 reader

21:59 defn: i just have a hard time imagining a tool which could accurately refactor within a single lnaguage (english) let alone 10 of them

21:59 it would be a mess

22:00 tomoj: the only thing you'd need to match with the raw code is the positions of the symbols

22:00 so you could stick that in the metadata maybe?

22:00 DuneMan: Fairly basic question (starting out with clojure today). I have a lein project.clj defined that includes clojure-1.1.0-master-SNAPSHOT and clojure-contrib-1.1.0-master-SNAPSHOT.

22:00 when I do lein "deps" the correct libraries are copied from my maven dir (~/.m2) into my project's lib.

22:00 hiredman: defn: you are getting to hung up on the "different language" thing

22:00 DuneMan: However, when I bring up a repl and do (System/getProperty "java.class.path") both the clojure and clojure contrib jars show up in my classpath. However, doing a (require clojure.contrib.str-utils2) fails (or any other namespace that's supposed to be in clojure contrib).

22:01 tomoj: defn: it's really just variable renaming

22:01 hiredman: you want to rename all instances of symbol X in scope Y to W

22:01 tomoj: but doing it over and over again once per unique symbol

22:01 across a list of source files

22:01 DuneMan: (bringing up a repl using lein repl, to make sure the class path is correct)

22:01 tomoj: without changing the program

22:01 hiredman: I no stuartsierra really wants a namespace renaming tool

22:01 DuneMan: this also fails in VimClojure+Nailgun

22:01 tomoj: DuneMan: lein repl uses the clojure that leiningen has

22:02 ~/.swank-clojure I think

22:02 clojurebot: That is the one thing Clojure can not do.

22:02 hiredman: DuneMan: what version of contrib?

22:02 DuneMan: 1.1.0-master-SNAPSHOT

22:02 hiredman: in master a lot of stuff got renamed

22:02 DuneMan: same as the version of clojure

22:02 I've also tried it with 1.1.0, and 1.2.0

22:02 tomoj: do you even need to maniplate symbols?

22:02 DuneMan: (1.2.0 seems to make Vimclojure + nailgun not work at all)

22:02 tomoj: or can you just have something which scans the raw code looking for symbols

22:02 DuneMan: (\sr just stops doing anything)

22:03 oh, I'm also on MacOS.

22:03 tomoj: hmm, no, if you change a name, you must change it in every other file that references the symbol

22:03 "The repl task will use the version of Clojure and Contrib that Leiningen uses, not the one specified by your project."

22:04 I dunno if that's your problem, but

22:04 DuneMan: hm... that is interesting.

22:04 Where was that in the docs?

22:04 tomoj: on http://github.com/technomancy/leiningen

22:04 defn: DuneMan: change your includes to clojure "1.1.0"

22:04 tomoj: "known issues"

22:04 DuneMan: (one would think that the nailgun task would use the correct version)

22:04 defn: and clojure-contrib "1.1.0"

22:04 tomoj: one would indeed

22:05 lein-swank does

22:05 DuneMan: defn: That's what I had it as before, and had the same problem. I'll try again.

22:05 defn: those are a better bet than what you're using

22:05 tomoj: I think there are pretty difficult problems in that area of lein

22:05 defn: AFAIK no one has been using those snapshots for awhile

22:05 tomoj: subclassloaders oslt

22:06 yet lein new still generates a project.clj with them, correct?

22:06 defn: depends on what version of lein

22:06 tomoj: oh, I see, no

22:06 "1.1.0"

22:06 nice

22:07 DuneMan: yes, it generates them with 1.1.0

22:07 and yeah, same problem. Start nailgun, open vim, and get a huge slew of errors about not being able to find seq-utils

22:07 tomoj: DuneMan: how does it fail? pastie the error

22:07 and, which jar for contrib do you see in the classpath?

22:08 (the one in your project's lib/?)

22:08 DuneMan: lib/clojure-contrib-1.1.0.jar from my project's lib

22:08 #<CompilerException java.lang.Exception: No such namespace: seq-utils (parsers.clj:9)>

22:08 when doing \ef

22:09 Even though seq-utils is in the 1.1.x branch docs on github...

22:09 tomoj: how many contrib jars do you see in your lib dir

22:09 DuneMan: just that one. I blasted lib/

22:09 tomoj: well shit

22:10 DuneMan: it just makes no sense.

22:10 tomoj: oh

22:10 hehe

22:10 paste the exact code that's failing

22:10 DuneMan: I've been complaining about clojure all day because of this ;-) (stupid jvm)

22:10 tomoj: (require clojure.contrib.str-utils) ?

22:10 defn: does nailgun f--- with the classpath at all?

22:10 DuneMan: (ns beansprout.parsers

22:10 (:import java.util.Date

22:10 java.text.DateFormat)

22:10 (:require [clojure.contrib.str-utils2 :as string]

22:10 [clojure.contrib.seq-utils]))

22:11 slyphon: DuneMan: uh, pastebin?

22:11 DuneMan: defn: If it did one would think that doing (System/getProperty ...) within the nailgun repl would be getting the right classpath from the urrent jvm instance

22:11 tomoj: well, the contrib jar is on the classpath when he checks from the repl, yes?

22:11 yeah, exactly

22:11 DuneMan: it blows up on seq-utils?

22:11 DuneMan: slyphon: woop, sorry.

22:12 tomoj: yes. But if I'm in the repl and do a simple (require clojure.contrib.seq-utils) it also fails, also with (require clojure.contrib.str-utils2)

22:12 tomoj: those would naturally fail

22:12 DuneMan: why naturally?

22:13 tomoj: in (require clojure.contrib.seq-utils), the "clojure.contrib.seq-utils" is evaluated as a var

22:13 DuneMan: aha

22:13 tomoj: not sure I'm using the right words there

22:13 but, you need to quote when using require et al manually rather than through the ns macro

22:13 so (require 'clojure.contrib.seq-utils)

22:15 however

22:16 putting that code in src/beansprout/parsers.clj, it works fine for me

22:16 and I can see the functions that were pulled in

22:16 DuneMan: huh.

22:17 tomoj: can you pastebin/gist/whatever 1) the error you get when you try to load the code with the ns macro 2) the error you get when you (require 'clojure.contrib.seq-utils) ?

22:17 DuneMan: maybe my jvm install is screwed somehow

22:17 tomoj: are they the same?

22:17 DuneMan: When I do the latter I don't get an error, it returns nil (which I think means success?)

22:18 but then it says it can't resolve the symbol, e.g. flatten

22:19 ah...

22:19 tomoj: brandonw: hey

22:19 maybe you can help DuneMan :)

22:19 DuneMan: I have to fully qualify that.

22:19 tomoj: DuneMan: yes

22:19 and (require '[clojure.contrib.str-utils2 :as string])

22:19 hiredman: require doesn't make alias in the current namespace

22:20 DuneMan: yeah, already did that with :as string...

22:20 tomoj: then you should be able to (string/whatever)

22:20 use use if you want to just pull in all the functions

22:20 (but I don't like doing this)

22:20 except like (use '[foo.bar :only (baz bim bang)])

22:20 which will pull in baz, bim, and bang from foo.bar

22:21 DuneMan: Aha, so it was all because I wasn't FULLY qualifying that.

22:21 tomoj: lein-nailgun and/or vimclojure must be screwing up

22:21 but, you still get the error trying to load that file, right?

22:21 DuneMan: ... no.

22:22 *looks back at his old errors*

22:22 tomoj: oh, the error was only that you were referring to the functions incorrectly after loading the file?

22:22 DuneMan: No, the error I was getting was about not being able to find the seq-utils class file

22:23 But now... it appears to work magically?

22:23 tomoj: hah

22:23 well, grats

22:23 DuneMan: Thanks :-)

22:23 tomoj: you might feel the need to meditate deeply on the docs for ns, use, require, etc

22:24 they confused me when I was new to clojure

22:24 DuneMan: I've read them a few times now but I'm still very confused by them.

22:25 The language that is used to talk about these things are unfamiliar to me.

22:25 dnolen: DuneMan do you know Python?

22:25 DuneMan: yes.

22:25 dnolen: use -> import *

22:26 require -> import foo.bar

22:27 DuneMan: Ah, okay. And :import ~> from foo import bar (but only for java classes)

22:27 rickmode: duneman i've hit a similar thing with these... the language is correct but unfamiliar. A laymans writeup would definitely help. Something giving the "why" along with canonical / idiomatic usage to go along with the theory

22:28 DuneMan: Might be good to write up a blog post about it or somesuch, after wrestling with it for a day

22:28 took me forever to get lein working

22:28 tomoj: I plan to do that but with a focus on emacs

22:29 rickmode: I would like to see a unification of the java things with the clojure things so there isn't as much of a difference

22:29 things like import and the extra dot notation are a bit odd and smell like a hack. I could be wrong though.

22:30 tomoj: I kind of like the extra dot

22:30 because it shows clearly when you are using a function and when you are using some java method

22:30 rickmode: as far as the differences between ns, in-ns, use, requrire and refer, I am getting a feel for them after a few days

22:31 DuneMan: I think a lot of this is just normal stumbling through a new set of tools

22:31 tomoj: java methods will rarely (but maybe increasingly more often with 1.2.0 features?) behave in ways that make me want to think of them as functions

22:31 DuneMan: but it's particularly frustrating because its new language foo + the awful mess that working with the jvm always is.

22:32 tomoj: yeah :/

22:32 I think the jvm is overall a good thing though once you stumble through it

22:32 for clojure, I mean

22:32 DuneMan: Oh, it's a wonderful product, hotspot rocks, etc. Using it is... a pain, though.

22:32 tomoj: yeah

22:33 DuneMan: anyway, I think you helped me stumble into something that works...

22:33 tomoj: I think without an easy-to-interop-with host, clojure would suffer

22:33 rickmode: Part of the attraction of a lisp dialect and clojure specifically is the lack of unneeded syntax. Something like this: (.getCanonicalPath (File. "public" "main.css")) just feels odd in a lisp. How can I anticipate where the dots go?

22:34 tomoj: by understanding the interop syntax, I guess :(

22:34 rickmode: but it's a small thing... I am *totally* digging this language

22:34 tomoj: I think it's worth it, though, because I don't want jvm interop to look like clojure code

22:34 it should look different because it will likely not behave in clojure-ish ways

22:34 rickmode: tomaj: ah.. you are totally right... if it's different , emphasis the difference

22:34 tomoj: your clojure wrapper can still look clojure-ish

22:35 but when you are doing things that could be Evil, I think a different syntax is good

22:35 but the ability to do Evil is a great boon to clojure :)

22:36 rickmode: well so long as it doesn't reintroduce mutable collections... ;)

22:37 tomoj: that's the thing

22:37 all of the available options with good library support are Evil, I think

22:38 so unless you want to write everything from scratch, you're going to have to do interop with stuff that uses mutable collections or whatever

22:38 and as long as you're doing that, better to have a slighly different syntax for that stuff

22:39 hiredman: ,(macroexpand '(.foo bar))

22:39 clojurebot: (. bar foo)

22:39 hiredman: ,(macroexpand '(foo. bar))

22:39 clojurebot: (new foo bar)

22:44 DuneMan: btw, vimclojure = ghetto

22:45 vim is not meant to host a repl... and it works like it

22:45 heh

22:47 rickmode: thanks, hiredman... i honestly hadn't quote got the classname. syntax

22:48 er... quite got...

22:51 tomoj: DuneMan: slime... :P

22:51 DuneMan: Yeah... I don't know emacs... will probably need to learn it if I ever actually want to code in this.

22:51 tomoj: I think a lot of people use vim with success

22:52 (but personally I love slime/clojure-mode/lein-swank)

22:52 rsh: is there a good way to include free variables in macroexpansions w/o getting "can't use qualified name as a parameter" exception?

22:53 an intentional free variable, so a gensym will not work

22:53 tomoj: can you show what you're trying to do?

22:53 DuneMan: tomoj: Using the repl is painful... you have a vim buffer so doing movement expressions moves you within the buffer instead of doing readliney stuff

22:54 tomoj: ah, slime takes care of the readliney stuff very nicely in my opinion

22:54 DuneMan: yeah, emacs is good for this... it was designed for this

22:54 rsh: tomoj: is there a better way to show you a code snippit than pasting it directly in here?

22:55 tomoj: rsh: yes, any pasting service will do

22:55 gist, pastebin, whatever

22:55 I think the bot can help but I don't know how to ask it

22:55 clojurebot: paste?

22:55 clojurebot: lisppaste8, url

22:56 tomoj: rsh: anyway, I think I might understand your problem

22:56 consider this macro

22:56 rsh: tomoj: http://pastebin.com/5M7Cz1Q5

22:56 tomoj: (defmacro with-foo [& body] `(let [~'foo 3] ~@body))

22:56 (with-foo foo) macroexpands to (clojure.core/let [foo 3] foo)

22:57 rsh: yeah that is the same concept

22:57 tomoj: you need to syntax-quote the body of the macro

22:57 continuation framework?

22:57 rsh: yep!

22:57 thanks for your help

22:57 rickmode: I used http://paste.lisp.org/new/clojure earlier .. but you need to mention the URL here

22:57 tomoj: sounds interesting

22:58 tell us if you share it

22:58 dnolen: there's also clj-cont, http://github.com/swannodette/clj-cont, my port of the CL continuation library :)

22:58 never had a reason to use it yet tho :P

22:59 rsh: I saw that actually. Will probably take a look at it later after I play around with it some on my own to learn a little

23:00 dnolen: rsh: feedback appreciated. continuations are fun.

23:00 hiredman: lisppaste8 needs to be voiced

23:02 rsh: can someone explain to me or point me to some further reading why clojure has this issue with macroexpanding free variables into ns qualified names but common lisp macros do not have problems doing this?

23:02 DuneMan: okay, so... when I do (string/partition "a b c" #"\s")) I get: "java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number"

23:03 .... anyone have a clue why that would occur? partition takes 2 arguments, a string and a pattern.

23:03 according to all the web pages and (doc ...) [which, I'll note has a broken example]

23:04 dnolen: rsh: Clojure rules simply prevent you from shooting yourself in the foot. You can however accomplish what you want.

23:05 rsh: I see

23:07 tomoj: rsh: is ~' really so bad?

23:08 I quite like it, it makes unhygienic macros a bit harder to write

23:08 and the auto-gensyming makes up for it by making hygenienic macros easier to write

23:08 rsh: what would be the consequences of actually having a namespace qualified function parameter (if it were allowed)?

23:08 tomoj: s/hygen/hyg/

23:09 dnolen: rsh: it wouldn't make any sense.

23:09 tomoj: I don't even know what that means :(

23:10 dnolen: a namespaced qualifier would usually refer to some definition in a namespace, using that as a fn parameter name doesn't make sense.

23:10 tomoj: DuneMan: hmm

23:10 the example in the docs works for me

23:10 dnolen: what you want for =defn is (defn ~f [~'*cont* ~@parms] ~@body)

23:10 tomoj: (clojure.contrib.str-utils2/partition "abc123def" #"[a-z]+") returns exactly what the docs say

23:10 DuneMan: heh. The stars are not aligning says my coworker bob.

23:10 dnolen: rsh: I actually did PG cont stuff in Clojure as well.

23:11 tomoj: DuneMan: just wait a bit longer!

23:11 the stars will align after a while, I predict

23:11 rsh: dnolen: how did it work out?

23:12 DuneMan: haha. if I cut-n-paste the line that you just pasted, I get a classnotfound exception

23:12 wonderful

23:12 tomoj: DuneMan: yes

23:12 paste the whole file?

23:12 at least the ns declaration and the call to partition

23:12 dnolen: rsh: small tweaks here and there. had to use ~'. And you need to use an atom since you need *saved* to mutate.

23:12 tomoj: by paste I mean on some pastie webapp, of course

23:13 DuneMan: ah, I know what was wrong. I did :as string when I import str-utils2

23:13 tomoj: that's fine

23:13 DuneMan: and that... somehow messed up something in the namespace. if I require it as str-utils2

23:14 tomoj: you should then be able to string/partition

23:14 DuneMan: then the partition works right

23:14 tomoj: I get an IllegalArgument exception when I try to call clojure.core/partition with those arguments

23:15 DuneMan: yeah, as would be expected.

23:15 since core/partition is different.

23:15 tomoj: the problem might be that str-utils2 also uses this name, and that you were accidentally calling clojure.core/partition?

23:15 or not?

23:15 DuneMan: I was actually calling string/partition

23:15 explicitly.

23:15 tomoj: and you're sure string was clojure.contrib.str-utils2 then?

23:15 that should work fine

23:16 I just did it myself with the ns macro you pasted earlier

23:16 DuneMan: Yeah, it should work fine. But it didn't. And after I killed my repl and did the require again and used the fully qualified name it works

23:16 and now my original source works.

23:16 *shrugs*

23:16 tomoj: I blame vimclojure and/or lein-nailgun

23:16 DuneMan: That was actually just happening in a normal command line repl

23:16 tomoj: these kinds of problems don't happen to me

23:16 DuneMan: :-)

23:16 tomoj: well, shit

23:17 DuneMan: that I've been cutting and pasting into

23:17 tomoj: it may just be easier to stay sane about the repl's state when using slime?

23:17 DuneMan: yeah, who knows. thanks again

23:17 tomoj: not to imply that you screwed up, but maybe it's a possibility? I can't think of any way that could happen

23:19 DuneMan: No, I'm certain I'm screwing up somehow, I just can't figure out *how*

23:19 The toolset, when not using slime, at least, is... confusing.

23:21 Is there a better way to test this stuff in the repl than using load-file and then requiring the namespace?

23:21 I just did (eval (read-line (slurp "filename"))) so that it doesn't pop me out of the namespace

23:22 suppose you could load-file and then (ns ...) to put myslf in that namespace?

23:28 tomoj: DuneMan: yes

23:28 load-file, then use in-ns

23:28 (doc in-ns)

23:28 clojurebot: "([name]); Sets *ns* to the namespace named by the symbol, creating it if needed."

23:29 tomoj: then the repl will be in that namespace

23:32 DuneMan: slime looks like this http://tomojack.com/stuff/sshots/slime.png

23:32 you can see that the repl prompt changes when I switch to working on namespace/examples.clj

23:33 DuneMan: yeah, suppose I could learn emacs :-)

23:33 tomoj: you can C-c C-k when editing a clj file to compile and load that file into the repl

23:33 DuneMan: Go play with a symbolics machine...

23:33 tomoj: then there is a slime command which changes the repl's current namespace

23:34 I have C-c n look at the current source file's path, figure out the clojure namespace from that, and then switch to it in the repl

23:34 also C-c C-n looks at the source file's path and inserts a skeleton ns declaration with the appropriate namespace

23:34 (for lein-style projects only)

23:34 but that is ok because everything I work on is a lein project

23:35 plus, it works with 1.2.0

23:35 and if you learn emacs lisp (heh) the sky's the limit

23:35 DuneMan: Yeah, we'll see if use clojure long enough to make it worthwhile.

Logging service provided by n01se.net