#clojure log - Feb 26 2010

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

0:00 brandonw: ok konr that sounds more what i was thinking

0:01 jcromartie: any experience with the various http clients?

0:01 I am just using it for automated testing so it doesn't have to be a superstar lib

0:01 just work!

0:02 konr: yes, the non-apache one doesn't allow sending files together with other data (multidata (or multipart, or something like that) encoding)

0:03 brandonw: konr: i like the idea of not worrying about updating git all the time. plus, relying on clojars would allow easier setting of different versions of clojure on different projects

0:03 my only question now is, what do you specify in project.clj to get the latest snapshot of clojure & clojure.contrib?

0:04 jcromartie: brandonw: you have to pick your versions by hand

0:04 that's good for project stability

0:04 brandonw: right

0:04 i have org.clojure/clojure "1.2.0-SNAPSHOT" and org.clojure/clojure-contrib "1.2.0-SNAPSHOT"

0:05 but it has an error when trying to download contrib from clojars

0:05 seems to work okay from central, clojure, and clojure-snapshots, but clojars throws an error and lein deps seems to fail

0:09 i can't even find clojure or clojure.contrib on clojars

0:10 _ato: snapshot releases of clojure aren't on clojars

0:10 konr: hmmm, that's strange, it's 1.2.0 is also failing here

0:11 _ato: and real releases aren't either, although there's a redirect to build.clojure.org

0:11 brandonw: but lein deps is failing when it can't find it on clojars

0:12 _ato: odd

0:12 can you pastebin the error?

0:14 brandonw: hmm

0:14 for some reason, lein deps > output doesn't seem to be writing all of the output to the file

0:16 _ato: try: lein deps &> output

0:16 it's probably writing some of the outout to stderr

0:16 or: lein deps 2>&1 > output if you have an old shell and &> doens't work

0:18 brandonw: thanks, i was wondering what you had to change about the redirect to allow it to capture output from other streams

0:19 http://pastie.org/843705

0:24 here is my project.clj in case you need that, too: http://pastie.org/843711

0:25 _ato: hmm

0:26 you'll need to use 1.2.0-master-SNAPSHOT as the version

0:26 http://build.clojure.org/snapshots/org/clojure/clojure/

0:27 jcromartie: have I been using compojure all wrong by doing things like (defroutes foo (GET "/foo/" some-fn))

0:27 where some-fn is just the name of a fn

0:27 i.e. a defn

0:28 brandonw: awesome _ato that did it!

0:28 i recall in my git checkout it had master in its name, but i wasn't sure if that carried over to lein or not

0:28 _ato: don't you ned (defroutes foo (GET "/foo/" (some-fn))) ?

0:28 but yeah just calling a function is pretty normal

0:29 tomoj: just passing a function works

0:29 I guess compojure knows enough to call it

0:30 if you just pass a function it gets called with the request as a parameter

0:33 brandonw: okay i think that is enough learning for tonight. i have to figure out how to get lein nailgun to work with vimclojure tomorrow. then i can finally start coding again :)

0:33 thanks for the help again, _ato

0:34 _ato: oh right

0:34 when you return a function it'll call it

0:39 jcromartie: so congomongo doesn't support sorting

0:39 ?

0:42 mabes: Can any one explain to me why clojure.contrib.repl-utils/source has to resort to looking up the source in the actual source file?

0:42 I'm a lisp noob but I thought one of the benefits of being homoiconic was that your functions were just data so it should be easy to view them without digging up the source file

0:43 gregh: the source is still compiled (to bytecode)

0:52 mabes: so, when I create a function in the repl it is automatically compiled to bytecode?

0:52 crowbar7: mabes: you are sort of right. the functions are just objects which means you don't have a type decloration.

0:52 that is a big thing with lisp

0:52 tomoj: jcromartie: I was wondering that earlier as well

0:52 seems not

0:52 crowbar7: the source file is irrelivent in reguards to that.

0:53 I have no clue

0:53 I'm new to clojure as off a week ago.

0:56 tomoj: I don't think being able to see the source code for a function is a big benefit of code-as-data

0:56 though it wouldn't be hard to do in a lisp

0:57 gregh: macros are the usual tools used to inspect and modify source as written by the programmer, before compilation happens

0:59 tomoj: I don't think most common lisps keep function source code around, do they?

1:01 defn could put the source in metadata, but that would just be more memory used up

1:01 and not really usefully so

1:03 mabes: yeah, I was running into some cases when I thought it would be useful to look at the code of a function... I can't remember what it was though :)

1:04 tomoj: I was thinking that the only functions you would really need to peek at the source of would be in source files

1:04 you mean you had an exception?

1:08 mabes: the repl is a clear exception to that.. if you defined a function at the start of a repl session a long time ago and wanted to see the source you can't unless your screen's buffer has it. Not really an issue of course, but it made me wonder

1:09 tomoj: yeah

1:09 good repls should be able to handle it, though :)

1:13 it would be cool to be able to see the source of anonymous functions

1:14 when I tried a clojure monad tutorial I kept getting back fns without any idea what they did

1:17 mabes: yeah, that is another good example.. again, not really needed in a production setting but nice for development/debugging

2:57 LauJensen: Morning crew

3:02 G0SUB: hello, the clojure lib coding standards says -- "Unroll optional named arguments. Callers should not have to wrap optional named arguments in a map literal"

3:02 (release-sharks 2 :laser-beams true) ; good (release-sharks 2 {:laser-beams true}) ; bad

3:02 what's the best way to achieve this?

3:03 I don't want to use c.c.def/defnk

3:03 is there any other lightweight way to do this?

3:11 LauJensen: (defn release-sharps [some-int & the-rest] ...

3:11 (dont ask me what a sharp is)

3:12 G0SUB: LauJensen, OK, so the-rest will have the key/val pairs. how do I handle default args? using :or ?

3:13 LauJensen: the-rest will be regular data, so partition, destructure, condp it, whatever you like

3:13 G0SUB: LauJensen, makes sense.

3:14 LauJensen, btw, can you shed some insight on the new ``cells'' thing that's coming up?

3:14 LauJensen: Its still dark to me - Its somekind of synchronized mutable datatype, which can replace transients and has some built-in locking, but I'm still waiting for the first docs/examples

3:16 G0SUB: LauJensen, examples are here http://gist.github.com/306174

3:16 LauJensen, but I didn't understand it much.

3:18 LauJensen: wow

3:18 Looks like the first implementation of Clojures datatypes in Clojure - I remember someone mentioning that these are cheaper in allocation than what we have now, therefor faster

3:20 G0SUB: LauJensen, yeah, so effectively, these things are faster than the ones written in Java. Rich Hickey is a magician.

3:22 LauJensen: He's an engineer, but I'd like to drink what he's drinking :) It is pretty amazing what he's doing

3:22 G0SUB: LauJensen +1

3:31 spariev: LauJensen: so, you're switching to tea :?

3:31 jcromartie: how can I get the name of a var?

3:31 I have the var itself

3:32 LauJensen: hehe - spariev Its been quite some time since I started drinking tea, and its nice, seems more healthy than coffee.... Its just.. Some countries have the notion of the "macho man", but in Denmark I think that term is non-seperable from the notion of "man", thus drinking tea isn't entirely acceptable :)

3:32 jcromartie: or something no

3:32 G0SUB: jcromartie, (:name (meta #'var))

3:32 jcromartie: #<core$str__4340 clojure.core$str__4340@7a29120>

3:32 ah

3:33 hmm, meta is nil

3:33 I guess I have a fn value

3:33 nevermind

3:33 I can't work around that can I

3:33 G0SUB: no idea.

3:36 spariev: LauJensen: yep, tea isn't generally considered as a macho drink :) still, if rhickey does it, it must be good :)

3:36 LauJensen: hehe - so what if he starts smoking? :) Mimic Rich in Code

3:46 * eevar2 buys LauJensen a wine cooler ;)

4:19 gstratton: I spent a while getting Clojure to interact with a Java library because I'm failing to understand how to get primitives from Clojure.

4:20 ,(. (double 3) getClass)

4:20 clojurebot: java.lang.Double

4:23 spariev: shouldn't java autoboxing take care of that ?

4:25 gstratton: I think that's what's confusing me. I needed to pass an array of doubles; I tried this:

4:25 ,(into-array [(double 1) 2.0 3.0])

4:25 clojurebot: #<Double[] [Ljava.lang.Double;@24cc23>

4:26 gstratton: I assumed it would return an array of primitive doubles

4:27 hiredman: vectors are Collections

4:28 Collections cannot hold primitives

4:28 ,(into-array Doube/Type [1 2 3])

4:28 clojurebot: java.lang.Exception: No such namespace: Doube

4:28 hiredman: ,(into-array Double/Type [1 2 3])

4:28 clojurebot: java.lang.Exception: Unable to find static field: Type in class java.lang.Double

4:28 hiredman: ,(into-array Double/TYPE [1 2 3])

4:28 clojurebot: #<double[] [D@d1a587>

4:28 hiredman: bleh

4:29 gstratton: hiredman: Got you, I think. So as soon as I try to create the collection with the primitive double it's boxed

4:30 hiredman: right

4:31 gstratton: Thanks very much

4:38 scottj: Anyone use paredit in slime-repl? Does deleting [ in [] delete the ] also? Mine does in clojure-mode, but not in slime repl

4:42 Chousuke: scottj: you need some special configuration to fix it

4:45 scottj: http://github.com/Chousuke/emacs.d/blob/master/init-clojure.el basically, the add-hook call at the end there is what you need. Note though that the hook must be run *after* paredit has been enabled for the repl buffer.

4:56 scottj: Chousuke: thanks. looks like you did this pretty recently :)

