#clojure log - Mar 22 2010

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

1:02 Mec: Is there anything in java to see what the current relative path is?

1:17 psykotic: (System/getProperty "user.dir") i think

1:26 arkrost: Hi! Can someone explain me how to create global var?

1:31 Mec: psykotic: that does seem to be it, thanks

1:53 psykotic: haha, programming with promises from the repl is ridiculously annoying. the print function for IDerefs automatically derefs anything you try to print, even in a debug context like the repl.

1:53 which means... it will block. it's very easy to do it by accident.

1:54 promises should probably have a custom print function that prints <undelivered> when a promise is not ready, so it's nonblocking

1:56 it already does that for futures, from looking at core_print.clj, but not for promises

2:15 fixed it, sent my code to the list

3:54 LauJensen: Morning team

3:56 defn: Morning Lau

3:56 What's new?

3:58 LauJensen: Cells are pretty new, so I'm looking forward to getting acquainted with them

3:59 defn: yeah i have been stuck in the past waiting for the full 1.2 release

4:00 LauJensen: Have you put cells to good use already?

4:00 defn: not yet, no

4:01 ive been watching with great interest, though :)

4:01 LauJensen: yeah, the mapx, filterx implementations look very very promising

4:02 vegai: what are cells?

4:02 underdev: its where they keep me after i get arrested.

4:02 tomoj: I can't wait for someone to explain it to the laity

4:02 LauJensen: vegai: http://www.assembla.com/wiki/show/clojure/Cells

4:03 tomoj: I tried for a bit to decipher that but gave up

4:03 LauJensen: vegai: Its a low-level mutable construct which uses locks in some clever way, so that its safe and as fast as java, so that you can implement map and filter in clojure without speed loss

4:03 (as far as I understood, might be wrong/dillusional)

4:03 tomoj: we have speed loss on map and filter?

4:04 LauJensen: If not, I dont see why Rich would start out by implementing them

4:04 tomoj: I guess that means multithreaded map and filter?

4:04 like pmap?

4:04 LauJensen: No I dont think so

4:04 defn: me likey pmap

4:05 vegai: sort of STM?

4:05 or did clojure already have STM elsewhere

4:05 LauJensen: But there's already a lot of those standard functions implemented for parallel use in the par branch

4:05 vegai: Not like STM

4:05 hircus: LauJensen: just followed your "Approaching Productivity" guide, and the Emacs color theme looks fine on GTK+ but when using "emacs -nw" I get a green background, odd

4:05 Chousuke: tomoj: the speed loss comes from all the thunks you need.

4:05 vegai: LauJensen: dataflows?

4:06 reactive programming?

4:06 Chousuke: cells are not dataflows either.

4:06 * vegai throws out buzzwords out there until one of them sticks

4:06 underdev: lol

4:06 Chousuke: they're basically a reference type for managing "dangerous" things.

4:06 such as java objects or transients

4:06 defn: ah-ha!

4:06 that makes sense to me

4:07 tomoj: so this lets you do pmap on arrays?

4:07 defn: hircus: your terminal doesn't support 256 colors

4:07 LauJensen: tomoj: You can already do that

4:07 tomoj: oh, hmm

4:07 LauJensen: But yea, one important thing which I heard, was that cells should replace transients in 1.2

4:08 defn: what of chunked seqs?

4:08 i thought chouser said something about chunked seqs -> cells

4:08 Chousuke: remember though that this is still all speculative :P

4:08 defn: :)

4:08 LauJensen: I think that sequence parsing usings cells will make them obsolete, because cells are faster than regular chunked seqs

4:08 Due to less allocation

4:08 And when thinking about it, I think that was the motivation for the mapx and filterx functions

4:09 http://gist.github.com/311542

4:09 defn: yeah i think that makes a bit of sense

4:09 but like Chousuke said -- no way to be sure

4:09 well there is a way to be sure

4:09 you need to be rich

4:09 Chousuke: the performance improvement supposedly comes from being able to have a "virtual" seq. ie. the cell represents the seq and as long as the user does not actually request the seq itself, the cell will never even create it.

4:09 hircus: defn: that's probably it, some of the default color themes are displayed odd too

4:10 defn: hircus: yeah you gotta hack your terminal up a bit

4:10 get the proper TERMINFO and TERM vars setup

4:10 you might need to compile a terminfo file

4:11 hircus: i beleive the emacs wiki has stuff about using emacs from the terminal, some of it is very helpful

4:11 LauJensen: Chousuke: That sounds like a minor improvement over chunks

4:11 Although, I would like to reclaim the lazyness, chunks make modelling something like Mersenne impossible

4:11 Mersenne Primes that is

4:11 hircus: defn: thanks, will look it up. I don't recall having this problem at home, but the work computers have an odd Linux setup

4:11 Chousuke: LauJensen: apparently it's a lot faster

4:11 LauJensen: oh

4:13 Chousuke: LauJensen: I think the idea is that a cell-based seq can be transient, and if a transient-seq-aware function uses it, the seq can stay virtual. ie. it can just be a stream of values, with no caching.

4:13 I hope I understand it right though :P

4:15 hircus: defn: export TERM=xterm-256color -- heh :)

4:15 defn: hircus: did that do the trick for you?

4:15 sometimes that's all it takes

4:15 LauJensen: Chousuke: No caching, as in reuse equals recomputation ?

4:16 defn: i run rxvt-unicode so i have a bit more of a pain

4:16 hircus: defn: yup, that's all. Wonder why that's not the default

4:16 defn: gnome-terminal here

4:16 defn: i suggest rxvt-unicode :) it'

4:16 it's faster -- i use it with xmonad and run it as a daemon

4:16 so i can spawn terminals like mad

4:18 Chousuke: LauJensen: you're not supposed to reuse it

4:18 LauJensen: the point is that it goes through a pipeline and gets fully consumed somewhere (or maybe finally transformed into a real seq, I guess)

4:19 LauJensen: Ok, but thats a feature loss compared to present day seqs

4:19 Chousuke: I don't see how

4:19 you don't care about the intermediate seqs in (reduce (map ... (filter ... (foo blah)))

4:19 or whatever

4:20 LauJensen: Im trying to think of an example where I do

4:20 Chousuke: well, in those cases you just need to make the transient seq a real one.

4:21 LauJensen: True

5:18 underdev: hi! when using lein project & swank-clojure-project, there is some :dev-dependency that needs to be added to the the project.clj file, but i can't remember what it is. google isn't helping. does anyone know what it is off hand?

5:19 LauJensen: underdev: skip google and go directly to www.bestinclass.dk

5:19 :dev-dependencies [[swank-clojure "1.1.0"]])

5:19 underdev: LauJensen: the pittsburgh (pennslyvania, usa) clojure users group just discovered your blog

5:20 LauJensen: underdev: from Reddit Clone in 91 lines, which covers deployment as well

5:20 underdev: ookay, thanks

5:20 LauJensen: underdev: great :)

6:28 jeffmess: is it possible to do graph animations over time with Incanter?

6:35 esj: jeffmess: yes. directly using the Processing interface. if using the jfreechart you'll have to bung by redrawing each frame (I think).

6:37 jeffmess: esj: awesome, are there any tutorials showing this being done?

6:38 esj: As far as processing goes I think the Incanter tests / examples document it (I remember a bouncy ball example of some sort). Processing itself is documented in its own right.

6:38 jeffmess: esj: thx

6:39 esj: good luck, I've been planning a similar thing myself for a while, but still working on the plumbing of 'what lies beneath'

6:41 * esj wonders what he was on when he wrote all that perl, and where he can get some more.

8:17 Licenser: defn: greetings to you :) I'm playing a bit more with walkon if you don't mind?

8:33 powr-toc: Is anyone here running compojure? I'm wondering how you can restart the jetty server at the REPL with a new app or set of routes?

8:33 tomoj: you often don't need to

8:33 er, are you an emacs/slime user?

8:33 powr-toc: yeah

8:34 re-evaling didn't seem to cause the definitions to update

8:34 tomoj: if you started the jetty server in the slime repl, recompiling the file that defines the routes works for me

8:34 powr-toc: hmm... I'll try again

8:34 tomoj: powr-toc: https://gist.github.com/3e4088d23fcc1e316dde

8:34 I do that

8:35 then if I'm at a repl I just do (start-server) to start it up

8:35 recompiling that file or a handler usually makes the update live

8:36 maybe you have to recompile the dependent files, then recompile the files that require them, etc..

8:36 I think the :reload tags can help, not sure really yet

8:37 powr-toc: tomoj: hmm.. I'm using compojure 0.4 and ring 0.2-snapshot... I use run-jetty to start the server, is there a difference between that and jetty-server ?

8:38 tomoj: I'm not sure, really

8:38 dunno what run-jetty is

8:38 powr-toc: what namespace is jetty-server from?

8:38 tomoj: I don't think I've been using 0.4

8:38 https://gist.github.com/355412ea5c68d123eedc

8:38 powr-toc: well 0.4 is pretty bleeding edge

8:39 tomoj: that is the relevant part of my ns decl

8:39 I think this is 0.3.2

8:40 powr-toc: yeah, I think 0.4 uses ring for starting jetty etc...

8:40 tomoj: dunno anything about that :(

8:46 chouser: cemerick: do you use polyglot maven?

8:47 actually, does anyone here?

8:47 cemerick: chouser: no, just the regular clojure-maven-plugin (which might sit underneath the clojure polyglot stuff, actually)

8:47 chouser: I think it can, yeah.

8:48 cemerick: I (unsurprisingly) don't think much of the fever to have sexprs everywhere, no matter the consequences. *shrug*

8:49 chouser: what intruiged me most was having clojure logic in the pom instead of ... what, xml logic. :-/

8:49 cemerick: well, poms are entirely declarative, so there's no logic, per se.

8:51 Besides, the tough bits of any nontrivial build aren't the "logic" or general process, it's tying together all the disparate pieces that go into making the build work. The glue is the commodity, not the stuff you're gluing together.

8:57 chouser: perhaps it would be the ability to write maven plugins in clojure that would be the killer feature for me, not writing poms in clojure.

8:58 cemerick: well, you can do that today

8:58 chouser: I suspected as much

9:00 cemerick: maven's architecture has a lot going for it, but the real value is in the ecosystem. Being able to hook in any of 100's of plugins that take care of otherwise horrendously-complicated build tasks is glorious. The concrete stuff -- XML, local repo formats, whatever -- are entirely inconsequential IMO.

9:00 chouser: I'm just mulling a swan-dive off the maven cliff. Trying to get an eye on the bracken I'm likely to hit on the way down.

9:02 cemerick: You'll feel yourself drawn to the big-3 IDEs -- their maven tooling is pretty spectacular these days. Really learning about how lifecycles and phases work is foundational, and shouldn't be skipped. Profiles are ingenious, and *will* save your bacon. In an organizational setting, deploy nexus, and only pull deps through that (ensures that external network issues don't hinder your builds).

9:03 AWizzArd: cemerick: :-)

9:03 Thank you for thinking about my network issues *g*

9:04 cemerick: AWizzArd: well, you're an outlier in that area. I was thinking more along the lines of "the cable's out for the afternoon" or "maven central is down", etc.

9:05 AWizzArd: cemerick: is it possible and worth to think about moving maven functionality into Leiningen?

9:06 cemerick: AWizzArd: I don't know that that's a comprehensible notion.

9:08 lein uses maven's dependency mechanisms. In general, it offers a subset of maven's capabilities (given the latter's plugin ecosystem). The sexpr syntax is the big draw AFAICT, which I personally don't think should be a relevant factor when choosing a build system (but if you do, the nascent polyglot maven project(s) await).

9:10 chouser: cemerick: I actually think it's the percieved simplcity of setup -- the friend FAQ, the clojure-specific help, etc.

9:11 bah, can't type: simplicity, friendly

9:11 * cemerick holds his head

9:11 chouser: cemerick: nobody wants to think about the build system, they just want to get on with the code.

9:11 ericthorsen: chouser: I'm just about finished moving all the enclojure builds to maven. I was hesitant on the xml and was intrigued by lei sexpr support but in the end I was looking for simplicity. The IDE support has been great and once you get your head around what maven it taking care of for you, the xml part was not much of a bother.

9:11 cemerick: Might have to get that quick-start clojure-maven-plugin blog post up today.

9:12 chouser: right, until they actually get build requirement #2, and start reimplementing javac invocation. :-x

9:12 AWizzArd: I would also think that it could be an interesting psychological “trick” if it were possible to do all/most of the build stuff in Clojure. The complexity will stay about the same, but people like I would perceive it as easier to use.

9:12 LauJensen: ericthorsen: I heard a report recently that on a large software project "maven related activity" accounted for 1500+ hours, which gave me the clear impression that its a dinosaur which needs to be avoided?

9:13 chouser: cemerick: that kind of quick-start guide could be really key to pulling people that way, I think.

9:13 ericthorsen: interesting thanks.

9:14 fwiw, talk of IDE pull does not attract me. I'm willing to overlook it in the hopes that such integration is not necessary. :-)

9:14 cemerick: LauJensen: I saw that piece. Quite a bit of puffery, IMO. Let's do a tally of hours spent twiddling ant files, or reimplementing stuff for lein, or monkeypatching stuff in rake scripts.

9:14 chouser: sounds too much like "Java is a fine language as long as you have sufficient IDE support" ... to generate code, refactor, etc. I'd rather have a good language.

9:14 I'll just assume that doesn't apply the same way to maven. :-)

9:14 ericthorsen: LauJensen: I cannot speak to what it is like for very large projects as mine is only a few. It solves a complex problem and has a large eco-system which is what attracted me to it.

9:15 cemerick: chouser: By no means necessary. However, when you see "code" completion on artifact revisions, etc., it's hard to not be impressed.

9:15 LauJensen: cemerick: ericthorsen ok

9:15 Maybe the main attraction of Clojuresque and Lein is that they're both so young nobody has really been burned by them on bigger builds :)

9:16 chouser: our project at work does not live mainly in the Java ecosystem, so I'm still pretty hesistent about using maven there. But for clojure-only projects, if maven is better than lein, we should also make it easier and more popular. :-)

9:16 cemerick: chouser: a good language does nearly nothing for you w.r.t. builds IMO. This is why I could care less what the chrome is on the build system.

9:16 chouser: no offence to technomancy|away

9:17 ericthorsen: LauJensen: possibly...I am also using to build an IDE plugin :) Once people start using maven projects for the myriad of different java project types, getting the dependancies and having a REPL with a properly setup classpath is much simpler