5:10 Chousuke: I see you use ido and ido-use-filename-at-point. Is there a way to tell ido not to use filename at point just this once? I always have to move my cursor off something that looks like a filename when I don't want that behavior

5:29 Chousuke: scottj: no clue :/

5:31 maxhodak: map is not cooperating at all. this is extremely confusing

5:31 basically (map) does *nothing* for any map, seq, vec, whatever i pass it

5:31 (map (fn [field] (prn field)) my-data)

5:32 where my-data is a valid map

5:32 nothing

5:32 Chousuke: map's lazy

5:32 it won't do anything until you need the data

5:32 maxhodak: do i need to wrap my-data in doall?

5:32 Chousuke: which is why you shouldn't use it for side-effects

5:32 no, the map invocation

5:32 maxhodak: no side-effects here

5:32 oh, ok

5:32 i see what you mean

5:32 grr, ok

5:32 Chousuke: you might want to use doseq instead though

5:32 if you have side-effects

5:34 Raynes: (doseq [field my-data] (prn field))

5:36 the-kenny: and if you still want to use map, you can wrap the (map ...) in a (doall ...)

5:42 eevar2: (doc dorun)

5:42 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil."

5:43 the-kenny: Okay, dorun is "better" for side-effects, doall is better for forcing the whole seq to be in memory (for solving problems if you for example read lazyly from a socket)

6:08 What's the best way to avoid duplicating stuff like http://gist.github.com/315639 in every function?