9:17 chouser: cemerick: i'm not speaking of maven's language in that analogy, just the sense that "it's easy to use if your IDE has integration"

9:17 LauJensen: ericthorsen: Yea I was very happy to actually try out Enclojure, its come a long way :)

9:18 Licenser: defn: http://playground.licenser.net:3000/walton.html if you want to have a look

9:19 LauJensen: Licenser: dead link

9:19 Licenser: LauJensen: not for me o.O

9:19 chouser: IDEs scare me. I assume this is a personal problem. :-/

9:19 LauJensen: chouser: It is :)

9:20 ericthorsen: LauJensen: Thanks...it will be easier to extend as well being part of maven world since contrib is there. Simpler to pull is known versions, etc.

9:20 chouser: They are much scarier from the inside :)

9:20 chouser: LauJensen: what are you grinning at? emacs is not an IDE.

9:20 LauJensen: chouser: ehm... yes it is, among other things

9:21 AWizzArd: When I want to work with directories, is then java.io.File the best class to use?

9:21 Chousuke: chouser: emacs is not. CEDET is :P

9:22 or actually, CEDET is the foundation of multiple IDEs as far as I understand

9:22 chouser: ericthorsen: yeah, I wrote a patch for enclojure early on. But I won't hold what I learned against NetBeans. :-)

9:22 LauJensen: AWizzArd: Yea I think so

9:23 AWizzArd: LauJensen: and do you know a better way of (File. (str my-file "/next-dir/")) if I want I want to cd into another dir?

9:23 LauJensen: Do you actually need to change the working directory, or do you need to recursively consume files?

9:23 AWizzArd: changing the working directory

9:24 cemerick: AWizzArd: you cannot change the working directory of a java process.

9:24 LauJensen: AWizzArd: true what cemerick said, but File can construct with 2 args right?

9:25 AWizzArd: I don't want to change the wd of the process. I just have a str representing a path to a dir, and another str representing a subdir

9:26 LauJensen: So how did wd changing come into this?

9:31 AWizzArd: but as I don't know if my code runs on Linux I can not simply (str dir "/" subdir) as dir may already end in a slash, or even a backslash

9:31 first making dir a File, then getting the canonical path allows me to add a File/separator and then concat it with subdir, which first should be freed of slashes/backslashes

9:32 cemerick: AWizzArd: if you're worried about being cross-platform, then it's a bad idea to go around glomming strings together. Use the File api that you have available to you, which will account for platform-specific details.

9:33 LauJensen: AWizzArd: http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html#File(java.io.File, java.lang.String)

9:33 chouser: AWizzArd: File ctor can take two string args: base dir string and then relative path string.

9:33 LauJensen: chouser: keep up now, thats what the Emacs guy just linked to :)

9:34 AWizzArd: ok, that sounds good

9:34 thanks you three