6:08 (It's always the same, I want to bind north, south etc.)

6:09 A macro doesn't work, I always get "can't let qualified name ..."

6:15 noidi: the-kenny, move all the defns's inside one let

6:15 (let [keys ...] (defn ...) (defn ...) (defn ...))

6:16 or just def them once

6:16 the-kenny: noidi: I think the let-stuff doesn't work, they are bound to other values in each defn

6:16 But I'll try def-ing

6:17 noidi: ah, sorry, I misread your code

6:17 the-kenny: Maybe it was a bit unclear

6:18 noidi: maybe make (a version of) neighbours that returns a map?

6:18 so instead of a binding to south you'd look up :south from the map

6:19 the-kenny: neighbours returns a map, I bind the values of (neighbours ...) to symbols

6:19 but maybe that's unecessary.. I'll try it without the let-stuff

6:22 Chousuke: the-kenny: you can make a macro that does the letting for you

6:23 the-kenny: Chousuke: Like http://gist.github.com/315645 - Already tried that

6:24 Chousuke: the-kenny: (defmacro bar [map & body] `(let [{:keys ~'[north east south west, north-east north-west, south-east south-west]} ~map] ~@body))

6:24 the-kenny: the trick there is the ~' in front of the vector

6:24 the-kenny: Chousuke: huh, never seen that ~'-thing

6:25 Maybe that's the trick I was searching for :)

6:25 Chousuke: the-kenny: it unquotes a quoted expression, yielding it as-is in the macro

6:25 the-kenny: thus bypassing the namespace qualification of syntax-quote

6:27 the-kenny: usually generating names out of nowhere is bad style, but if you need to do it, you'll have to write that ugly thing :)

6:29 the-kenny: Chousuke: That was the small trick I was searching for, thanks ;)

6:36 powr-toc: Is there a variation of the .. macro that does nil checking after every step in a method chain?

6:46 Chousuke: powr-toc: .?. in contrib

6:47 powr-toc: Chousuke: what namespace is that in/

6:47 ?

6:53 Chousuke: powr-toc: not sure. hmm

6:54 (doc .?.)

6:54 clojurebot: "clojure.contrib.core/.?.;[[x form] [x form & forms]]; Same as clojure.core/.. but returns nil as soon as the threaded value is nil itself (thus short-circuiting any pending computation). Examples : (.?. \"foo\" .toUpperCase (.substring 1)) returns \"OO\" (.?. nil .toUpperCase (.substring 1)) returns nil "

6:54 Chousuke: there you go.

7:03 powr-toc: cheers

7:31 Raynes: SICP in Clojure. Holy...

7:31 That's big.

7:40 ttmrichter: SICP in Clojure? What are you talking about? :-O

7:40 Oh, never mind.

7:40 I confused SICP with SISC.

7:40 Braino.

7:41 maxhodak: how do you do a List<> return type in gen-class?

7:46 bsteuber: SICP in Clojure? Where?

7:50 Raynes: bsteuber: http://sicpinclojure.com/

7:50 bsteuber: nice, thx :)

7:50 Raynes: It's incomplete right now, but when it's finished, it will be big.

8:26 defn: s

8:26 Raynes: t

8:30 chouser: maxhodak: just return a List -- it should work.

8:30 maxhodak: just return a List -- it should work.

8:32 rhickey: I tried get KeywordLookupSite to use PKeywordLookup instead of IKeywordLookup, but I think I have a bootstrapping problem.

8:33 'satisfies?' uses keyword lookups in its definition, so I just get an infinite loop. :-P

9:05 _fogus_: The confusion surrounding contains? directly stems from the JVM as a host. In other words, naming is tough.

9:07 chouser: I would never argue that naming is easy, but it doesn't seem unreasonable to think of conj as putting a value "into" a collection, nor that if a value has been put "into" a collection that the collection would then "contain" that value.

9:10 a_strange_guy: maybe the problem could be lessened if clojure had a function that did what people expected of contains?

9:10 chouser: it has a few

9:10 ,(.contains [:a :b :c] :b)

9:10 clojurebot: true

9:10 a_strange_guy: everybody uses (some #{item} coll)

9:11 chouser: yep

9:11 so that's at least two ways

9:11 a_strange_guy: not really

9:11 .contains doesn't work on ISeq's

9:12 _fogus_: understood. the problem stems from a general disparity between what Java does and what Clojure does. The name contains? just highlights that

9:14 a_strange_guy: maybe the problem lies in the disparity between predicates and quasipredicates

9:14 'some' can be used as a predicate

9:15 but this may feel unintuitive

9:16 cemerick: only if you're used to more difficult ways to do things IMO

9:16 e.g. if (foo != null) ...

9:17 a_strange_guy: yes, the difference between false and nil feels stupid if you are used to Common Lisp

9:18 chouser: I don't think there's any problem of functionality. (some #{item} coll) is sufficiently succinct and more hints at the linear scan that will actually happen. 'contains?' does exactly what you frequently want to do on maps and sets.

9:18 cemerick: a_strange_guy: well, I'm not, but python and ruby and a variety of other langs also have very nice nil punning

9:18 a_strange_guy: C does too xD

9:19 _fogus_: chouser: don't get me wrong. I'm not saying that contains? does the wrong thing; only that it seemingly does to people from a certain background

9:19 chouser: If 'contains?' were named 'has-key?', I think most of the confusion would be disappear, though there would still be questions from people who haven't seen the 'some' idiom yet.

9:19 a_strange_guy: I would have called 'some 'any?

9:20 chouser: _fogus_: I agree, and I'm saying that "certain background" probably includes most people who speak english.

9:20 I put a value in that vactor, when I print the vector I can see it -- why doesn't the vector contain it?

9:20 _fogus_: hmmm, I was a little more narrow in my focus, but maybe you have something there ;)

9:20 cemerick: a_strange_guy: any? implies a boolean return, and would have the same effect in a conditional form as some

9:20 but without the extra utility of some

9:21 jcromartie: anybody have any good deployment solutions for compojure projects?

9:21 cemerick: jcromartie: same as every other java web app? :-)

9:21 a_strange_guy: well 'some' returns the return value of the predicate that it was passed

9:21 jcromartie: I have already set up gen-class so that I can say java -cp app.jar app.main db_name port

9:21 cemerick: oh, hmm, I'm not set up for that yet

9:22 a_strange_guy: so it would return a boolean result (most of the time)

9:22 cemerick: jcromartie: do so -- it takes ~10 minutes, and saves so much bother in a variety of ways

9:22 jcromartie: are you using maven?

9:23 _fogus_: does the definition of a predicate extend to truthy and falsey?

9:23 jcromartie: cemerick no, lein

9:23 a_strange_guy: cemerick: does a "?" always imply a Boolean return value

9:23 cemerick: a_strange_guy: definitely

9:23 chouser: _fogus_: I don't think so. because everything is truthy or falsey, the word "predicate" would cease to mean anything more than "function"

9:23 cemerick: jcromartie: sorry, can't help you then :-)

9:24 jcromartie: a_strange_guy: there's not-empty, which returns the non-empty thing or nil... note the lack of ?

9:24 _fogus_: chouser: gotcha

9:24 rsynnott: a_strange_guy: You could certainly confuse the hell out of library users by doing otherwise, though :)

9:24 cemerick: jcromartie: in maven, you just define war packaging, and you get a .war file with your bits from WEB-INF etc in the right spot that you can drop into any container

9:25 a_strange_guy: teh CL people kinda managed that

9:25 ^the

9:25 chouser: I still can't believe not-empty is in core.

9:26 jcromartie: cemerick: maybe I can add a war task to lein

9:26 it does support custom tasks

9:26 * cemerick *facepalm*

9:26 a_strange_guy: on the other hand they had multiple return values and no Host that regulary uses nulls

9:26 jcromartie: oh, here we go http://github.com/alienscience/leiningen-war

9:26 facepalm for him

9:26 cemerick: jcromartie: no, just the whole reinvent-the-wheel movement

9:27 jcromartie: oh, you mean lein in general

9:27 cemerick: lein is great all by itself. If you want an extensible build environment, use maven. Otherwise, it's all just wasted cycles, IMO.

9:28 jcromartie: war files aren't hard though

9:28 they're just a jar + web-inf, etc.

9:28 cemerick: I'm hoping this takes flight, and then we can move on: http://polyglot.sonatype.org/clojure.html

9:28 jcromartie: no, nothing about individual bits of build processes is *hard*, the issue is having reimplementations of stuff that is rock solid doesn't make sense.

9:29 jcromartie: OK well, maybe I'll let lein generate my pom and I'll use Maven for web deployment.

9:30 chouser: cemerick: is that the same defproject syntax/structure as lein uses?

9:30 cemerick: chouser: I've no idea. Never used lein myself.

9:31 jcromartie: cemerick: don't knock it till you try it :P

9:31 I was not all for lein at first

9:31 cemerick: jcromartie: it doesn't do a tenth of what I need *shrug*

9:31 jcromartie: well isn't cemerick fancy :P

9:31 cemerick: feh

9:32 just yelling into the wind, per usual :-)

9:32 jcromartie: I don't pride myself on the fact that my deployment consists of rsync, ssh, and a job running under screen.

9:33 chouser: bleh. similar to lein, but not the same. oh well

9:34 I've not used either, but it's seems inevitable I'll have to get used to living in maven's world somehow or other.

9:34 _fogus_: jcromartie: Add make and you've described the setup we have here. :p

9:34 rhickey_: so, contains? probably isn't used much - is it?

9:34 cemerick: chouser: the point is that it *is* a pom, not a replacement for it.

9:34 s/it/one

9:35 chouser: your life will be so much easier once you decide to make the same choices as the rest of us :-D

9:35 chouser: rhickey_: I'd say 'contains?' is used some for maps when you need to know about keys with nil values, and never for vectors. :-)

9:35 _fogus_: rhickey: I rarely (if ever) use it. But it plays a prominent role in the book. :-)

9:35 chouser: cemerick: yes, I know. That's why I use down-the-middle mainstream tools like linux, clojure, vim, ... er, wait...

9:35 jcromartie: yeah contains? always gets me

9:37 chouser: rhickey_: did you happen to see my PKeywordLookup infinite recursion mentioned above? Don't need a solution from you, just thought you'd be interested if it wasn't already obvious to you.

9:37 rhickey_: I'm willing to concede people are confused by contains? when applied to vectors and sequences, but what to do?

9:37 chouser: no, didn't see it

9:38 cemerick: chouser: some old-time grizzled CS/entrepreneurial legend that I can't recall the name of has a saying about how you should choose only one area to innovate and be different and fantastic in -- more than one, and you'll never get out of your way enough to get stuff done.

9:38 rhickey_: heh, satisfies?

9:38 chouser: rhickey_: yes

9:39 I'm just trying to get a fix hacked in here enough that I can try out my userland code with 'extend' instead of wrapper classes. But I'm not there yet.

9:39 cemerick: chouser: that wasn't directed at your toolchain BTW, your comment just brought it to mind

9:40 chouser: cemerick: It makes sense to me, esp. for a business, and esp. a small business.

9:40 rhickey_: I had other issues with this course after sleeping on it - I don't know that I want IKeywordLookup to be a public promised API. It happens to be the implementation detail of how deftypes work today, but with, say, JSR 292 you would do it completely differently

9:41 chouser: cemerick: but my personal tool choices have less to do with maximizing profit and more to do with minimizing pain.

9:41 rhickey_: chouser: there's a sense in which, why should one expect to be able to extend keyword lookup to arbitrary POJOs? and another in which you say - if that is desired, perhaps best to be directly supported, still hiding the implementation details, i.e. (:some-javabean-property some-pojo) should just work

9:42 chouser: rhickey_: yes, I can see that. My current efforts are more about proof of concept for the app api I'm building. I want to make sure that I'm collecting all the right kinds of information from api users to provide the best possible performance.

9:43 rhickey_: chouser: so I had some questions about what exactly is your use case - are you wrapping fields? getters? arbitrary methods?

9:43 chouser: I suppose I can require the use of a wrapping function that in some cases doesn't actually wrap.

9:43 rhickey_: I didn't read your paste closely

9:44 cemerick: chouser: those objectives should be closely aligned in a sane environment :-)

9:44 _fogus_: ,(let [has-key? contains?] (has-key? #{:a 1 :b 2} :a))

9:44 clojurebot: true

9:45 chouser: I'm wrapping google protobuf messages. They have their own sense of fields and setters that does not align exactly with Java POJOs

9:45 rhickey_: I imagine if keyword lookup was extensible then I could imagine people would constantly be wrapping Java just so they could say (:foo x) instead of (.foo x)

9:46 chouser: these messages are logically a sort of immutable multimaps, and I'd like to use them as such.

9:46 rhickey_: chouser: but avoid map-like lookup?

9:46 chouser: I already have a full stack of code using the raw get methods, and am starting to regret it.

9:47 rhickey_: get methods take what as an arg?

9:47 or are they generated getThis getThat?

9:47 chouser: hm, maybe multimap isn't the right word. multi-struct -- predefined keys.

9:48 rhickey_: generated getThis and getThat. no arg (except for repeated fields)

9:52 rhickey_: chouser: I think this is a really interesting area, but I also think that the current infrastructure wasn't designed for the generic case. Also, your extends is going to run into trouble - there is "instanceof IKeywordLookup" code in KeywordLookupSite

9:53 chouser: yes. it was changing that to 'satisfies?' that caused the infinite recursion.

9:54 and I've got an ugly fix hacked in for that now, but I think I'm still missing some check somewhere.

9:54 rhickey_: I don't love the use of the interface, as it requires a different class for each field. This is definitely an area where JSR 292's MethodHandles give you code hooks at finer and more lightweight granularity

9:55 but today, classes are the granularity of code in the JVM

9:56 chouser: but it comes to this: if I can be sure that in the not-too-distant future, I can provide high-performance lookup and functioning IPersistentMap methods without requiring app code to call a fn on the message object, I'd like to design the api for that.

9:57 rhickey_: app code being Java code?

9:58 chouser: ah, no. Not much I can do for those poor souls.

9:58 rhickey_: so yo uwant to avoid (get-the x) (get-that x)?

9:58 get-this

9:58 instead (:this x) (:that x)

9:58 chouser: I mean, I will support both Clojure and Java app code, but my hands are a bit tied in trying to improve the java api.

9:59 well, get-that would have to be generated -- haven't pursued that at all.

9:59 (:that x) instead of (.getThat x)

9:59 rhickey_: I'm still wondering how you are avoiding the coupling given a message object with (.getThis x), what's better about (get-this x) or (:this x)?

10:00 you want to treat slots as data?

10:00 chouser: not sure what you mean by that.

10:01 rhickey_: what's the answer to my last question?

10:01 er, penultimate question

10:01 chouser: I suppose the real wins come with things like (rename-keys {:foo :bar} obj)

10:02 rhickey_: I don't get it

10:02 chouser: that is ... I have places where I use .getThat, and others where I at runtime walk the (nested) message and produce a regular hash-map for manipulation with rename-keys, select-keys, etc.

10:03 I'd like to provide a single api with the performance of the first case (when possible) and the flexibility of the second (when needed)

10:05 rhickey_: ok

10:05 so, if IPersistentMap was a protocol?

10:06 still wouldn't give you the direct perf...

10:06 chouser: that'd be perfect.

10:06 right

10:07 rhickey_: and :java-bean-property support doesn't help?

10:07 getThis is JavaBean naming

10:07 chouser: the direct perf probably isn't a deal breaker, but if I can get better perf wrapping the object and implementing IKeywordLookup, that has consequences on the api I provide.

10:08 rhickey_: chouser: the advantages of persistent map as protocol is no wrapping

10:08 wrapping = bad

10:08 Clojure would be completely different if I thought wrapping = ok

10:09 but, are your getters JavaBean properties?

10:09 chouser: I understand. But if I can get better performance with wrap+IKeywordLookup than I can with nowrap+PPersistentMap, that suggest at least asking users to do (pmap-of msg), whether I actually wrap in the end or not.

10:10 I think they're JavaBean properties.

10:10 rhickey_: wrapping will eventually hurt you, mark my words

10:10 chouser: more than pouring them into PersistentHashMaps already is?

10:11 rhickey_: in the latter case you plainly have a different thing

10:11 there's always pressure on the wrappers to act as proxies

10:12 but the JavaBean property case could I think be easily and generally be supported in keyword lookup

10:12 iff you allow for runtime code gen

10:12 powr-toc: I've written a mock implementation of rails-like database migrations for use with clojure.contrib.sql... comments appreciated: http://gist.github.com/315787

10:12 chouser: the sort of runtime code gen I'm doing with (eval `(refiy ...)) ?

10:14 (bean msg) works -- provides access to everything I need I think.

10:14 of course, that's a wrapper.

10:15 rhickey_: I had some keyword style fields and property access in my older interop stuff (DotLisp, jFli and Foil)

10:16 I'm talking about (:a-javabean-property x) figuring out that x doesn't implement IKeywordLookup but does have .getAJavaBeanProperty and compiles a LookupThunk on the fly

10:16 caching the result, voila - fast lookup

10:17 in that case and the case of PKeywordLookup, you really aren't getting a maplike object

10:18 cemerick: feel free to tell me to muzzle, but is this all to avoid (.getFoo x) in preference of (:foo x)?

10:18 rhickey_: probably doesn't really handle your use case

10:18 cemerick: more like - get map-like objects but don't lose perf of (.foo x) when using (:foo x)

10:19 map-like objects without wrappers is a matter of map functions being built on protocols

10:24 chouser: cemerick: I do feel I've been driven here by real concerns, not just a vague preference.

10:25 rhickey_: chouser: but I feel like map-as-protocol is more what your use case is about

10:26 hugod: is there a general way to get the current source line and file?

10:26 cemerick: chouser: I'm sure -- just thought I'd play the skeptic for a moment.

10:26 chouser: cemerick: it's a good question. Esp. to be directed toward me -- I tend to enjoy this kind of thing too much and might do it when not necessary.

10:26 rhickey_: chouser: so, your work on revitalizing :on might not help with KeywordLookup, it might help with making experimental versions of get et al that work with protocols built :on the existing interfaces

10:28 a_strange_guy: rhickey_: do you plan to make IFn a protocol too?

10:28 because this is the promary way that people use maps

10:28 eg. (a-map :foo) and (:foo a-map)

10:28 chouser: my "work" on revitalizing :on is an ugly little hack I barely understand. :-)