9:55 licoresse: with (map #(.getWidth %) (seq (. @c getComponents))) I get a list of the widths of some components, how can I use reduce to compute the total width ?

9:56 LauJensen: reduce + ?

9:56 hiredman: I would use appply, and you don't need that call to seq there

9:56 LauJensen: hiredman: Why apply ?

9:56 Or is appply something special, like pl ?

9:56 licoresse: how would reduce know that I am interested in the getWidth method of component?

9:57 hiredman: LauJensen: + is var arg and uses reduce interally

9:57 LauJensen: (->> (.getComponents @c) (map #(.getWidth %)) (reduce +))

9:57 hiredman: licoresse: it doesn't, but you already have the map

9:57 apply +

9:57 licoresse: LauJensen: ah, great

9:57 thanks

9:58 LauJensen: hiredman: Im not sure its that simple, I remember cgrand arguing quite heavily for reduce in all cases but apply str

9:58 np licoresse

10:26 spariev: ,(reduce conj (map (fn [k] { k (name k)} ) [:a :b :c]))

10:26 clojurebot: {:c "c", :b "b", :a "a"}

10:28 spariev: is it ok to process big vectors this way ?

10:28 chouser: sure

10:29 though I guess I'd suggest using 'into'

10:30 ,(into {} (map (fn [k] [k (name k)]) [:a :b :c]))

10:30 clojurebot: {:a "a", :b "b", :c "c"}

10:32 spariev: I'm worried about performance of this snippet on big vectors - shouldn't I somehow use transients there ?

10:34 chouser: into uses transients. :-)

10:35 and map on a vector uses chunked seqs, so you really should be good-to-go.

10:35 spariev: cool, so into version will be faster/allocate less memory that reduce ?

10:35 chouser: should be faster and less GC churn, yes.

10:36 though of course you should measure your actual use case and see if it's acceptible and if not where the real problem lies.

10:36 spariev: good to know, thanks chouser

10:36 chouser: np

10:37 also shorter, which is how you know you're using a good language and api: the shorter code is more correct. :-)

10:47 fogus: chouser: So J and APL are flawless? :p

10:47 chouser: hmph

10:49 Licenser: whgat is J and APL?

10:49 chouser: languages. succinct ones.

10:49 Chousuke: goodness is a function of comprehensibility and expressiveness, both of which are functions of length :P

10:50 esj: J is succinct in the way that Tyson is tough.

10:50 chouser: Requiring custom printers and type-ball heads may be too high a price for succinctness, but J is indeed intruiging.

10:50 esj: Chousuke: and that function is, in turn, a function of the user.

10:51 fogus: Agreed. I would love to dive into J one day

10:51 chouser: but actually I meant within a given language or api -- if the correct code consistently requires more code, something is wrong.

10:52 I'm thinking of prohibitions against default copy constructors in C++ for example.

10:52 spariev: I have method setFacetSpecs() in java class, which is a setter for _facetSpecMap.

10:52 Then I do (.setFacetSpecs specs) I get exception java.lang.IllegalArgumentException: No matching field found: FacetSpec for class ...

10:53 at clojure.lang.Reflector.getInstanceField(Reflector.java:245)

10:53 how can I tell clojure to look for method, not instance field ?

10:53 chouser: that's weird.

10:54 spariev: setFacetSpecs takes no parameters?

10:55 spariev: chouser: oh, sorry, missed one arg, it takes one parameter, something like (.setFacetSpecs browse-request specs)

10:56 chouser: that looks nothing like a field lookup or field 'set!' -- you're sure that's the line causing the error?

10:56 you might try hinting the first arg -- you can sometimes get clearer error messages.

10:56 (.setFacetSpect #^BrowseRequestThingy browse-request specs)

10:57 spariev: thanks, I'll try

11:11 figured this one out, was a typo in ctor call, sorry for the noise

11:14 powr-toc: I took a look at labrepl today... but I still can't quite figure out how it's supposed to be used... what workflow/benefits does it give over just having some HTML tutorial and a standard clojure REPL?

11:19 chouser: oh dear.

11:19 I just spent much too long on what turned out to be a misplaced close-paren.

11:20 If I had requested this block of code be re-intented, I would have seen the problem immediately. :-/

11:20 * esj is glad its not just him that plays that game

11:21 * fogus has logged countless hours chasing misplaced code ender-thingies

11:22 chouser: (let [y z] (if-let [x (foo)] (bar x)) (log-error))

11:22 (let [y z] (if-let [x (foo)] (bar x) (log-error)))

11:22 *sigh*

11:23 hiredman: rainbow parens!

11:23 chouser: I doubt I would have noticed the minor difference in colors. :-/

11:24 hiredman: it's not really minor

11:24 tomoj: anyone know if there are clojure jcloud docs around?

11:30 Chousuke: with paredit you wouldn't have been able to type that wrong ;P

11:30 dnolen: chouser: that's one advantage of paredit. If you have a misplaced paren it flips out and you can basically no longer type. Annoying but in a good way.

11:30 chouser: heh

11:32 Chousuke: do you now use arrow keys to navigate a clojure source file? Or hjkl?

11:33 Chousuke: chouser: mostly regexp search, actually

11:33 but arrow keys, yes.

11:33 chouser: no more viper?

11:33 zmila: in the dvorak keyboard layout the hjkl are placed not so nice as in qwerty :)

11:33 Chousuke: haven't been using it for a long while

11:34 chouser: Chousuke: ok

11:34 zmila: yeah

11:34 esj: zmila: I know your pain

11:34 arohner: tomoj: AFAIK, just the docstrings

11:34 tomoj: I read all of the clj source as well

11:35 tomoj: arohner: yeah, getting help in #jclouds

11:35 the source indeed

11:35 arohner: speaking of

11:35 bah, technomancy is away

11:35 I was going to ask him what his plans are on the clojure API

11:35 tomoj: he's working on it?

11:36 that is good to know

11:36 arohner: he's a jcloud committer

11:36 and I saw a few emails from the maintainers asking him to make changes to the clj API

11:37 the current API is not very clojure-y, and I've been writing my own bindings to accomplish what I want

11:37 tomoj: bindings over the java?

11:37 or just over the clojure stuff?

11:38 arohner: I'm mainly calling the java directly

11:38 cemerick: chouser: eh, someone beat me to it: http://learnclojure.blogspot.com/2010/03/clojure-maven-emacs-eternal-golden.html

11:38 I'll probably post anyway, to provide a version without the emacs and command-line dross.

11:38 chouser: heh. I just nested my closures too deeply: java.io.IOException: File name too long from clojure.lang.Compiler.writeClassFile

11:39 hiredman: nice

11:41 Raynes: I wish Ioke had multimethods. :(

11:41 * Raynes could write them, but is lazy.

11:42 chouser: cemerick: nice, thanks for that link.

11:43 hm, is it true that a lib built using maven is easier to add to a project that uses lein than the other way around?

11:43 oh, I guess you don't usually build dependent libs from source either way, so perhaps it doesn't matter?

11:44 Chousuke: isn't lein built on maven? :/

11:44 chouser: Chousuke: that was my understanding as well, but I've been corrected.

11:46 Chousuke: one thing I like about lein is that I can get it to start a clojure repl anywhere

11:47 maven apprently requires a pom.xml for that to work, at least by default. :/

11:48 spariev: with lein install you can install your lib in maven's local repository, so there is no difference IMO

11:49 cemerick: Chousuke: IIUC, lein only uses maven's dependency mechanisms

11:50 chouser: are you asking about multi-module projects?

11:51 Chousuke: hm, my .m2 dir is 50MB

11:51 that's a lot, considering it has the dependencies for maybe two projects besides clojure and contrib :P

11:52 okay, three

11:52 chouser: cemerick: no, about clojure libs that want to make themselves as easy to depend on as possible.

11:53 cemerick: chouser: Ah. I have no idea how lein does deployments. `mvn deploy` is how it's done in maven-land.

11:59 phf: is there fix to null pointer exception when doing slime-edit-definition while connected to a jar'ed clojure program?

12:01 tomoj: hmm

12:01 it works for me

12:01 elpa clojure-mode and swank-clojure?

12:02 and, how are you starting clojure?

12:10 cemerick: The inability to scope methods to particular namespaces is growing into a bit of a problem.

12:10 tomoj: hmm?

12:11 hmm, I think I understand what you mean

12:11 you get one hook into the multimethod, and that's it

12:11 everyone shares that hook

12:11 cemerick: right

12:11 tomoj: maybe you could define a dispatch function which can scope to namespaces?

12:12 then a macro or two to use it easily?

12:12 cemerick: tomoj: well, in this case, the multimethod is defined by third-party code.

12:13 tomoj: oh, yeah, so they define the dispatch function already

12:13 lame indeed

12:13 how do haskell's typeclasses handle this?

12:13 cemerick: No idea.

12:13 chouser: cemerick: I don't understand -- you can have a defmulti by the same name in a different namespace

12:14 tomoj: then you have to redefine all the methods in the third-party code, though, don't you?

12:14 chouser: ...and you can have methods dispatching on keywords with the same name but different namespaces resulting in different defmethods being called.

12:14 Chousuke: if you're using a multimethod you need to accept the fact that anyone can define a method on it.

12:15 cemerick: chouser: except I have no control over the dispatching fn

12:15 chouser: oh, you want to "inherit" some defmethods but the have different ones added in different namespaces for the same keywords?

12:16 cemerick: so in this case, I'm wrapping the multi with (if (some-predicate-here) (do-special-thing) (call-existing-multi ...args...)))

12:16 "inherit" is a decidedly bad term in this case

12:16 Chousuke: isn't it possible to get all the methods on a multimethod?

12:16 there's some Java method for it.

12:17 ... too many diffrent methods in these sentences. :P

12:17 chouser: you want multiple dispatch functions that are somehow automatically composed based on namespace? I clearly have no idea what you're talking about. :-)

12:17 cemerick: Chousuke: yes, but I'm not sure what that'd get me.

12:18 Chousuke: cemerick: you could create a new multifn and take existing methods from another :P

12:18 possibly. I haven't tried

12:18 cemerick: Chousuke: except the dispatch fn is opaque.

12:18 AWizzArd: Hello performance Gurus. Problem: I have 1-1000 substrings sub1 to sub1000 that I want all to replace by string S inside a big text string T. Example: subs1-subs3 are ["clojure lisp", "the clojure programming language", "clj"] and I want them all to be replaced by "Clojure" (my S in this example).

12:18 Now the thing is: I have not only one set of sub1 to subN and one String S, but I have 1700 of those. What is a very performant way to take a text T and replace all my 1700 sub1-subNs by S1-S1700 in T? Ideas?

12:19 Do I want 1700 regexps of form #"(sub1|sub2|sub3|...subN)" and do a (.replaceAll T r S) 1700 times? Is using JavaCC better for this? Are there other existing solutions? Bake something myself?

12:21 chouser: I would indeed be tempted to try #"(sub1|sub2|sub3|...subN)"

12:26 AWizzArd: I thought about traversing the T once, collecting all substrings that need a replacement and look those up in a hashmap off 1700x 1-1000 entries and then build a new string out of that.

12:27 ... collecting all start/end positions of substrings ...

12:45 TalkingHead: New to clojure, and have been looking at the Geonames Java API

12:45 Wondering what the clj equivalent of would be: ToponymSearchResult searchResult = WebService.search(searchCriteria)

12:46 (ToponymSearchResult. (WebService/search tsc)

12:46 doesn't seem quite right

12:46 with tsc being:

12:46 tsc (doto (ToponymSearchCriteria. )

12:46 (.setQ (str loc ", " country)))

12:48 hiredman: TalkingHead: (ToponymSearchCriteria. ) is new ToponymSearchCriteria()

12:49 (which doesn't apear in the java code)

12:49 notallama: i just did something somewhat useful with my monad library: http://github.com/hclarke/clojure_combinators/blob/master/src/examples/parser.clj

12:49 still not sufficiently magical, but it's getting there.

12:49 TalkingHead: gotcha

12:49 hiredman: so in order to translate to clojure you first need to understand what is happening in the java

12:50 ipostelnik: TalkingHead, you want to do something along the lines of (let [result (WebService/search tsc)] ... your code to use result ...)

12:50 hiredman: stuff on the left of an = can generally be ignored

12:51 ipostelnik: TalkingHead, result will be bound to the return value of the web service inside let

12:53 TalkingHead: thanks - makes sense

13:18 Licenser_: greetings my lispy friends!

13:21 tomoj: salutations

14:05 arkrost: Hi! Explain please how can I use set! and var-set

14:18 dnolen: arkrost: there's documentation for set! on the clojure website in the special forms section. var-set can only be used with thread-locally bound vars. what are you trying to do?

14:56 dcnstrct: how do you specify that a regex should be case insensitive in clojure ? Ruby also has regex literals and to do what I'm talking about would like like this: puts "match" if "Ninjas are cool" =~ /ninjas/i

14:57 the case insensitivity specifier thingy is built into the language's regex syntax.. is it the same in clojure ?

14:58 drewr: ,(re-find #"(?i)ninjas" "NiNJaS")

14:58 clojurebot: "NiNJaS"

14:58 dcnstrct: neat

14:58 are there a bunch of other flags you can use in (?) ?

14:58 I

14:59 I'll google it. thanks

15:00 drewr: in http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html, look for "special constructs"

15:45 edbond: what does :: means? like ::result

15:45 rhickey: ,::foo

15:45 clojurebot: :sandbox/foo

15:46 rhickey: ,*ns*

15:46 clojurebot: #<Namespace sandbox>

15:46 zaphar_ps: edbond: it automatically qualifies the symbol with the the namespace it's in

15:46 it's handy for DIY types

15:47 edbond: didn't symbols global?

15:47 sorry, I thought about keywords

15:48 :result

15:48 chouser: also handy for adding keys to maps that may be used by multiple namespaces, like metadata on objects that are getting passed around.

15:51 drewr: edbond: the namespacing is just syntactic

15:55 Crowb4r: It's a shame clojure did not do GSoC, I would really use a job. :p

16:00 vegai: is clojurebot's source available?

16:01 LauJensen: clojurebot: where are you?

16:01 clojurebot: http://github.com/hiredman/clojurebot/tree/master

16:01 vegai: oh, he answered to "source" privately, I just saw :)

16:01 cheers

16:02 does its evaluator have some sort of sandboxing?

16:03 chouser: yes

16:03 ,(java.io.File. "/")

16:03 clojurebot: #<File />

16:03 vegai: ah, it implements its own

16:03 chouser: ,(file-seq (java.io.File. "/"))

16:03 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission / read)

16:03 chouser: ,(def five 5)

16:03 clojurebot: DENIED

16:03 vegai: :)

16:04 Raynes: vegai: Check out http://github.com/Licenser/clj-sandbox

16:04 vegai: Raynes: that looks nice

16:04 Raynes: vegai: Me and Licenser_ have been doing some hardcore testing and such on it over the last few days. It's in good working order. ;)

16:05 Licenser_: vegai: yap thanks to Raynes it might actualy be usefull for people aside of me :P

16:05 _invis: Hi all

16:05 Raynes: Licenser_: You're too kind. <3

16:06 _invis: Guys could you tell me how I can multiply LazySeq with Number ?

16:06 Licenser_: nah, it's very important

16:07 (reduce * (range 10))

16:07 ,(reduce * (range 10))

16:07 clojurebot: 0

16:07 Licenser_: ,(reduce * (range 1 11))

16:07 clojurebot: 3628800

16:07 Licenser_: there we go

16:07 _invis: emm

16:07 (def Fi (range 0 60 1)) for example

16:07 with 150 for example :)

16:08 kotarak: ,(map #(* 150 %) (range 0 6 1))

16:08 clojurebot: (0 150 300 450 600 750)

16:08 _invis: I should take Seq with for each Fi*150

16:08 wow

16:08 Thank you :0

16:08 *:)

16:08 kotarak: np

16:08 _invis: What # does ?

16:08 Licenser_: ah :)

16:09 _invis: ^^

16:09 kotarak: _invis: #(foo %) is equivalent to (fn [x] (foo x))

16:09 _invis: I am from java :)

16:09 ok

16:09 ty

17:02 Raynes: Can you use Clojure on JavaME?

17:03 programble: lawl

17:03 knew you were going to ask

17:03 right, afk

17:18 seangrove: Anyone in here used opengl with clojure?

17:18 I'm having a hard time loading a texture and referencing it later on

17:20 LauJensen: seangrove: Read this (all of it) http://ideolalia.com/

17:20 seangrove: Oh, looks good

17:21 LauJensen: Yea, Zach is very inspirational

17:21 seangrove: Damnit

17:21 I've built all this up on cloggle, now there's a better lib, heh

17:22 LauJensen: :(

17:22 penumbra is here to stay

17:23 seangrove: I did an automaton which ran at about 300 ms per iteration of a 160x160 board, cgrand optimized it, so it ran at something like 2 msecs per iteration, then Tellman put it on the GPU using Penumbra, and it still ran at about 1.6 msecs per iteration, but now on a 2000x2000 board

17:23 seangrove: wow, crazy

17:24 LauJensen: Thats the word

17:24 rfg: seangrove: I'm using LWJGL.

17:25 And loading textures.

17:25 seangrove: Yeah, I guess I should have used jwgl instead of jogl

17:25 I have a slightly more general clojure-java interop question

17:25 rfg: In fact I'm using lwjgl and jogl.

17:26 seangrove: If I use a proxy class in clojure, and then I have an error in the code (or what would be an error in java land), I don't get any error output at all, it just silently fails

17:26 I have to litter my class with output to find out where it's stopping its execution

17:26 I lost hours and hours finding this out because I wrote .getGl instead of .getGL

17:27 Does that seem normal?

17:27 rfg: seangrove: try looking at *inferior-lisp*, assuming you are using slime.

17:27 seangrove: I am using slime - would that have given me some error output?

17:27 rfg: Quite possibly.

17:30 seangrove: I'll definitely keep that in mind

17:30 The jogl issue I'm having is loading a texture into memory without a gl context

17:31 Here's what I have so far - progressively building up the examples: http://pastie.org/881700

17:32 But the one I'm concerned about is the texture-window

17:32 It *works*, in the sense that it displays the texture on the quad, but it does it by loading the texture into memory everytime display is called, which obviously is not right

17:33 But I can't load the texture before the proxy class (which would be my preferred way of doing it)

17:33 I thought perhaps I should load all of the textures and store their int-ids in some global variable?

17:34 lpetit: hello

17:36 rfg: seangrove: What I do is, with a GL context already available I load in the textures I'm going to use and save the glGenTextures numbers in a ref.

17:37 seangrove: rfg: Do you have an example?

17:42 rfg: seangrove: this is my texture.clj: http://pastie.org/881721

17:43 seangrove: Heh, I like the " ;; Massively side-affecting

17:43 rfg: :)