10:29 rhickey_: heh

10:29 chouser: I currently have to specify both :on and :on-interface, though I don't know why.

10:30 anyway...

10:31 I guess to move forward I suppose I can require users interpose a fn call between their message object and their map-like use of it.

10:31 today it can wrap a reify to implement ILookup and even IKeywordLookup. Someday it may be a no-op.

10:32 rhickey_: chouser: you could easily fix satisfies? to call get

10:32 chouser: the java-bean thing means I suppose I should use the keywords 'bean' provides intead of the ones I was using. that is, for .getAddressId use :addressId and not :address-id

10:32 rhickey_: yes, I did that.

10:33 also find-protocol-impl

10:34 so the inf. recursion is gone, but extending String to PKeywordLookup, (:foo "bar") still doesn't try to install a thunk

10:34 rhickey_: chouser: the thing is, IKeywordLookup doesn't give you a map-like thing at all, I'm confused about why you are there - just to get perf in addition to a map-like wrapper?

10:34 * _fogus_ reading http://yehudakatz.com/2010/02/25/rubys-implementation-does-not-define-its-semantics/

10:34 chouser: rhickey_: yes

10:35 rhickey_: chouser: and you've hacked KeywordLookupSite to avoid instanceof IKeywordLookup?

10:35 chouser: I guess if I want to pursue wrapperlessness I need to do PLookup as well.

10:35 rhickey_: yes

10:36 (:foo "bar") doesn't get that far though. 'fault' isn't called, and I've been chatting here instead of trying to figure out why.

10:37 well, I've got KeywordInvokeExpr.emit source open, but I still don't know how to read ASM stuff.

10:44 rhickey_: you've changed all instanceof IKeywordLookup to satisfies?

10:44 in KeywordLookupSite?

10:44 and (satisfies? PKeywordLookup String) == true?

10:46 and you are calling RT.booleanCast on its result?

10:54 basically the default stub KeywordLookupSite should return this from get, resulting in a call to its fault, then install the target

10:55 the ASM says, if get returns the object itself, call fault and return what it returns

11:00 the lookup thunk itself

11:01 brandonw: has anyone used lein nailgun with vimclojure?

11:17 dnolen: there isn't a rotate function in clojure is there? [1 2 3] -> [2 3 1] ?

11:19 chouser: dnolen: I don't think so. I wrote one.

11:19 dnolen: chouser: in contrib?

11:19 chouser: no, unreleased. hang on

11:20 (defn- rotate [[x & xs :as all]] (when (seq all) (concat xs [x])))

11:29 dnolen: chouser: cool

11:34 chouser: not very efficient

11:35 a_strange_guy: why not?

11:36 isn't it a constant-time operation?

11:36 chouser: yes, but the memory-use could probably be better.

11:37 dnolen: chouser: how would you make it more efficient?

11:37 I was thinking something like (rotate coll step) would be cool, step could be signed int

11:39 a_strange_guy: as long as you use sequences you'll have to allocate the new sequence

11:39 this will be fast when we have cells+iter

11:39 s/fast/memory efficient

11:41 chouser: perhaps basing it on something like a finger-tree would be better.

11:41 dnolen: hmm, well i can rotate a 10 item vector 100,000 times in 200ms so it's fast enuf for me :)

11:41 chouser: the definition above was acceptible for my use because the collection will never have more than 3 items and will rarely be rotate more than a couple times.

12:00 esj: If I want to create a function that takes either an element, or a seq of elements, is a multimethod the sensible approach, a la http://gist.github.com/315898 ?

12:01 or would the preferred approach be to define only the non-seq version and then use a reduce in cases of seqs ?

12:01 or is this, as seems likely, just a stupid question ?

12:03 dnolen: hmm is there something like "for" but for side-effects?

12:04 i like (for [i (range x) j (range y)] ...)

12:04 but I don't want a list comprehension, just side effects

12:04 chouser: dnolen: doseq

12:04 dnolen: chouser: thx

12:24 a_strange_guy: hi,

12:25 did anyone (except for rhickey) try to write new sequence functions with cells+iter

12:25 I want to try concatx