17:43 I like to write down when things have side effects.

17:46 Then I have this function to store the ids in a ref: http://pastie.org/881725

17:47 The function alters textures which should really be called *textures*.

17:48 clojurebot: function is <Chouser> there is one class per fn, one instance of it per closure

17:48 seangrove: I assume that clojurebot was not referring to your code, rfg?

17:49 rfg: I should think not.

17:49 seangrove: I haven't used dosync or alter at all yet, just looking up those

17:49 Ok, I think I understand this

17:50 But you can only call this while you have an opengl context, right?

17:50 rfg: Indeed.

17:50 I open the window first.

17:51 seangrove: Alright, it's all coming together slowly in my head

17:51 rfg: My texture.clj was just a translation of an example from the lwjgl website, I think.

17:51 seangrove: I haven't used opengl before, so it's been a bit of a tough learning curve

17:52 Been fun though, have an opengl rss reader working, and onto texture mapping

17:52 clojurebot: Function literals are cute, but overused

17:52 rfg: seangrove: Here's what it looks like: http://img715.imageshack.us/img715/7810/64460624.png

17:53 seangrove: That's the lwjgl example?

17:53 rfg: No that's my clojure.

17:54 seangrove: Well, certainly looks nice in any case

17:57 Penumbra looks pretty amazing though

17:58 rfg: Yeah, I've not tried it yet.

17:59 dnolen: seangrove: rfg: it's excellent. very idiomatic, http://github.com/swannodette/clj-nehe/blob/master/src/clj_nehe/tutorial11.clj

18:00 seangrove: Seems to be, yes

18:10 dnolen: So you've used penumbra?

18:15 Licenser_: hey defn_ you're around?

18:51 seangrove: I'm curious about the meaning of nested arglists to defn

18:51 what is (defn example [[x y] z]) ?

18:51 Raynes: seangrove: It's destructuring.

18:53 kotarak: ((fn [[x y] z] [x y z]) [[1 2] 3])

18:53 ,((fn [[x y] z] [x y z]) [[1 2] 3])

18:53 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--7214$fn

18:53 kotarak: not my day...

18:53 ,((fn [[x y] z] [x y z]) [1 2] 3)

18:53 clojurebot: [1 2 3]

18:54 seangrove: I see, so if you're being passed a series of arguments in a manner you don't really like, you can use that to remap it?

18:55 kotarak: seangrove: I wouldn't put it like that. You should only use destructuring in arglists if it's part of the contract.

18:56 seangrove: I think I understand

18:57 ,((fn [x y] [(first x) (second x) y]) [1 2] 3)

18:57 clojurebot: [1 2 3]

18:57 seangrove: Ok, yeah, got it

18:57 That's much nicer

18:57 Ok, and also _

18:58 programble: _ means you dont care

18:58 a name for a variable you are not going to use

18:58 seangrove: Ah, ok

18:59 Thank you!

18:59 Struggling, but enjoying my tiem in clojure

19:12 ,(doc ->)

19:12 clojurebot: "([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."

19:13 seangrove: What a strange function :P

19:13 kotarak: ,(-> 1 (+ 2) dec (* 5))

19:13 clojurebot: 10

19:13 kotarak: seangrove: actually a macro

19:13 ,(macroexpand-1 '(-> 1 (+ 2) dec (* 5)))

19:13 clojurebot: (clojure.core/-> (clojure.core/-> 1 (+ 2)) dec (* 5))

19:14 seangrove: Hrm...

19:14 That looks the same?

19:14 dnolen: seangrove: yes, I use Penumbra, I'm working through the nehe tutorials, I'm swannodette on github.

19:14 kotarak: seangrove: note the recursion

19:14 ,(macroexpand '(-> 1 (+ 2)))

19:14 clojurebot: (+ 1 2)

19:15 kotarak: ,(macroexpand '(-> (+ 1 2) dec (* 5)))

19:15 clojurebot: (* (clojure.core/-> (+ 1 2) dec) 5)

19:15 seangrove: I see

19:17 Ok, looking at its use, it seems for readability?

19:18 Instead of nested parens?

19:19 kotarak: seangrove: yes. eg. for chaining method calls. Instead of Java: foo.bar().baz(5).frobnicate() you say (-> foo .bar (.baz 5) .frobnicate)

19:19 seangrove: just as one example

19:20 seangrove: Great, looks good

19:20 Chousuke: note: less parens than java :P

19:20 kotarak: hehe :)

19:20 Chousuke: fewer, even

19:20 * kotarak shakes head thinking about these useless syntax discussions. Each language its own syntax...

19:22 Chousuke: kotarak: if syntax were irrelevant, people would not discuss it :)

19:22 seangrove: Heh, sorry if I made a faux pas, I was simply wondering about it in this source file here

19:23 kotarak: Chousuke: syntax is relevant, but discussions of the style my brackets are faster than your parens are useless. I hate in particular this moronic "not used to X" argument.

19:23 Chousuke: If that was valid, I would still use C64 Basic. ;P

19:24 seangrove: no, no, no problem :)

19:24 Chousuke: right.

19:25 Though in lisp dialects the simple syntax is a necessity for macros to work as well as they do.

19:25 kotarak: seangrove: it's just a usual argument against Lisp: "Uh the many parens. The average John Doe programmer is not used to them. It's soooo scary!". That's just so stupid. "Uh the pointers in C. The average John Doe programmer is not used to them..." "Uh those classes in Java. the average John Doe is not used to them..."

19:26 programble: hm

19:26 Chousuke: if the syntax were any more complicated, you couldn't have neat things like syntax-quote :)

19:26 seangrove: I'm coming from scheme land, and clojure seems to have a somewhat complicated syntax to me

19:26 kotarak: Chousuke: well, you can them, cf. camlp4 of OCaml. But that is rather something for masochists. I'm not in SM. ;)

19:27 seangrove: But considerably nicer than cl, I think

19:27 Chousuke: seangrove: it has more syntax elements. I actually appreciate that.

19:27 seangrove: In any case, mostly everything I've used in clojure has turned out to be quite convenient in short order, so I'm not too worried about that

19:27 Chousuke: seangrove: in scheme and CL you need to use lists to represent all structure in your code. in Clojure you have vectors and maps of code too.

19:28 .. and sets, but no-one uses sets of code :P

19:29 seangrove: Heh, I'm sure I'll use them at some point in time

19:30 Once I get more comfortable with thinking in clojure

19:32 Chousuke: Sure you'll use them for storing your data, but I mean actual clojure code represented by vectors and maps in the syntax of a particular macro. the defn macro for example takes an argument vector instead of a list, and the macro really sees it as a vector.

19:50 dnolen: is there a version of clojure-contrib on clojars that's up-to-date, like a nightly or something?

19:51 Licenser_: night people

19:53 powr-toc: I'm hosting a Clojure workshop tomorrow evening in Dundee (Scotland)... The attendees are all experienced coders, but don't have much experience with FP, Lisp or Clojure... they all know Clojure's hot-shit... any ideas about what I should show them?

19:53 It'll hopefully be the first of many events

19:54 I'm looking for nice code snippets to disect etc...

19:54 programble: powr-toc: tool on rosetta-code