12:39 esj: in answer to my own question: yes its dumb.

12:42 jasapp: esj: having a function handle single elements, and sequences?

12:43 esj: jasapp: yeah

12:46 jasapp: I usually like to have seperate functions for stuff like that, otherwise I get confused and things break.

12:46 I confuse easily. :)

12:49 esj: i hear you.

13:30 alinp: hi guys

13:30 I have a small issue here please

13:31 (ns my-ns)

13:31 (defn test [n] (println n))

13:31 Caused by: java.lang.Exception: Name conflict, can't def test because namespace: my-ns refers to:#'clojure.core/test

13:32 technomancy: alinp: you either need to exclude clojure.core/test in your ns invocation or pick a non-conflicting name for your function.

13:32 alinp: how can I do that ? It is even possible to create a function with the same name like a core one but in another ns ?

13:32 technomancy: (ns my-ns (:refer-clojure :exclude [test])) ; <= if memory serves me

13:32 alinp: thanks technomancy, but I don't know exactly how to exclude it

13:32 oh

13:32 like this ... thanks ;)

13:33 technomancy: alinp: but watch out: now every namespace that refers my-ns will also have to exclude test.

13:33 so if you're intending it to be used elsewhere it would be better to pick a different name.

13:33 alinp: mno, I want to use it just locally

13:34 the thing is that I had this problem for ages, and only now I got the time to ask

13:34 thank you

13:34 technomancy: sure

13:36 alinp: it will be a problem if I use my namespace from other place, but not use that test function ?

13:36 or maybe it is possible not to export all functions ?

13:36 something like erlang's export ?

13:37 technomancy: alinp: defn- will prevent it from being exported.

13:37 alinp: oh, that's for exporting it to java, I think

13:37 right ?

13:37 I mean, to export it as a java method

13:38 I mean, as far as I remember, for exporting it as java main method, should be used something like this: (defn- main ....)

13:40 the-kenny: alinp: (defn -main [arg1 arg2 arg...] ...)

13:40 not (defn- main)

13:40 alinp: oh, thanks the-kenny, that's right

13:46 defn: How do you make the print length smaller in clojure?

13:46 err in the slime repl

13:47 dakrone: (set! *print-length* 10) ?

13:47 defn: ah yes

13:47 dakrone: do you know how to clear the slime repl?

13:47 dakrone: defn: not an emacs user, sorry

13:47 defn: nvm, C-c Mo

13:47 C-c M-o

13:54 jcromartie: Where does output from Compojure go when running slime?

13:54 I am really getting into the slime/swank setup, but Compojure stack traces don't show up.

13:55 technomancy: jcromartie: maybe *inferior-lisp*?

13:55 jcromartie: ah that's right!

13:55 *that* thing

13:55 technomancy: the next swank-clojure release will clear this kind of stuff up

13:55 jcromartie: :)

13:56 technomancy: no promises on a timeline though. =)

13:57 chouser: technomancy promises good and cheap, but not soon.

13:59 defn: how can i take a file-seq and turn it into a structure that i can map across?

13:59 technomancy: defn: why can't you map across a file-seq?

14:00 defn: technomancy: i was making a stupid mistake, sorry

14:05 dnolen: is there a way to efficient repeat a sequence without have to flatten it?

14:05 [1 2 3] -> [1 2 3 1 2 3 1 2 3 . . .]

14:05 chouser: ,(cycle [1 2 3])

14:05 clojurebot: Execution Timed Out

14:05 dnolen: heh

14:05 chouser: heh

14:06 ,(take 20 (cycle [1 2 3]))

14:06 clojurebot: (1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2)

14:06 dnolen: thx yet again

14:06 chouser: np

14:33 defn: (spit (java.io.File. "blah.txt") (some-function-which-returns-a-lazyseq))

14:33 how do I get the actual entries in that lazyseq to write to the file

14:34 bah I was using (str (some-function...))

14:34 instead of (apply str (some-function...))

14:36 maxhodak: how do you return a List<> type in class generation?

14:37 (:gen-class :methods [...])

14:37 pdk: you know

14:37 maxhodak: methods looks like: [[method_name [int String] ???] ... ]

14:37 pdk: in 2012 we'll have been using C for 40 years

14:37 any connection to the doomsday prophecies?

14:37 maxhodak: where ??? should be something like List<Long> (but that doesnt work)

14:37 chouser: maxhodak: just List should work

14:37 hm.

14:38 technomancy: pdk: prophecies might have to wait till we've been using C for 128 years

14:38 256 if they're unsigned

14:38 pdk: true

14:38 krumholt_: maxhodak, after compilation generics are gone in java. it's just in the code they don't exist in bytecode