19:56 birdspider: hi, trying to compile clojure to *.class and getting "java.lang.IllegalArgumentException: Wrong number of args passed to: Test$-mytest", anyone interested ? :)

19:59 powr-toc: programble: nice idea... these guys are all OOP heavy... primarily c# background... any of those jump out at you?

19:59 chouser: birdspider: the first arg for every defclass fn is the "this" arg

19:59 birdspider: chouser, wow that was simple :)

20:00 chouser, thanks, it sure looks like I need to do more reading :)

20:00 programble: powr-toc: how about some good ol' factorial, quicksort, binary search, etc

20:01 powr-toc: programble: I was thinking that... I might sneak a few in... I have quite a bit about sequences already, but I'd quite like to decimate some design patterns too....

20:02 programble: powr-toc: must show them macros!

20:03 powr-toc: programble: yeah I know =) though I think that's worthy of a session of its own

20:03 Chousuke: powr-toc: write an instance of a design pattern, then show them an invocation of a macro that expands to said design pattern :P

20:04 chouser: how long do you have? 1 hour?

20:04 powr-toc: chouser: maybe 2

20:04 I'd like to keep it pretty interactive... i.e. I want them to be hacking code at their laptops where possible

21:09 seangrove: what is this %2 and %1 doing here? (reduce #(%2 ball %1) (:v state) ....

21:11 Ah, I think I found it.. pre-expr and post-expr?

21:15 Not quite...I think they refer to arguments whenever using #() to define a funciton without arguments list

21:21 shales: What is the proper was to set *stack-trace-depth* from clojure.test and other similar earmuffed vars?

21:55 sattvik: shales: I could be wrong, but I think it's generally done with (binding [*muffed* val] ... )

21:57 shales: so with unit tests I'd used a fixture to set *stack-trace-depth*? What about for *load-tests*?

21:58 JonSmith: you can also use set

21:58 oh wait

21:58 maybe that is depricated

21:58 it was set!

22:00 shales: Tried set! but got exception "Can't change/establish root binding of: *load-tests* with set"

22:01 gfodor: is there any API function or contrib function that does this: (map #(apply f %) coll))

22:01 its useful if you want to use destructuring w/ an anonymous function for map

22:01 JonSmith: for set! it needs to be within a thread

22:02 gfodor: Clojure=> (map-apply (fn [a b] (identity b)) [[1 2] [3 4]]) => (2 4)

22:04 JonSmith: so you'd do like (spawn-thread (fn [] (set! *var* something) (rest-of-code)) )

22:05 hiredman: ,((comp (partial apply map) (juxt (partial apply apply) idenity) + [[1 2]])

22:05 clojurebot: EOF while reading

22:05 hiredman: pffft

22:05 ,((comp (partial apply map) (juxt (partial apply apply) idenity)) + [[1 2]])

22:05 clojurebot: java.lang.Exception: Unable to resolve symbol: idenity in this context

22:05 hiredman: ,((comp (partial apply map) (juxt (partial apply apply) identity)) + [[1 2]])

22:05 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$identity

22:05 hiredman: bah

22:06 JonSmith: hm

22:07 why do you need identity of b

22:08 (map second [[1 2] [3 4]])

22:08 ,(map second [[1 2] [3 4]])

22:08 clojurebot: (2 4)

22:08 JonSmith: mine's shorter :-P

22:09 gfodor: hah, well, that's just an exampl

22:09 i didn't see anything that does map-apply idiomatically

22:09 JonSmith: right

22:09 hiredman: JonSmith: but your's has nothing to do with map-apply

22:09 gfodor: basically if you have a sequence of lists of arguments

22:09 JonSmith: right

22:09 hiredman: so how short it is does not count

22:09 JonSmith: ahh

22:10 so you are looking for like common lisp maplists or whatever that thing is called

22:10 gfodor: yeah I don't know CL, I just didnt' know if there is a more idiomatic way than defn'ing my own map-apply

22:10 shales: JonSmith: I see what you're saying, but I'm running unit tests using "lein test". Plus it seems like the value of *load-tests* should be changed globally and not just local to one thread.

22:10 Raynes: How can I get rid of paredit's newline-after-comment behavior?

22:11 gfodor: tho i guess a better name is "mapply" :)

22:13 JonSmith: gfodor: i think your implementation is pretty clear

22:14 hiredman: ,((partial map apply) (repeat +) '((1 2) (3 4)))

22:14 clojurebot: (3 7)

22:25 rpenguin: hiredman: how do you keep clojure bot from getting stuck in infinite loops? do you kill off a thread after a certain time?

22:28 hiredman: rpenguin: yes

22:31 rpenguin: was thinking about this beacuse i typed (recur) a couple times in a repl and was wondering why my mbp battery was draining so quickly

23:16 Mec: is there a way to combine 2 calls to swap! ?

23:17 danlarkin: Mec: do

23:17 Mec: is that safe tho?

23:17 danlarkin: yes

23:18 swap does a compare-and-set

23:18 Mec: ok, i thought i might have to end up using refs after all

23:18 danlarkin: so whatever fn you give to swap is safe

23:19 you just can't make two calls to swap! and assume it's safe

23:19 Mec: thats what im doing

23:19 i have 2 functions that each call swap! and want to do both in a 3rd function

23:19 hiredman: uh

23:20 danlarkin: nah you can't do that

23:25 Mec: so am i just stuck duplicating code so that theres only 1 swap! call?

23:25 danlarkin: you want to use refs

23:25 sounds like

23:26 Mec: i figured i'd be safe with an atom since im only tracking 1 map

23:27 danlarkin: well it just depends on what your application logic requires

23:27 if you're just associng on or something and you don't care about the order then use an atom

23:32 Mec: ya basically each function is changing out a different key and then i need to combine then to change 2 keys

23:38 danlarkin: Then you either want to do a bunch of work in the fn you send to swap! or use a ref

23:38 Mec: even if they're both just using assoc?

23:39 danlarkin: do you not understand the logic of a compare and swap?

23:40 if you're running in a single thread then it doesn't matter

23:40 but if not, you're going to see inconsistent values (most likely)

23:41 Mec: ill just stop being lazy and read up on refs

23:56 technomancy: danlarkin: hey... does leiningen master hang when it's done for you too?

23:57 (this is what I get for accepting patches late at night when I'm too tired to test them fully.)

Logging service provided by n01se.net