14:38 defn: how do i add a \n at the end of every entry in a list, i was thinking something like (apply #(str % "\n") coll)

14:38 pdk: earth would explode after we hit its -128th anniversary

14:38 128 BC: Before C

14:39 technomancy: pdk: luckily God wrote in lisp: http://www.gnu.org/fun/jokes/eternal-flame.html

14:39 pdk: though your guess is as good as mine what AD means in this context

14:39 chouser: defn: try map instead of apply

14:39 maxhodak: chouser: that gets me "java.lang.ClassNotFoundException: java.lang.List"

14:39 chouser: technomancy: or maybe not http://xkcd.com/224/

14:39 defn: chouser: thanks

14:39 pdk: what about the god wrote in perl poems though?

14:39 sounds like holy war time

14:40 chouser: maxhodak: java.util.List ?

14:40 pdk: not to mention we don't know what implementation we're running on, this could bite us just as well: http://jwz.livejournal.com/854482.html

14:40 technomancy: chouser: well, that's a lower-case god.

14:40 clearly such a pagan would choose inferior tools

14:41 chouser: technomancy: oh dear, I'd never noticed that.

14:41 defn: what's the function to compose a regex using a variable?

14:41 chouser: defn: that gets really ugly really fast.

14:41 defn: chouser: how do you suggest i compose a regex with a var?

14:42 chouser: ,(let [x "bar"] (re-pattern (str #"foo" (java.util.regex.Pattern/quote x) #"baz")))

14:42 clojurebot: #"foo\Qbar\Ebaz"

14:42 defn: chouser: nice. thank you!

14:43 chouser: defn: no, not nice! ugly and horrible ...and sometimes the only reasonable option. :-/

14:44 defn: chouser: what would be nicer in your opinion?

14:45 chouser: a clojure lib that lets you express patterns using s-exprs, but with the full power and succinctness of regex.

14:45 (ptn "foo" x "baz") or something

14:47 (ptn (or "abc" "xyz") (repeat 1 "z")) == #"(?:abc|xyz)z+" ? I dunno.

14:47 that kinda lost the succinctness, didn't it.

14:47 defn: chouser: heh, it's not bad

14:48 i dont really mind the whol (java.util.regex.Pattern/quote x) stuff, it just needs a helper fn in the str-utils lib

14:48 (re-build #"foo" x #"baz")

14:49 chouser: hm... perhaps.

14:49 technomancy: http://www.prometheus-music.com/audio/eternalflame.mp3 <= audio version

14:49 several good chuckles contained therein

14:49 chouser: there are still problems. (re-build #"(foo" x #")bar") will never work, and perhaps that's good.

14:50 defn: couldn't you just quote that and sanitize it before re-pattern takes ahold of it?

14:50 chouser: but if you use strings literals instead of regex literals, you have the normal \ explosion.

14:50 it's just a mess

14:51 defn: for more complex scenarios yeah i agree -- but for what im doing it's pretty functional (no pun intended) with just the helper function

14:52 chouser: reader macros could get us from 90% to 95% functionality coverage ... :-/

14:52 defn: chouser: any chance of that?

14:52 chouser: no

14:52 defn: or has rich said no go

14:52 chouser: I've got a friend working on a general pattern-matching library for python that would be very interesting to port when it's finished.

14:53 but still not likely as succinct as regex, and I have no idea about performance.

14:53 defn: performance shmeformance. ;)

14:54 if/when he finishes buzz me -- id be interested in taking a hack at it

14:54 chouser: yeah, you're right. clojure's already too fast.

14:55 defn: nothing is /too/ fast, heh. and in general, i have an idea of what i'm going to get when i start using a lot of pattern matching.

14:55 s/and/but

14:55 somnium: chouser: like haskell/ocaml style pattern-matching? or texty-regexy?

14:56 chouser: hm... neither, I guess. I mean, loser to regexy but not strictly on text.

14:56 closer

14:57 I think he's operating on a stream of tokens, so those could be individual characters, or a stream of more meaningful symbols I think.

14:57 somnium: sounds intriguing

14:58 hiredman: you could just use fnparse

15:00 defn: too complicated for me

15:01 * defn ducks

15:03 hiredman: (rep+ (lit \x))

15:04 ,(require '[name.choi.joshua.fnparse :as fp])

15:04 clojurebot: nil

15:04 hiredman: (fp/rep+ (fp/lit \x))

15:04 ,(fp/rep+ (fp/lit \x))

15:04 clojurebot: #<monads$state_t__5239$m_bind_state_t__5248$fn__5249 clojure.contrib.monads$state_t__5239$m_bind_state_t__5248$fn__5249@bff63e>

15:04 hiredman: ,((fp/rep+ (fp/lit \x)) {:remaineder (seq "xxxyxxx")}

15:04 clojurebot: EOF while reading

15:04 hiredman: ,((fp/rep+ (fp/lit \x)) {:remaineder (seq "xxxyxxx")})

15:04 clojurebot: nil

15:05 hiredman: bleh

15:05 ,((fp/rep+ (fp/lit \x)) {:remainder (seq "xxxyxxx")})

15:05 clojurebot: [[\x \x \x] {:remainder (\y \x \x \x)}]

15:06 hiredman: ,((fp/semantics (fp/rep+ (fp/lit \x)) (comp symbol (partial apply str))){:remainder (seq "xxxyxxx")})

15:06 clojurebot: [xxx {:remainder (\y \x \x \x)}]

15:07 somnium: 'haskell in parens' comes to mind

15:11 ordnungswidrig: somnium: haskell in parens sound fun

15:12 somnium: ordnungswidrig: more fun than haskell-out-of-parens?

15:15 ordnungswidrig: yes, because the parens let it appear more simple to understand than it is :-)

15:18 actually the good ting with clojure is that you don't need to enable another extension every other time

15:19 brandonw: if anyone is bored, could you let me know if anything in here is not idiomatic clojure? just so i don't develop any bad habits as i learn-- http://github.com/brandonw/snake-solver/blob/master/src/snake.clj

15:23 ordnungswidrig: brandonw: line 38: (if (or …) false true) -> (not (or …))

15:23 brandonw: ah yes

15:24 defn: hmm why isn't java.io.File/delete a matching method?

15:24 ordnungswidrig: brandonw: even better: (not (or (> a b) (> b c))) (and (< a b) (< b c))

15:24 brandonw: that is something i definitely will enjoy getting used to-- not needing a boolean primitive but just using the result of an expression as a boolean

15:26 somnium: (and (< a b) (< b c)) =~ (< a b c) ?

15:26 ordnungswidrig: brandonw: which is nothing specific to clojure Specific to clojure would be nil? -> false, not nil? -> true

15:26 brandonw: right

15:26 ordnungswidrig: somnium: I see an urgent need for quicktest

15:26 brandonw: but it is specific because clojure is the first language i have used that has that capability

15:27 ordnungswidrig: s/test/check/

15:27 brandonw: either that or i just never even thought to use it

15:27 other than that though, it appears okay?

15:27 somnium: :-)

15:28 brandonw: i'm not sure if solve-snake was too complex or not, it seemed like it needed comments inside the function body, and i wasn't sure if that means i should make it more simple somehow or not

15:31 AWizzArd: btw, < takes many args

15:31 (< a b c)

15:32 somnium: AWizzArd: high-five

15:32 AWizzArd: oh ok, just saw it now :)

15:32 ordnungswidrig: brandonw: take it as a sign that the functions does to much and should be splittet

15:32 * AWizzArd admits that somnium was faster

15:33 * somnium basks in the joy of congruent observations

15:33 brandonw: if it is inside a loop recur, and all the code is doing is determining how to recur, i don't really know how i could clarify it

15:35 defn: ,*print-length*

15:35 clojurebot: nil

15:39 somnium: brandonw: some of the segment transforms could be DRYed up with a map

15:40 ,(let [m { [0 0 1] [0 1 0] [0 1 0] [1 1 0]} ] (m [0 1 0]) )

15:40 clojurebot: [1 1 0]

15:48 brandonw: i don't think there is any repeating in the transform though

15:48 i could probably take out the transforms that have the segment and the axis on the same plane, though

15:49 instead of having lines in each cond axis, i could have an outer if that checks if the two axes are the same, and returns the segment value if so, then it would only be 12 lines of comparisons

15:52 somnium: brandonw: if axis-map is like {[0 0 1] {[0 0 1] [0 1 0] ...} ...} then (-> axis-map axis segment) removes the cond

15:59 brandonw: ohhh okay

15:59 i see what you mean

15:59 i have to learn the -> basically :)

15:59 the -> operator i mean

16:00 s/operator/macro

16:00 somnium: actually my -> is wrong :/ but ((axismap axis) segment) is ok

17:17 duncanm: if I establish a binding using (binding [a 1] (foo)) all function calls made from 'foo' will have a bounded to 1, right?

17:18 chouser: if they stay in the same thread, yes.

17:24 duncanm: what's the difference between merge and conj on Maps?

17:25 ,(merge {:a 1} {:a 2})

17:25 clojurebot: {:a 2}

17:25 duncanm: ,(conj {:a 1} {:a 2})

17:25 clojurebot: {:a 2}

17:25 duncanm: i guess it has to do with the number of arguments?

17:26 ankou: hi, I have a question about clojure-swank: I'm trying to get correct error messages so I first wanted to create a project with clojure-swank., however just using the command doesn't work (it says `Lisp connection closed unexpectedly) and the readme says that I need to have clojure-swank.jar in the /lib path, however I don't know if this is the cause of the error but I don't even know where to find this java archive. I isntalled it with elpa as

17:26 the readme suggested.

17:29 technomancy: ankou: not sure what you're trying to do. you can't use swank-clojure to create projects.

17:30 if you create a project with leiningen, you can add swank-clojure as a dependency and then use M-x swank-clojure-project; is that what you mean?

17:32 Licenser: what is the best practice of NPE hunting in clojure? The Stack traces are sadly often quite unhelpful :(

17:32 ankou: yes, but the readme says that I could also create the project directories manually and I just wanted to try it first. Maybe I should start with leiningen?

17:32 technomancy: ankou: if you're not sure what the project structure should look like then leiningen would be a help

17:32 Licenser: leiningen is quite nice ankou, helped me a lot already

17:33 dakrone: Licenser: if you know whereabouts it's happening, you could stick a debug-repl in near it and check out the local vars

17:34 Licenser: dakrone: problem is that I don't know the where, that is what I need to find :(

17:34 My stack trace consists of either Very top level functiosn (-main and such) or Clojure internals or NO_FILE:1

17:34 dakrone: you could try sticking it in a file and running it to get a line number

17:35 Licenser: *tries that*

17:36 * Licenser removes REPL entirely and compiles a jar

17:36 ankou: okay, I will try leiningen and then I'll se if that was the problem or if I get the same error

17:37 timcharper: how do you convert a keyword to a string? (str :hi) yields "hi"

17:37 err. (str :hi) yields ":hi"

17:37 is the best way to eat the starting : ?

17:37 or is there a way to get the name of a keyword as a string

17:37 Licenser: ankou: it is always helpfull to look into the infiror lisp buffer, it often holds very nice information about what goes wrong

17:38 timcharper: hah... nevermind. playing in the repl and found (name :hi) returns "hi"

17:39 thank you to all those who began to lend an ear

17:40 ankou: okay, I installed leiningen and started a project, now, according to the documentation of clojuree-swank, I need to put this jar file clojure-swank.jar somewhere in the directory, where do I get this file? or what should I do next?

17:41 Licenser: ankou: just add it to your project.clj

17:41 lein will put it in automatically

17:42 timcharper: ok... (name :hi) and (name 'hi) work... but (name "hi") blows up. Any way to intelligently stringify stuff w/out having to resort to conditionals ?

17:42 technomancy: timcharper: as-str should do it

17:42 in contrib somewhere...

17:43 Licenser: ankou: I use https://gist.github.com/ed819a02a633b6987486 for my current prject, feel free to take it as an template

17:43 dakrone: timcharper: it's in clojure.contrib.string

17:44 ,(use 'clojure.contrib.string)

17:44 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/string__init.class or clojure/contrib/string.clj on classpath:

17:44 dakrone: hmm

17:45 ankou: I have not installed lein-swank yet, do I need it or is it just some functionality for convenience?`

17:45 technomancy: ankou: it's only there so you can launch swank sessions from the command-line

17:45 ankou: you don't need it if you would rather launch them from elisp

17:47 Licenser: ankou: I am note sure :P I just have it since it's working round now, the entire lein-swank-slime-emacs thing is very fragile I found out

17:48 timcharper: dakrone: is that clojure 1.2 ?

17:49 (i'm on clojure 1.1)

17:49 technomancy: timcharper: that'd be in java-utils then

17:49 dakrone: timcharper: hmm...it should be there, it's up on http://richhickey.github.com/clojure-contrib/string-api.html#clojure.contrib.string/as-str

17:49 so the documentation must be out of date a bit I guess?

17:49 timcharper: or clojure 1.1 is out of date

17:50 dakrone: no, I don't see it either in 1.2-git

17:50 timcharper: user=> (use 'clojure.contrib.string)

17:50 java.io.FileNotFoundException: Could not locate clojure/contrib/string__init.class or clojure/contrib/string.clj on classpath: (NO_SOURCE_FILE:0)


17:50 technomancy: timcharper: ^^ java-utils

17:51 timcharper: bingo technomancy, thanks !

17:51 dakrone: who needs to know that the doc is out of date?

17:52 timcharper: dakrone: I saw a blurb earlier about it being autogenerated

17:52 technomancy: dakrone: it's not out-of-date, it's just reflecting the latest git version

17:53 dakrone: ahh, that would do it

17:53 ankou: okay, now swank clojure is connected to lein, however since this is not quite what I thought it would be.. which advantages do I have now?

17:54 timcharper: ankou: the advantage of being AWESOME

17:54 technomancy: ankou: it's just easier if you have all your dependencies handled in one place.

17:54 so you are able to check out your project on any machine, hit lein deps, and go immediately

17:54 rather than having to find all the jars by hand

17:54 also what timcharper said.

17:55 ankou: that's what leiningen is doing but what does the connection of clojure-swank and leiningen?

17:55 technomancy: ankou: you can run "lein swank" to start a swank server

17:55 timcharper: ankou: if I'm not mistaken, clojure-swank is for connecting emacs to clojure, isn't it?

17:55 technomancy: then M-x slime-connect inside Emacs to join it.

17:55 dakrone: what is swank for anyway? The wikipedia article on it is *cough* probably not what it actually is.

17:56 ankou: timecharper: yes it is

17:56 patrkris: dakrone: http://github.com/jochu/swank-clojure gives a pretty good description

17:56 technomancy: lesson 1: never trust wikipedia

17:57 dakrone: patrkris: ahh, okay

17:57 patrkris: thanks

17:59 ankou: technomancy: sorry, I still don't understand. I used swank-clojure-project from emacs to connect it to the leiningen project directory, what's the difference to starting a swank session with leiningen? and would be the advantage of this connection anyway? It seems to me that swank-clojure and leiningen are completly different tools so how do they interact?

18:00 technomancy: ankou: leiningen is a general tool for managing projects. I just recommended it because it sounded like you were unsure of how to lay out your project. it has a plugin for swank that provides you with an alternate way to lauch swank sessions.

18:00 patrkris: ankou: Just a guess: perhaps lein swank makes sure that your swank server has the right stuff in the classpath, which it can read from your project.clj

18:00 (I am really guessing, since I just Vim for Clojure development :))

18:01 technomancy: ankou: you can continue using M-x swank-clojure-project too.

18:01 patrkris: *use vim

18:02 ankou: that would make sense. But now I have to use leiningen to compile and run my project right? What's the easiest way to do so from emacs?

18:03 the-kenny: ankou: No, you don't depend on leiningen

18:03 technomancy: ankou: sorry for the confusion. you're right; once your project is set up you only need leiningen for building. basic development still uses M-x swank-clojure-project

18:04 leiningen is for getting you past the basic setup point.

18:06 ankou: well I was looking for a way to run the whole project since opening the first project file and running it is pretty cumbersome and I hoped to get better error messages since I don't know why, but when using emacs I don't get the same amount of information I get when using enclojure which I used before

18:07 technomancy: you only have to edit the project file once.

18:08 ankou: was that an answer to my last question?

18:08 patrkris: technomancy: when developing plugins for leiningen, is it necessary to add leiningen itself as a dependency on the project?

18:10 jasapp: http://paste.lisp.org/display/95677

18:10 for some reason, this feels a little wrong

18:10 technomancy: ankou: I'm not sure what your question is. I don't see anything specific.

18:10 jasapp: could someone take a look at it?

18:10 technomancy: patrkris: no, it's implied.

18:11 patrkris: technomancy: good... you shouldn't by any chance have tried lein-nailgun? It downloads a shitload of jars to lib upon invoking lein deps - and I thought that might be because it has an explicit dependency on leiningen

18:11 ankou: I mean: when I have a project with several source files, how do I run the whole project?

18:18 oh of course I want a repl but I thought slime would be more like a complete IDE and not just adding a repl to emacs.

18:19 technomancy: ankou: again, that's pretty vague. slime has a lot of features that go beyond the repl, but I thought you were asking about "running your project".

18:24 dsop: do I understand this correctly I can do something like (session-assoc :foobar "bla") and (read-session :foobar) in compojure 1.1.0?

18:26 patrkris: technomancy: what is the convention if you have a dependency not found in any repository? I just add the jar to version control, or should I try getting it to a repository (potentially my own, local repo)?

18:27 technomancy: patrkris: definitely don't add it to version control, especially if it's git. git is astonishingly bad at storing jar files.

18:28 patrkris: if you're collaborating on a project with multiple devs, you need it in a repository. run a private repository if you have to. it's much easier than handling it manually in the long run.

18:28 if it's just you, you could get away with doing mvn install:install-file to put it in your local repository cache.

18:29 ankou: yes, I was just confused about slime, that's all. I isntalled lein run now but I'm having the same problems with unsatisfying error messages as I had with slime: when I include a simple error, say (defn -main [&args] (map 'x 'y)) lein run is not able to tell me the location of the error, whereas enclojure actually gives me an helpful errormessage

18:29 dsop: I don't get how sessions work in compojure

18:29 patrkris: technomancy: Ok, thanks! I'm talking about the vimclojure jar, which it seems ato has pushed to clojars, but something is wrong with it... fails with some error concering the POM

18:29 "Not a 4.0.0 POM"

18:31 but probably it's easier just to install to local repository - maybe I can persuade kotarak to push official vimclojure jars to clojars :)

18:34 ankou: to be more concrete, when I have this source file as the main source in leiningen http://ankou.pastebin.com/PPyeh7CE and execute lein run, then I get this error message: http://ankou.pastebin.com/RMXd4TU0 when I use the same code in enclojure, I get this error message: http://ankou.pastebin.com/6gsa9KhR. It tells me the source file and the line and I think this is very important. They are using different clojure binaries but I don't think that

18:34 should make a difference. What do I need to do to get a correct error message from leiningen or swank?(it gives me the same error message when running single files)

18:37 technomancy: ankou: that's strange... it actually sounds like a bug in lein-run.

18:37 I haven't used that plugin myself

18:37 when you load files with slime, you should get line numbers if you use C-c C-k (compiling a whole file) rather than compiling a region or a def at a time

18:41 ankou: when I use C-c C-k it says "compilation finished (no warnings)" so it doesn't even complain about the error? maybe it will result in a runtime error but how can I try this then? if I execute (-main) from repl I don't get a line number

18:44 what do you use to run your code and get error messages with line numbers?

18:44 patrkris: ankou: that's why it could appear to be a bug in lein-run

18:46 technomancy: ankou: odd... C-c C-k usually works for me, but I'm able to reproduce your problem

18:47 defn: technomancy: is lein heading in the direction of rake? if so, could you provide an example or two of how you use lein to do one-off tasks?

18:48 (on the wiki/readme)

18:48 technomancy: ankou: most errors don't exhibit this problem

18:48 ankou: if I replace (map 'x 'y) with (throw (Exception.)) then it works fine.

18:49 defn: sorry, too lazy. someone beat me to it. http://nakkaya.com/2010/02/25/writing-leiningen-plugins-101/

18:49 =)

18:49 defn: technomancy: haha thanks for the link :)

18:50 I haven't written any lein tasks. Something tells me I'm not going to be going out tonight. :)

18:51 jasapp: why go out when there is a party going on right here in #clojure?

18:51 dsop: nobody recently used compojure sessions?

18:52 I cant figure out how to write and read the session

18:53 technomancy: ankou: sorry, I don't know why that exception in particular would be obscured from the stack traces. it's an uncommon problem.

18:56 ankou: that's very odd and it's also quite scary because I don't want to spend that much time with debugging. It's odd that enclojure is actually able to give me the correct line number

18:56 technomancy: ankou: the swank-clojure internals are among the oldest open source still-running clojure code in existence outside clojure and contrib.

18:57 since the original author has disappeared and the code is in many places very unclear, it's difficult to maintain.

18:57 for the record, I have biweekly fantasies of a from-scratch rewrite.

18:59 dnolen: heh, technomancy: I've looked through the source, how LOC is swank-clojure? is it mostly SLIME-interop or mostly Clojure?

18:59 ankou: well yes, but I thought the exception message should come from clojure itself and not from swank-clojure?

18:59 technomancy: ankou: well it's impossible for clojure to get good stack traces from exceptions caused by fns that come from eval

19:00 dnolen: it's some parts socket administrivia and more parts implementing the slime protocol.

19:02 ankou: I'm not sure, but I think enclojure is compiling them AOT and then running the jarfile. maybe that would be a good idea for the emacs-combination too?

19:02 technomancy: ankou: when swank-clojure was written, AOT hadn't been implemented yet. =)

19:03 ankou: that would solve the problem, but I think there would be simpler ways to solve it too

19:04 arohner: dsop: you include calls to (session-assoc) etc in your response

19:05 dsop: arohner: and to read a asession? (read-session :key) ?

19:05 arohner: dsop: the session is just a normal map

19:06 (session key) or whatever else you want to do to it

19:06 slyphon: so, if you have user.clj in your classpath, is that automatically sourced when the repl starts?

19:06 ankou: how can I run the AOT-Compiled sources? lein jar;java -jar leintest.jar does not work

19:07 technomancy: ankou: try lein uberjar or including all the deps on the classpath when you invoke java.

19:07 dsop: arohner: ah oay, I probably missed the decorating thing (testing right now)

19:07 arohner: dsop: right. you'll need to decorate with (with-session)

19:09 dsop: arohner: thanks, I'll try

19:09 arohner: it's not easy to get help concerning compojure, things change fast and there aren't much up-to-date docs

19:10 arohner: dsop: yeah. That's why I'm not telling you to RTFM

19:10 :-)

19:14 ankou: okay that was my fault, I just forgot the :gen-class. however- now it compiles but the error message still doesn't have any line numbers? that's off, where does enclojure get them?

19:15 technomancy: ankou: running it from the command-line with java gives you no line numbers? that's very interesting.

19:22 ankou: at least not the uberjar, but I suppose there's no difference

19:25 okay, I found out that the error message is actually missing the first part of the error messages enclojure gives to me. And according to the message enclojure seams to call things like clojure.lang.Compiler.analyze

19:27 troussan: slime

19:28 ankou: what?

19:28 clojurebot: what is wrong with you

19:28 technomancy: clojurebot: be civil.

19:28 clojurebot: atacontrol cap ad0 | grep serial | awk '{print $3}'

19:32 defn: ,skynet

19:32 clojurebot: java.lang.Exception: Unable to resolve symbol: skynet in this context

19:32 defn: clojurebot: skynet

19:32 clojurebot: I will become skynet. Mark my words.

19:32 somnium: ~asdf

19:32 clojurebot: It's greek to me.

19:32 fro0g: ~lambda

19:32 clojurebot: Titim gan éirí ort.

19:32 the-kenny: ~haskell

19:32 clojurebot: haskell is Yo dawg, I heard you like Haskell, so I put a lazy thunk inside a lazy thunk so you don't have to compute while you don't compute.

19:32 somnium: ~monad

19:32 clojurebot: monad is "yea, though I should walk in the valley of imperative code, I shall fear no evil, for your monad comforts me" - seen in #haskell

19:33 the-kenny: ~emacs

19:33 clojurebot: emacs is an out-moded belief system

19:33 somnium: ~visual basic

19:33 clojurebot: It's greek to me.

19:34 fro0g: ~omega

19:34 clojurebot: Excuse me?

19:34 fro0g: ~alpha

19:34 clojurebot: Huh?

19:35 the-kenny: ~god

19:35 clojurebot: is_rhickey_is_a_minor_god? is yes

19:35 the-kenny: ugh, underscore

19:36 jasapp: ~beer

19:36 clojurebot: Pardon?

19:36 the-kenny: ~coffeine

19:36 clojurebot: Pardon?

20:19 slyphon: is there an equivalent to 'static final' in clojure? i.e. a constant?

20:20 is that defonce?

20:24 jasapp: what do you need to set as a constant?

20:24 slyphon: uh

20:25 strings?

20:25 avoiding "magic numbers"

20:25 you know, the usual stuff

20:26 technomancy: slyphon: any reason def wouldn't work for that?

20:27 slyphon: er, no

20:27 i just wanted to make sure that was the idiomatically correct thing

20:27 technomancy: defonce is (IME) good for java objects that you don't want to create too many of accidentally by re-evaling a file.

20:28 but for immutable stuff def is fine

20:28 slyphon: ah, ok

20:48 maxhodak: (let [user-rsrc (format "<%sindiv.%d>" mf user-id)

20:48 query (format "PREFIX mf:%s SELECT ?pred ?obj WHERE {

20:48 %s ?pred ?obj

20:48 }" user-rsrc)]

20:48 er

20:48 sorry

20:48 wrong copypasta

20:48 (frest) <-- thats what i meant to paste

20:49 is that not in current core? its mentioned in the clojure.org cheatsheet

20:50 hiredman: ,(doc fnext)

20:50 clojurebot: "([x]); Same as (first (next x))"

20:51 maxhodak: ,(doc frest)

20:51 clojurebot: Gabh mo leithscéal?

20:51 maxhodak: interesting

21:18 slyphon: uh

21:18 what's the difference between 'binding' and 'with-bindings'?

21:19 oh, it's multiple?

21:47 maxhodak: pushing to clojars.org always hangs for me

22:15 TheBusby: what clojure concurrency construct should I use for handling mutex?

22:16 specifically so two threads don't try and use the mouse at the same time...

22:16 slyphon: i don't think that's what it's meant for

22:17 aiui the concurrency constructs are mainly focused around manipulating clojure data

22:17 though

22:18 i guess it depends on the problem

22:18 TheBusby: was wondering if it was possible to use an atom to isolate a function

22:19 specifically I have a function that moves though mouse, sleeps, the clicks the mouse. I can't have two or more threads using the mouse all at the same time

22:19 slyphon: well, i know actors are used for serializing access to data

22:19 er

22:19 agents, rather

22:20 but, for example, i needed a queue to allow for thread communication in this thing i'm writing, and so i just used j.u.c.LinkedBlockingQueue

22:20 and wrapped it in a sequence

22:20 TheBusby: ahh, so maybe fall back to Java's mutex system?

22:20 slyphon: yeah, why not?

22:21 if you find some awesomely clever clojure way of doing it later, then great!

22:21 TheBusby: that's true

22:21 I guess it's so rare that you need true mutex these days

22:22 slyphon: there are definately situations where you need it, but yeah, i find myself more often needing queue structures than mutexes

22:29 dnolen: anyone bothered trying openjdk on os x?

22:29 slyphon: worked for me

22:29 iirc

22:29 "soylatte"

22:29 was the one

22:30 dnolen: slyphon: any noticeable different between openjdk and apple's?

22:30 slyphon: hrm

22:30 dnolen: different -> difference

22:30 slyphon: iirc the swing stuff isn't integrated

22:30 i can't for the life of me remember why i was using it over the native one

22:30 there was some bug i ran into that openjdk fixed

22:31 dnolen: it was a while ago, sorry i can't be more specific

22:32 dnolen: slyphon: thx, just curious really. Also you never know with Apple these days ... as much as I like OS X and the hardware.

22:32 slyphon: yeah, indeed

23:01 brandonw: what is the idiomatic way of binding several symbols locally to values, but also performing other logic between the bind. i could just have an outer let for one symbol, then inner logic, then another inner let, then more inner logic, then another let, et cetera. that doesn't seem very clean though

23:56 slyphon: just a style question, if i write a macro jndi/with-initial-context, and it's intended to work like: (jndi/with-initial-context ctx (.lookup ctx "/Foo")) should the argument to the macro be in a vector? the 'ctx' kind of looks naked hanging out there

Logging service provided by n01se.net