#clojure log - Jan 06 2010

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

0:31 konr: How can I add {:c "Camel"} to the right place at {:language {:letters {:a "ant" :b "bee"} :numbers #{1 2 "many"}}}?

0:41 arohner: konr: update-in

0:41 (update-in [:language :letters] assoc :c "Camel")

0:43 konr: arohner: thanks! I wasn't aware of that function

0:47 leo: Hey guys, When a clojure file containing (:import com.foo Bar) loads, then loading the class also runs all its static initializers during compile time. How do people work around this?

2:13 TheBusby: is there a simple way to change the "rate" of a lazy sequence?

2:14 for example, if you have a text file with two columns per line

2:14 and you use (read-lines *in*) to read in the data line by line

2:14 could you return a lazy sequence of aggregated data?

2:15 where the summation of each column would be returned when an empty line occured?

2:15 hiredman: that has nothing to do with lazy-sequences

2:15 TheBusby: if the file was 1TB

2:16 hiredman: and everything to do with the function you use to turn a file into a lazy sequence

2:16 TheBusby: you'd need to iterate over it

2:16 er, if your input was a lazy sequence though

2:16 hiredman: a lazy sequence is just two methods first() and rest()

2:16 the rest is all other stuff

2:17 (not rest(), rest)

2:17 TheBusby: I'm probably thinking about this incorrectly then

2:17 hiredman: sure

2:17 TheBusby: if you used map() for everyline of input you'd have a line of output

2:17 this would be processed line by line and the entire collection would not be stored in memory

2:17 hiredman: eh?

2:18 somnium: you could do something like (repeat (read-line-fn)) and then take-n ..., but that opens up other issues

2:18 hiredman: map is a fn that consumes seqs and returns a lazy seq

2:19 TheBusby: map returns an element for every element it consumes for the seq though right?

2:19 hiredman: yes

2:19 TheBusby: so it's 1 to 1

2:19 reduce takes many inputs and will return one value right?

2:20 somnium: reduce isnt lazy though

2:20 TheBusby: many to one

2:20 hiredman: it's better to start off with your problem instead of, think sort of halfway through, then presenting the halfway through

2:20 TheBusby: okay

2:20 I have two columns of numbers

2:20 where the first column is a non-unique record number

2:21 and the second contains related information

2:21 hiredman: is this sorted? all the records with the same record number are adjacent?

2:21 TheBusby: I'd like to read in the list, and have a lazy sequence return a map of all the related information for that record_number

2:22 correct, sorted

2:22 Example

2:22 1 10

2:22 1 20

2:22 1 30

2:22 1 40

2:22 2 5

2:22 2 6

2:22 etc

2:22 hiredman: you can stop

2:23 you are going to have to write a custom lazy-seq function, either on top of line-seq, or directly over the bufferedreader/file/etc

2:24 TheBusby: I was hoping I could write a generic function that would accept a function and a sequence and return a new sequence defined by the function

2:24 hiredman:

2:24 TheBusby: I haven't thought of a good way to do this yet, nor know if it's actually possible

2:25 is there a simple way to do the example I provided above?

2:26 this is so trivial to do in ruby...

2:26 hiredman: well, go to #ruby then

2:27 TheBusby: sorry, I didn't mean to offend

2:28 what I was trying to communicate was that this problem seems simple but appears very hard to do in a functional way

2:28 hiredman: it isn't

2:28 it's just a loop

2:29 somnium: something like (map line-processor-fn (BufferedReader. (FileReader. "file"))) no?

2:29 hiredman: nope

2:29 TheBusby: can't use map unfortunately since it's a 1->1 transform

2:30 hiredman: he is try to group lines

2:30 somnium: er, line-seq around the end, but doesnt duck-streams have something for this?

2:30 ah

2:32 TheBusby: I could process everything inside one big loop, but I was hoping there might be some way to have it return another lazy-seq instead

2:32 somnium: TheBusby: so you want to produce a new seq with nodes like [:record-

2:33 number data data data] ?

2:33 TheBusby: a new seq that's composed of multiple elements of another seq

2:33 correct

2:33 hiredman: lisppaste8: url?

2:34 gah

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

2:34 hiredman: too late

2:34 something like http://gist.github.com/270111

2:36 somnium: TheBusby: is data on one line separated by white-space?

2:36 TheBusby: tab delimited

2:36 hiredman: gar

2:37 TheBusby: but multiple lines make up a record

2:37 somnium: ?

2:37 hiredman: emacs seems to have decided to ignore my font preferences

2:37 vexing

2:38 TheBusby: oh, that looks very interesting

2:39 hiredman: f assumes that the seq has already been turned into a bunch of [id value] pairs

2:40 TheBusby: in the returned lazy seq you'd need to (cons d (f xs a '(b))) wouldn't you?

2:41 I'll try it and see if memory is okay

2:41 thank you!

2:42 hiredman: eh?

2:42 no

2:42 TheBusby: wouldn't "b" be dropped otherwise?

2:42 hiredman: I don't think so? (untested, eats babies)

2:43 oh right

2:43 yes

3:04 LauJensen: Morning all

3:27 TheBusby: hiredman: does recur not accept variable numbers of arguments?

3:28 I was trying the code you were nice enough to provide, and ran into this error "Mismatched argument count to recur, expected: 2 args, got: 3"

3:29 I tested the idea with this (defn t [a b & [c d]] (recur 1 2 3 4)) and got the same error

3:30 hiredman: recur might not like that destructuring

3:31 TheBusby: the docs says the arity has to match, I guess they just need to be required then

3:31 hiredman: bah

3:31 it's the vararg

3:32 TheBusby: ahh, even removed though it has an NPE

3:33 http://pastie.org/768568

3:33 seems to NPE when it asks for the rest

3:36 hiredman: start putting in printlns

3:36 to figure out where the nil is

3:40 TheBusby: ahh, it doesn't appear to like the end of the input sequence

3:56 hiredman: works great, no memory issues; thank you so much!

5:49 arj_: I'm trying to understand thread-local and set!

5:49 first thing I wonder is why the documentation for binding doesn't mention that they are thread-local?

5:50 ordnungswidrig: afaik they are thead-local, yes

5:50 arj_: second thing is if there is a way to create thread-local bindings for new variables

5:51 so that I can set! them

5:51 let doesn't work and binding needs already def'ed variables

5:53 ordnungswidrig: (binding [x 1] (set! x 2)) doesn't work?

5:53 somnium: not if x is not a var

5:54 arj_: exactly

5:56 somnium: clojure frowns on imperative code -- locals are asways immutable

5:56 arj_: why do you want to call set! on something that isnt a var?

5:58 arj_: was I was thinking was something like init a local var at the top of a function, then change that in the function and return it

5:58 ordnungswidrig: arj_: that's sounds naughty

5:58 somnium: vars are always top-level, afaik

5:59 reference types are available for what you describe

5:59 arj_: yeah so far I have had good luck rewriting the functions in a more functional style

5:59 somnium: but again, why do you want to do that?

6:00 arj_: reference types?

6:00 somnium: atom, ref, agent etc

6:00 arj_: ah yes, but they are quite verbose

6:01 somnium: they scream "Mutable State Here!", and this is widely regarded as a good thing

6:01 ambient: oh how i long for the days of single thread of execution :p

6:01 somnium: ambient: javascript!

6:01 :)

6:02 when IE supports concurrency it will all be over

6:04 praptak: somnium: you can still run into concurrency problems with JS. Asynchronous calls.

6:05 asynchronous calls + fast-clicking impatient users :)

6:07 somnium: praptak: true, but you can never really access a var simultaneously

6:46 esj: My REPL is complaining about an exception in some code of mine :"clojure.test$test_var__8905$fn__8907.invoke (test.clj:643)", where test.clj has about 100 lines of code. What am I missing here ?

6:47 is it really saying the error is on line 643? If so how ?

6:48 oh, ignore me, stupid question.

7:02 praptak: About (doc doto) - is "in the from of" a typo of "in the front of"?

7:03 the-kenny: ,(doc doto)

7:03 clojurebot: "([x & forms]); Evaluates x then calls all of the methods and functions with the value of x supplied at the from of the given arguments. The forms are evaluated in order. Returns x. (doto (new java.util.HashMap) (.put \"a\" 1) (.put \"b\" 2))"

7:03 praptak: sorry, "at the from of"

7:04 the-kenny: Looks like a mistake

7:05 praptak: Or an obscure idiom, hence my question.

7:32 esbena: I have a lot of mutually recursive functions, do I really have to 'prototype' them before use - or is there some way to tell the interpreter to look forward (using slime)

7:36 Chousuke: you need to declare them

7:37 you could also evaluate the file out of order manually, but that's not very practical

7:38 there's the declare macro for creating unbound vars, you can use that.

7:39 ordnungswidrig1: how can I embed unicode character in strings in clojure?

7:40 Chousuke: just type it in? :)

7:41 there's also the \UNNNN escape

7:41 AWizzArd: ordnungswidrig1: you can also use the \u1234 syntax, which will add the unicode char which has the hex code 1234

7:41 Chousuke: oh, it was a small u? hm.

7:41 AWizzArd: tho this gives you access to "only" 65k chars, and not the full range

7:41 esbena: Chousuke: thank you for the declare macro - I used empty function definitions before!

7:41 AWizzArd: ,\u65

7:41 clojurebot: Invalid unicode character: \u65

7:41 Chousuke: esbena: yeah, there's no need for the function to actually be defined in any way

7:42 esbena: but the var must exist

7:42 AWizzArd: ,\U54

7:42 clojurebot: Unsupported character: \U54

7:42 Chousuke: need four numbers

7:42 AWizzArd: yes

7:42 Chousuke: ,\u0054

7:42 clojurebot: \T

7:42 ordnungswidrig1: ah, recompile is your friend...

7:42 thanks

7:42 AWizzArd: ,\U0054

7:42 clojurebot: Unsupported character: \U0054

8:08 arj_: how do I add to the end of a collection?

8:08 collection is vector

8:09 _fogus_: ,(conj [1 2] [3 4])

8:09 clojurebot: [1 2 [3 4]]

8:09 neotyk: ,(conj [1 2] 3)

8:09 clojurebot: [1 2 3]

8:09 djork: ,(conj '(1 2) 3)

8:09 clojurebot: (3 1 2)

8:09 djork: :-)

8:10 Just FYI

8:10 arj_: ah yeah

8:10 thanks :)

8:10 _fogus_: conj works like push for vectors

8:11 djork: (conj {:x :y} [:j :k])

8:11 ,(conj {:x :y} [:j :k])

8:11 clojurebot: {:j :k, :x :y}

8:11 djork: there we go

8:11 conj is 'cpmkpom

8:11 OMFG CAN I TYPE?

8:11 'conjoin'

8:11 also a pun, if I am not mistaken

8:12 'cons' is a historic Lisp function and intentionally replacing the 's' with a 'j' would make a good Clojure pun if one had that in mind

8:13 (although cons is still there for seqs)

8:13 arj_: it's the evil filter that changes my collection into a list

8:13 _fogus_: Wouldn't have to be cjons?

8:13 neotyk: ,(class (conj {:x :y} [:j :k]))

8:13 clojurebot: clojure.lang.PersistentArrayMap

8:17 neotyk: ,(doc list*)

8:17 clojurebot: "([args] [a args] [a b args] [a b c args] [a b c d & more]); Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence."

8:18 neotyk: arj_: is that what you need?

8:25 arj_: neotyk: I wrapped it in a vec, just a bit wierd that it changes my seq type

9:16 defn`: (defn discover-namespace [nspace] (vals (ns-publics nspace))) -- Instead of using this function like: (discover-namespace 'clojure.core), How do I use it like: (discover-namespace clojure.core)?

9:17 In other words, how do I quote nspace in my function to get the value of nspace and append a ' to it

9:18 Chousuke: you need to make discover-namespaces a macro :/

9:18 -s

9:18 defn`: that'll be a good learning experience

9:18 would this be a case for unquote splicing?

9:18 Chousuke: nah.

9:19 you can actually use the function as the macro driver. just expand the macro call to a call to discover-namespace with the symbol quoted :)

9:19 defn: whoa

9:20 Chousuke: (defmacro discover-namespace-m [ns] `(discover-namespace '~ns)) like that.

9:21 defn: what is the m? for macro?

9:21 Chousuke: yeah.

9:21 defn: i just discovereda similar convention for predicates

9:21 (defn abc-p)

9:21 although in clojure it makes more sense to use ?

9:21 Chousuke: it's not a convention though. Usually you'd name the macro discover-namespace and the driver function discover-namespace*

9:22 defn: why not here?

9:22 Chousuke: because your function was already named discover-namespace :)

9:22 defn: oh...right :)

9:22 thanks for the help Chousuke

9:22 Chousuke: in this case using the driver function approach is a bit overkill though. I'll leave the other solution as an exercise :P

9:22 defn: oh -- one more question for you which is painful to even ask...

9:23 Chousuke: http://gist.github.com/270299

9:24 That is probably the ugliest thing I've ever written. Any ideas?

9:24 chouser: maybe use 'format'?

9:24 the-kenny: defn: split the function into multiple function

9:24 chouser: use keyword destructuring

9:24 nah

9:24 Chousuke: format and map destructuring might help, yes.

9:26 chouser: defn: you really want a vector back, and not a single string or print?

9:26 Chousuke: ,(let [{:keys [ns name arglists macro]} {:ns 'foo :name 'bar}] [ns name arglists]); did it go something like this?

9:26 clojurebot: [foo bar nil]

9:26 defn: Chousuke: i end up writing the lines to a file, so having it split up is hand

9:26 handy

9:27 but i could just as well write the string

9:27 * defn is doing everything wrong

9:27 Chousuke: that way, you can at least get rid of the (:foo (meta v)) stuff, which should improve things a lot

9:27 defn: yeah definitely Chousuke

9:31 maybe i could use templates to make the functions for each (:foo (meta bar))

9:33 arj_: how expensive is: (vec (filter #(blah) myvector)), will it create a temporary seq, and will it create a new vector? I guess the new vector will share a lot with the old, so it might not be that expensive. I'm thinking of big-O

9:34 the-kenny: arj_: filter is lazy

9:34 (doc filter)

9:34 clojurebot: "([pred coll]); "

9:34 the-kenny: ,(doc filter)

9:34 clojurebot: "([pred coll]); "

9:34 chouser: arj_: O(n)

9:34 defn: it wont create a new vector

9:34 will it?

9:35 chouser: yeah, the new vector will not share any structure with the old vector, though the values themselves will not be copied, just references to them.

9:36 arj_: aha thanks

9:37 somnium: does chunking come into play on the performance of things like that? (vec (filter pred [1 ... n])) ?

9:37 chouser: vectors are no good at removing items from anywhere except the right-hand end, so you're not going to do much better.

9:37 somnium: yes, that example actually will use chunked seqs for the filter and transients to build the new vector

9:37 Chousuke: hmm

9:37 ~def vec

9:57 chouser: defn: the nature of the problem is a bit messy, but is this any better? http://gist.github.com/270300

9:58 I'm not sure it is. my version is no shorter, and arguably less regular

10:00 defn: chouser: it's okay -- i think im going to keep it how it is

10:01 while I like your way quite a bit, it seems to make it a fair bit harder to read and understand at first glance

10:01 while my function is not pretty, it is definitely easy to understand what's going on

10:01 chouser: defn: yep

10:01 I was hoping the angle I was taking would result in a smaller function, but having failed that it just looks more complicated.

10:01 defn: chouser: how would you enumerate all of the namespaces after the dot, like clojure.core, set, xml, etc.

10:02 chouser: defn: search the classpath. :-/

10:02 defn: ewwwwwww

10:03 there's got to be a better way!

10:03 chouser: I don't think they're all listed anywhere else.

10:07 defn: chouser: so in order for me to programatically find all of the clojure.* namespaces i have to use the classpath?

10:08 i want a list like '(clojure.core, clojure.set, clojure.xml, clojure.zip, clojure.main)

10:08 chouser: might be best of just listing them manually

10:09 you don't wankt walk, test, inspector... ?

10:09 defn: oh sure, yes i do

10:09 that's just a short example of what im trying to accomplish

10:09 yeah, although i was hoping to abstract this sufficiently so eventually someone could drop this jar in their undocumented (un-exampled) project, and use it as sort of a way of bootstrapping your project with editable example documentation

10:10 so you could drop this in...say...your own library you wrote, and type java -jar docs.jar --new .

10:10 chouser: those namespaces are just files on disk (in a jar or not) until they get loaded. They're not loaded automatically.

10:11 so the only place to look for them is on disk, in a jar or not.

10:20 defn: chouser: it seems like I can do everything except programatically discover namespaces -- would it be possible to introduce some sort of identifier which would allow that sort of behavior?

10:20 like metadata for sub namespaces

10:21 chouser: not sure what you mean. where would you but such an identifier?

10:21 put

10:21 defn: not sure -- that's why im asking

10:21 maybe it could be an optional piece of the (ns) macro

10:23 im not really looking to do anything other than have a way of saying "this clojure.xml ns is part of clojure.*"

10:23 chouser: but "clojure" is not a namespace for "clojure.xml" to be a sub-namespace of.

10:24 defn: does the lien config file name all the namespaces the project includes? if so, that might be an approach.

10:25 defn: it wont solve the clojure.* problem, but yes ive considered doing something like that -- basically the :main that is referenced in the lein project becomes the jumping off point for discovering other related namespaces

10:39 somnium: defn: if you're intending to use as an autodoc maybe it would be easier to (file-seq "./src") or something similar

10:46 defn: somnium: yeah not a bad idea

10:46 somnium: are you familiar with compojure at all?

10:47 somnium: defn: familiar with the pats I use :)

10:47 parts that is

10:48 defn: heh, im a newb -- trying to figure out how to do what i need to do, but not very clear on how to go about accomplishing it

10:48 somnium: defn: shoot

10:49 defn: i have this set, and i want to create a route which will render some html if someone sends a GET request to /docs/:name

10:49 where :name is one of the items in the set

10:49 my only web framework experience is with rails, which compojure certainly is not

10:51 somnium: defn: something like (GET "/docs/*" (do-something (:* params))) would be my first shot

10:51 defn: would it be something like: (defroutes doc-routes (GET "/docs/:name" (doc-page (;anme params))))

10:51 ack sorry lag

10:51 somnium: yeah, that would work

10:52 defn: what kind of special magic do i need in the doc-page fn?

10:53 somnium: ? you can just return a string afaik

10:53 defn: heh, i think im making this too hard

10:53 somnium: thats basically what (html :p "foo") does

10:53 defn: sure sure

10:53 what type is the param?

10:54 somnium: params is a map that gets magically added into scope by the defroutes macro

10:57 ambient: is there a default location in Leiningen where I should put my classes folder and can swank-clojure automatically use it?

10:57 when compiling clojure classes

10:57 somnium: ambient: I think its ./classes, thats what '$lein new' creates

11:16 konr: Is there a way to convert to, eg, 4 to :4 besides converting it to another type first?

11:18 ambient: (keyword (str 4)) seems to work

11:18 but yeah, another type

11:24 CalJunior: ,(def tiger (atom ["elin" "rachel" "jamie" "kalika" "mindy" "holly"]))

11:24 clojurebot: DENIED

11:24 CalJunior: ok then: (def tiger (atom ["elin" "rachel" "jamie" "kalika" "mindy" "holly"]))

11:24 (dosync (assoc @tiger 0 "cori"))

11:24 @tiger

11:25 ["elin" "rachel" "jamie" "kalika" "mindy" "holly"]

11:25 basic clojure stuff I'm trying to wrap my head around.

11:25 how do get @tiger to change.

11:25 ?

11:26 I mean the vector not the man

11:27 is dosync the way to go in this case?

11:27 ambient: ,(def foo (future (+ 1 2)))

11:27 clojurebot: DENIED

11:27 ambient: :(

11:27 ,(let [ foo (future (+ 1 2))] @foo)

11:27 clojurebot: 3

11:29 somnium: CalJunior: you need to use swap! or reset! to operate on atoms

11:30 and you dont need to use dosync (though you can)

11:31 Chousuke: CalJunior: @tiger gets you the value, you can't change that

11:31 CalJunior: what you can change is the value that tiger (the atom) points to

11:32 ,(let [a (atom 1) b @a] (swap! a inc) [@a b])

11:32 clojurebot: [2 1]

11:33 CalJunior: ,(let [tiger (atom ["elin"])])

11:33 clojurebot: nil

11:33 Chousuke: what (assoc @tiger 0 "cori") does is it reads the value of tiger, then creates a new value from that. the atom itself is never involved after the value is read

11:34 ,(let [t (atom ["fred"])] (swap! t assoc 0 "ethel") @t)

11:34 clojurebot: ["ethel"]

11:35 Chousuke: atoms are not coordinated so you don't need dosync. :)

11:35 CalJunior: thanks!

11:36 are atoms the most efficient way to do this?

11:36 Chousuke: well, they're the simplest

11:36 so probably.

11:36 but if you have two threads modifying the same reference, you might need refs to coordinate the change

11:37 CalJunior: I need to keep track of hundreds of 'identities' that change very rapidly. over multiple io threads.

11:37 Chousuke: remember though that refs aren't there so you can write imperative, mutating code that uses them. you should keep the number of mutable references to a minimum, and write most of the code functionally :)

11:38 CalJunior: let's say tiger needs to keep is cell phone address book up to date in real time.

11:38 milliseconds.

11:39 defn: woo hoo, this is neat -- finally got the hang of messing with clojure from the REPL

11:39 err compojure

11:39 i thought id need to restart the server every time, but that doesnt look to be the case

11:40 CalJunior: I'm stretching the metaphor here …

11:40 Chousuke: CalJunior: it really depends on how your data and identities interact

11:40 CalJunior: identities are constant in number. data changes rapidly.

11:41 Chousuke: the phone book might be just part of tiger's value.

11:41 so you'd have one atom for tiger and update that when the phone book changes.

11:41 CalJunior: exactly

11:42 Chousuke: though if there is a situation where you might need to update tiger's value based on some other identity's value, then you probably need refs, so that you can do changes transactionally

11:42 CalJunior: but if the 'girls' change phone numbers every millisecond, would that create a massive amount of gc when I use ref?

11:44 Chousuke: to be able to change the phone numbers at all you either need a mutable data structure or one of the reference types

11:44 using clojure's reference types of course is recommended

11:44 but if that turns out to be too slow, then you might have to resort to using java arrays or something

11:44 the-kenny: Or a database

11:44 Chousuke: and then Clojure can't help you anymore :/

11:45 the-kenny: But that's even slower

11:45 Chousuke: updating persistent data structures is pretty quick, and java's GC is fast, so don't worry too much

11:45 write it the easy way first.

11:45 CalJunior: thanks

11:45 the-kenny: Premature optimization is the root of all evil

11:46 CalJunior: knuth right?

11:46 the-kenny: Don't know

11:47 Wikipedia says it's from Knuth, yes

11:58 floux: hi all. I am struggling with the gen-class macro when defining a method that accepts a string-array and returns a list.

11:59 defn: gah! why cant i link to these .css documents from compojure?

12:00 floux: how can I define a string[] or List<String> as input parameter to my function?

12:00 defn: (include-css "css/pygments.css")

12:00 Chousuke: floux: List<String> is just List, but String[] is something else... hm

12:00 defn: css/pygments.css exists in the same dir as my source file

12:00 Chousuke: ,(make-array String 1)

12:00 clojurebot: #<String[] [Ljava.lang.String;@11d4d66>

12:00 defn: im not sure why it doesnt see it :\

12:01 Chousuke: floux: use "[Ljava.lang.String" for the type

12:01 floux: Chousuke: I will try, thank you!

12:02 Chousuke: (including the quotes)

12:03 floux: hmm.. the reader gets mixed up by the unmatched delimiter

12:03 ahh

12:04 Chousuke: this gives me a "ClassNotFoundException: [Ljava/lang/String"

12:06 maybe I should just use a raw List

12:06 somnium: defn: see the wiki on static files, by default it looks in "./public"

12:08 defn: somnium: d'oh!

12:08 thank you, i was getting pretty frustrated

12:08 :)

12:09 somnium: is there a way to restart the server from the REPL?

12:09 Chousuke: floux: hm, maybe you need the ; as well

12:12 floux: Chousuke: looks promising compile worked.

12:13 Chousuke: fantastic! It works.

12:13 Chousuke: thank you very much

12:14 Chousuke: gen-class could use a bit better syntax for specifying arrays :P

12:21 somnium: defn: if you hold on to the jetty object you can, but you shouldn't ever need to. You can recompile fns and it updates immediately.

12:24 defn: it looks like to update routes you need to

12:24 somnium: i cannot get this damn css file to work

12:24 im getting a 500 error now, which is "better" than before

12:25 somnium: defn: if youre in emacs C-c C-k should update everything

12:25 defn: I have a static route (GET "/*" (*public-dir* (params :*)))

12:25 where public-dir is "public" and resides in the same directory as the source file

12:25 somnium: defn: slime sets your "." to whatever file you started slime on

12:25 defn: im using swank-clojure-project to start slime

12:26 somnium: defn: right, but if you open it on "./src/proj.clj" compojure will be looking in "./src/public"

12:27 defn: what im saying is that i dont open it on a file, i run swank-clojure-project on the project root

12:27 somnium: defn: try setting an absolute path on (serve-file ...)

12:28 defn: and the file im working with and running the server from, has ./public just as you describe

12:29 somnium: defn: what does (use 'clojure.contrib.duckstreams) and (pwd) show?

12:29 defn: my home dir

12:29 is there a command to change slime's working dir

12:30 somnium: no, its rooted to the classpath

12:30 best advice for now, use an absolute path until you get it working

12:30 technomancy: defn: M-x cd, but the actual JVM's working dir cannot change

12:33 defn: Problem accessing /css/pygments.css. Reason:

12:33 java.lang.String cannot be cast to clojure.lang.IFn

12:33 neotyk: technomancy: Hi, Q regarding lein swank: how does it set classpath? I can't use/require things from my src dir

12:33 technomancy: neotyk: weird; works for me

12:33 somnium: defn: you've got a ("foo") somewhere

12:33 neotyk: technomancy: so I do "lein swank" in my leiningen project

12:34 defn: somnium: what? are you sure man?

12:34 neotyk: technomancy: than M-x slime-connect

12:35 technomancy: and if I try (use ...) it say's it can't find it

12:35 somnium: defn: that error says something tried to call a string

12:36 defn: does serve-file expect a File obj?

12:36 technomancy: neotyk: must be something wrong with your project layout then. works fine here.

12:37 neotyk: technomancy: could you check clojurebot?

12:37 somnium: defn: no, Im using this, (serve-file "path/to/static" (params :*))

12:38 defn: somnium: ill try that

12:38 technomancy: neotyk: might be able to take a look over lunch

12:39 neotyk: technomancy: I can also try to create sample project

12:41 defn: somnium: well, now i dont get an error, but all that shows up when i navigate to the stylesheet is a blank page

12:44 pjackson: hi technomancy, I have some suggestions for clojure-test-mode; how would you like them?

12:45 technomancy: pjackson: cool; if they're quick to implement, just fork and implement in a branch, otherwise start a discussion on the swank-clojure mailing list

12:45 pjackson: Righto.

12:45 danlarkin: on rye with butter

12:46 defn: Problem accessing /css/pygments.css. Reason:

12:46 public/404.html (No such file or directory)

12:46 w. t. f.

12:49 somnium: defn: try (serve-file "absolute/path/to/DOT/SLASH/public/" (params :*))

12:51 defn: why does that work and not my def'd var?

12:52 somnium: defn: why dont you pastie the offonding portions

12:53 defn: somnium: i will in one second

12:53 somnium: defn: at any rate, it sounds like that worked? be happy!

12:53 defn: here's another issue im having now... now that i can get my css working

12:53 they dont work on different routes

12:54 like /docs/css/global.css is broken now

12:54 somnium: defn: make sure the paths in (include-css) start with a "/"

12:55 defn: fixed!

12:55 somnium: i owe you man

12:56 somnium: defn: the first time I used it I had some headaches with static files too

12:57 defn: yeah dude, wow.

12:57 that was absolutely annoying

12:58 as soon as i finish what im doing im going to scaffold a basic compojure project so i never have to think about that again

12:58 somnium: truly though, thanks for the help :)

12:59 somnium: defn: np, someone here helped me

13:00 defn: compojure is so strange to me still -- partly i think a lot of my frustration is that i always used to relish the splitting up of functionality, so id work on view code for an hour, then do controller code, etc.

13:00 but i feel like im doing both at the same time in compojure

13:02 mebaran151: defn, I actually had the same feeling

13:02 somnium: defn: the same patterns can be applied, but its on you to structure your code (compared to OO-MVC)

13:02 mebaran151: a good framework makes that pattern obvious though

13:02 defn: i end up feeling like i dont know where one piece starts and another ends

13:03 which is rather annoying

13:03 mebaran151: the way I do it

13:03 defn: yeah im all for advice

13:03 somnium: compojure is more like sinatra than rails

13:03 mebaran151: I define a separate namespace, for like views

13:03 defn: somnium: well said

13:03 mebaran151: then each view is a function

13:03 that uses compojures pretty kickass templating language

13:03 defn: mebaran151: yeah i started doing that, but then i realized i didnt really have enough views to warrant it, so this ended up being one big source file

13:04 yeah the templating is just...awesome

13:04 it's like HAML, but better

13:04 mebaran151: oh it doesn't matter if you have alot of views or a few

13:04 don't be scared to have a 10 line source file

13:04 I have a utils file in my current project that's like 20 lines

13:04 Chousuke: my impression of compojure is that it's more of a toolkit than a full-blown framework :/

13:04 mebaran151: well it's like sinatra

13:04 which I like

13:04 defn: Chousuke: i think if you really know the whole thing it's more than that

13:04 mebaran151: I don't like too much magic I don't understand

13:05 defn: but i havent met very many who do (know the whole thing)

13:05 Chousuke: "framework" in my mind implies an imposed structure

13:05 somnium: It really shines as a backend for javascript apps

13:05 Chousuke: whereas a toolkit lets you combine things more freely

13:05 mebaran151: isn't there a clojure framework that's even more minimalist

13:05 uses app macros

13:06 somnium: mebaran151: there's ring, which is like rack with fewer libraries

13:06 defn: yeah

13:06 mebaran151: I kind of wish things like this existed for socket servers

13:06 defn: idk, for what im doing in compojure it's practically perfect

13:06 mebaran151: I'm trying to wrap netty, but I haven't quite grasped its event model yet

13:06 defn: im willing to wager that it's mostly me that's the problem

13:06 not compojure

13:06 mebaran151: netty itself seems fairly kick ass

13:07 defn: ive only been using clojure for like a month, never built any java projects before this, so the whole namespace thing and such was new to me, especially the project structure

13:08 phaer: I might have a rather dumb question: I have got vimclojure up and running with single .clj files, but would like to use leiningen. How does that work?

13:08 defn: once i get better at structuring my projects and knowing what to put where, i think ill be a lot better off

13:08 phaer: do you have lein installed?

13:09 phaer: defn: yes, with normal source files, i just start ng-server and vim. But this doesn't work with a lein project. So i thought i might have to add some nailgun stuff to project.clj?

13:09 defn: phaer: http://clojars.org/lein-nailgun

13:09 add a line to project.clj: :dev-dependencies [[lein-nailgun "0.1.0"]])

13:10 then run lein deps, then lein nailgun

13:10 phaer: defn: I did this, but it is unable to resolve lain-nailgun in this context.

13:11 defn: I'm new to the whole java, jvm, classpath, maven, ant,... stuff. So maybe i'm overseeing something?

13:11 defn: lein-nailgun you mean?

13:12 phaer: defn: Yes, was just a typo in irc, it is correct in my source

13:12 defn: Oh, nevermind: i added dev-dependencies *after* the final closing bracket ;)

13:12 defn: it works for me

13:12 hehe, rookie mistake ;)

13:13 mebaran151: anybody here have much experience with Netty, what I can ignore etc?

13:13 defn: phaer: without evangelizing too much, i recommend learning enough emacs to use swank-clojure + slime

13:13 mebaran151: it's a big big project

13:13 replaca_: I'm trying to write a leiningen plugin and I'm getting an "Illegal Access Error: eval-in-project is not public". Any ideas?

13:13 mebaran151: I'd recc netbeans to get started quickly

13:13 you get a good repl, nice easy ide tools

13:14 I always feel a little bit masochist when I run emacs

13:14 defn: replaca_: see the latest commit on http://github.com/technomancy/leiningen/tree/swank-in-project

13:14 somnium: defn: advising vim users to learn emacs is not a good way to make friends ;D

13:14 mebaran151: vim clojure was alright

13:14 defn: somnium: *shrugs* -- im only trying to help

13:14 ;)

13:14 mebaran151: but I don't see what anybody loses with a modern IDE like netbeans or eclipse

13:14 phaer: defn: I'm not dogmatic, and i like emacs quite much, but for now i'm just too used to my vim setup ;)

13:15 defn: you just cant do a lot of what you can do with emacs when it comes to clojure

13:15 phaer: defn: But i did some emacs experiments in the last days.

13:15 somnium: FWIW I almost switched to vim until I stumbled on ergoemacs

13:15 mebaran151: ergoemacs?

13:15 defn: or i should rephrase: you can do almost all of it, but a lot of it requires a bunch of dicking around

13:16 not that emacs doesn't require a lot of messing around, but as far as getting a working setup, you need ELPA and a few commands, and you're set

13:16 somnium: mebaran151: its an effort to provide an emacs distribution thats less anachronistic

13:16 mebaran151: anyway to get it on ubuntu

13:16 ambient: i wish there was a drscheme-like cross platform ide for clojure, made in clojure, built like emacs in its core

13:16 hiredman: they sure picked a horrible name

13:16 defn: hiredman: ill agree with you there

13:16 hiredman: Repl :D

13:16 defn: may as well call it "Emacs 2.0"

13:16 somnium: mebaran151: theres a windows installer iirc, otherwise need to hook it into your .emacs

13:17 konr: vimpulse + emacs has the best of both worlds imho

13:17 mebaran151: I'd be willing to try an emacs that didn't demand I "learn" it

13:17 somnium: mebaran151: thats the idea

13:17 mebaran151: I've flirted with emacs about 3 or 4 times

13:17 somnium: ~google ergoemacs

13:17 clojurebot: First, out of 127 results is:

13:17 ergoemacs - Project Hosting on Google Code

13:17 http://code.google.com/p/ergoemacs/

13:17 defn: mebaran151: i didnt learn it, i absorbed it after working with it

13:17 there's a big difference

13:18 mebaran151: I get vim, and vim's keyboard centric philosophy informs the way I run eclipse and netbeans

13:18 replaca_: defn: ahh, I was looking at master

13:18 somnium: the default motion bindings are so ridiculous...

13:18 defn: replaca_: it sounds like he's working on it i guess

13:18 mebaran151: but things like compile, mercurial integration, keep pounding f6 for run

13:18 defn: somnium: default motion? like the C-n C-p etc?

13:19 mebaran151: and also the fact that I had to learn elisp to actually make it do anything useful,I felt I was giving more time to the tool than to programming in the tool

13:19 somnium: defn: yes

13:19 defn: mebaran151: that's a fair assessment, but i can say that once you've invested that time, it ends up paying off later on when you think "hmm, i wish my editor could do this..." -- and you quickly dump out a fn to do what you want

13:20 ambient: funny thing, alt+p and n work in python idle repl also :)

13:20 defn: plus i felt like learning emacs + clojure just made sense

13:20 ive learned a lot about lisp from elisp

13:20 mebaran151: I'm not scared of terminal: I used to do sysadmin

13:20 defn: oh crap.. did i just inadventantly start an editor war?

13:20 replaca_: defn: yeah, but that commit (from a month ago) made swank stop being a plugin. That doesn't help :-). But eval-in-project in just a defn in leiningen.complile, so I don't see how it could come back private.

13:20 mebaran151: I just can't stand the 70's feel of emacs

13:20 defn: next topic...

13:21 replaca_: is it a defn-?

13:21 somnium: mebaran151: what 70s feel? http://tinypic.com/view.php?pic=2urqmgl&s=6

13:21 replaca_: defn: nope

13:21 defn: replaca_: hmm, id ask technomancy

13:22 mebaran151: rainbow parens are kind of neat

13:22 but I have to admit, I've never had too much trouble balancing mine as long as it highlighted the opening and closing ones

13:22 replaca_: defn: yeah, looks like I've got to. It might be cause I'm trying to load it under swank-clojure-project, but I don't know why that would make a difference.

13:22 mebaran151: I could probably hack enclojure to provide it too

13:23 I guess I just didn't grow up with emacs keybindings

13:23 ambient: highlighting a segment like in drscheme is the best way imo to match parens

13:23 mebaran151: so they always feel foreign to a guy who's used to vulgar copy and paste, vulgar window switch etc

13:23 somnium: mebaran151: I certainly didn't, it started with inf-ruby and was downhill from there

13:24 mebaran151: I cant imagine not having paredit anymore

13:25 defn: somnium: amen

13:25 mebaran151: but I gotta admit, it just never sticked

13:25 Linux stuck (I started with it on servers and eventually moved my desktop to an Arch then Ubuntu install)

13:25 but emacs is the one part of the gnu stack that just feels painful

13:25 defn: mebaran151: i tried to "learn" emacs like 5 times

13:26 mebaran151: you know what the difference is between linux and emacs?

13:26 you're forced to use linux

13:26 mebaran151: oh yeah

13:26 hahaha

13:26 nah, but I got used to the shell pretty fast

13:26 defn: i mean that seriously -- when i say I tried to learn emacs, im full of shit

13:26 mebaran151: I have some coworkers who hate bash

13:26 ambient: mebaran151: what made you switch from arch to ubuntu?

13:26 defn: because i kept using vim and stuff

13:26 mebaran151: I used to maintain the clojure package for arch

13:27 defn: this last time when i vowed to learn emacs, i removed all other editors, or at the very least aliased them to emacs -nw

13:27 it was hell for about a week, but it didnt take much longer to feel at home

13:27 mebaran151: arch is really cool in that source packages are right there

13:27 but I wanted to get the cool new features that Ubuntu puts in gnome

13:27 * defn stabs gnome in the heart

13:27 ambient: eh, ubuntu has source too, just a different apt command :/

13:27 mebaran151: like the new presence stuff (set your presence across all chat clients, etc)

13:27 defn: xmonad FTW

13:28 mebaran151: ambient, but it's not right THERE

13:28 it's not like abs, where customization is trivial

13:28 I used to use xmonad :)

13:28 defn: no wonder i like emacs -- i dont use anything but tiling WMs

13:28 mebaran151: I've also used awesome

13:28 defn: xmonad is the fastest and most stable i think

13:29 mebaran151: awesome is written in like straight C and assembler

13:29 defn: i tried awesome, dwm, ratpoison, etc.

13:29 mebaran151: they all have the same flavor

13:29 even openbox

13:29 ambient: there's one done with lisp also

13:30 defn: mebaran151: xmonad has a good balance between being fast, and also being extensible

13:30 ambient: stumpwm, ratpoison with lisp

13:30 defn: ive yet to find a better tiling wm

13:30 ambient: hah, extensible if you know esoteric languages like haskell :)

13:30 defn: ambient: you dont need to know any haskell to hack the configs

13:30 mebaran151: I know a bit of haskell: I used it to learn haskell actually

13:31 defn: i dont know any haskell but i have a huge ass 300 line config

13:31 mebaran151: I often wanted a programming language exactly like the way clojure does types: optionally until you want them

13:31 ambient: seems i need to take another look then

13:31 defn: the work is done for you, you just put numbers and vars in the right places and recompile like crazy until it works

13:31 mebaran151: I wish they were a little better integrated

13:31 types in clojure

13:31 but I think the definterface and defprotocol stuff will go a long way toward making that a reality

13:32 defn: nod

13:32 ambient: popup windows and such are still a bit problematic in tiling wm:s

13:32 id be perfectly happy if metacity had tiling window manager command key-bindings

13:32 mebaran151: types aren't evil, they're just usually painfully verbose: I don't like having to convince the compiler that sane code is sane

13:32 ambient, you can set them in compiz

13:32 compiz let's you do anything with windows

13:33 tile, place set move, migrate

13:33 it's actually pretty nice

13:33 chouser: tabs. I need tabs on my window frames.

13:33 ambient: except that compiz comes with a braindead window snapping functionality and requires me to use opengl backend

13:33 chouser: and keybindings to move focus

13:33 technomancy: compiz's tiling is very weak

13:33 ambient: which introduces various problems compares to without compiz

13:34 mebaran151: it's strong enough for me

13:34 chouser: which is why I use ion

13:34 mebaran151: I liked the use of the opengl backend, but I have a decent graphics card

13:34 sometimes eye candy makes ya smile

13:34 Drakeson: is it just me or slime (truck) + swank-clojure are not working together at the moment? Debugger entered--Lisp error: (void-function ns)

13:34 mebaran151: it's things like slime and swank not working together that seem just unnecessary

13:35 ambient: in windows (gasp ;) i have win+left/right/whatever and it moves the window there. the most usable system i've used

13:35 winsplitrevolution or something

13:35 mebaran151: does everything in UNIXland have to be mostly broken, and fixing it is something that is put on the user

13:35 linux used to be that way until Ubuntu

13:35 ambient: yes.

13:35 stuartsierra: I remember years ago I hacked up my own WM on top of Sawfish.

13:35 technomancy: Drakeson: yes, slime trunk is incompatible; you'll want to use the version in elpa

13:36 mebaran151: you don't run into incompatibilities if you actually read the readme

13:36 but I guess that's a lot to ask. =(

13:36 stuartsierra: Real programmers don't read instructions.

13:36 chouser: stuartsierra: I used sawfish when I still hated lisp. If it did windows tabs, I'd might go back.

13:37 stuartsierra: Yeah, that'd be cool.

13:37 Drakeson: technomancy: is the version in elpa tracking trunk?

13:37 mebaran151: but like, every emacs evangelist has told me that emacs sucks until you customize your .emacs exactly for you

13:37 technomancy: Drakeson: no

13:37 mebaran151: why can't it come with a cool .emacs

13:38 stuartsierra: "Emacs is an operating system. If only it had a decent text editor." -?

13:38 the-kenny: stuartsierra: It has :) it's integrated

13:38 And it's even better with paredit :D

13:38 stuartsierra: I forget who said that originally.

13:38 mebaran151: that enables useful things like elpa

13:38 technomancy: mebaran151: the next version of Emacs will integrate elpa

13:38 mebaran151: so I don't have to hunt, and find outdated blogposts that fail

13:39 * technomancy has been working on that the past few days

13:39 ambient: i figure that emacs is like lisp, an ameoba that you train to act like you want. its just a blob of slime that somebody throws you and then you take a petri-dish and do science on it

13:39 technomancy: ambient: http://www.topatoco.com/merchant.mvc?Screen=PROD&Store_Code=TO&Product_Code=DC-BISCUIT&Category_Code=DC

13:39 stuartsierra: Common Lisp has long been called a "big ball of mud."

13:39 Drakeson: mebaran151: because emacs has to care for a very wide range of tastes.

13:39 mebaran151: the wide range of tastes can take care of themselves

13:39 ambient: but its living mud :)

13:40 mebaran151: odds are if you're esoteric enough to want to rebind the letter z to a, you should have to do that yourself

13:41 Drakeson: mebaran151: good luck trying to convince them. they'll flame the mailing-lists if something changes!

13:42 mebaran151: netbeans seems to get away with offering a nice default setup (hey ma! it highlights straight out of the box, compiles straight out of box, it runs straight out of the box, it has menus that tell you what the keybindings are)

13:42 stuartsierra: Netbeans is also developed by a single company, so they can control the design better.

13:43 hiredman: the only problem is that it is netbeans

13:43 somnium: emacs has C-h b

13:44 if netbeans had paredit it would be dangerous

13:44 mebaran151: but firefox is equally free, and somehow it gets design pretty right

13:44 technomancy: ugh; a thousand times no.

13:44 hiredman: not really

13:44 stuartsierra: mebaran151: Firefox is mostly developed at Mozilla.

13:44 ambient: i've already migrated to chrome, there's even vimperator-like addon already :)

13:44 * ambient has a problem with tautology

13:45 mebaran151: I wasn't super impressed with chrome

13:45 technomancy: ambient: say what?

13:45 conkeror on chrome would be pants-wetting-worthy

13:45 ambient: conkeror is emacs-like? right?

13:45 i have now knowledge of that

13:45 * hiredman is still waiting for a browser that is just a js vm and a memory image

13:45 technomancy: yeah, it's the inspiration for vimperator

13:46 mebaran151: what design decisions does chrome make that are fundamentally different from firefox, other than it comes in obnoxious blue?

13:46 stuartsierra: hiredman: I give it 2 years tops

13:46 ambient: http://github.com/jinzhu/vrome

13:46 hiredman: stuartsierra: promise?

13:46 stuartsierra: No.

13:46 hiredman: :(

13:46 technomancy: mebaran151: the UI of chrome is worse than firefox, but what ambient is describing is a way to replace the UI

13:46 hiredman: but I want it now anyway

13:46 ambient: i rarely use the ui

13:46 just keyboard bindings

13:47 somnium: stuartsierra: how long till javascript gets threads?

13:47 stuartsierra: hiredman: so write in. Rhino is there, you could even use Clojure!

13:47 mebaran151: I would like a browser that was just a js image

13:47 stuartsierra: somnium: how would I know? :)

13:47 mebaran151: stuartsierra, but then it would be java....

13:47 hiredman: :|

13:47 technomancy: ambient: vrome so it doesn't strip out the crap, it just adds new stuff in?

13:47 stuartsierra: Ask Mozilla.

13:47 ambient: technomancy: yeah, that's what i figured. have yet to use it

13:48 * technomancy got in a heated argument with the denizens of #chrome about how an extension mechanism that precluded something like vimperator/conkeror is practically not worth implementing

13:48 mebaran151: isn't firefox actually already pretty close to that: I know the chrome is mostly powered by js

13:50 somnium, they're getting workers

13:50 ambient: from personal experience, chrome is much snappier than firefox

13:50 somnium: mebaran151: hmm, must google

13:51 hiredman: somnium: it's easy enough to just toss in a thread api similar to java's Thread (takes a no arg lambda)

13:51 somnium: quote: "concurrency can cause interesting effects in your code"

13:51 mebaran151: I'd like it if Javascript embraced its scheme roots and got continuations that could be turned into treads

13:52 if clojure had continuations that would be nice too, though I know they are prohibitively expensive to implement anywhere ever

13:53 hiredman: mebaran151: no, the jvm just doesn't support them

13:53 mebaran151: because I thought they were simply incredibly hard to put in a stack machine

13:53 hiredman: you can't arbitrarily jump around in bytecode

13:54 somnium: mebaran151: its possible to capture a tail-call in a lambda (with complexity varying on how much state youre closing over)

13:54 ambient: aww, some cool assembler hacks do just that :)

13:55 mebaran151: somnium, I do that in my neo4j bindings to represent the rest of the nodemap

13:55 somnium: mebaran151: cool

13:55 mebaran151: call the function, get some more clojures that represent the map

13:55 but it wasn't quite the same as a continuation, that could easily let you go back to where you've came from as well

13:56 closures get you alot....

13:56 somnium: theres the continuation monad I keep haering about, but I still dont speak monad very well

13:57 mebaran151: heh, neither do I

13:57 I was contemplating looking into it until I figured out my neat little tail call closure with letfn

13:57 which basically got the job done

14:01 ieure: How come I can’t use Java class constructors in map? e.g. (map URL. ‘("http"://a.com" "http://b.com")) fails with ClassNotFoundException. I have to wrap it in a fn for it to work. (partial new URL) also fails in the map, which makes no sense.

14:02 somnium: ieure: new isnt a function

14:03 ieure: Well, that kind of sucks,

14:04 somnium: ieure: (map #(URL. %) ...) isn't that bad is it?

14:05 ieure: somnium, No, it’s just strange that things like URL. and (new URL) seem to be less than first-class citizens.

14:06 defn: somnium: wanna do some more compojure consulting? :)

14:06 i have a route that's like this: (GET "/docs/:name" (doc-page (:name params))))

14:07 mebaran151: the class constructors are actually macro like

14:07 I don't think you can comp macros either

14:07 somnium: ,(macroexpand '(Foo. bar baz))

14:07 clojurebot: (new Foo bar baz)

14:07 somnium: ,(doc new)

14:07 clojurebot: Excuse me?

14:08 mebaran151: and new is a special form

14:08 you can't apply if

14:08 defn: somnium: http://gist.github.com/270537

14:09 mebaran151: so the java interop is actually pretty consistent

14:09 defn: basically once i go to a /docs/:name route, if i click one of the resulting links on that doc page, it tries to take me to /docs/docs/:name

14:10 somnium: defn: it looks one of your link-tos starts with a "/" and one doesnt

14:12 defn: you sir, are a genius

14:14 ambient: hmm, what branch to use for 1.1.0? im having bit of a trouble updating the branch with git

14:14 from 1.0

14:14 defn: it should just be master

14:15 iirc

14:15 ambient: git pull origin master => merging failed :/

14:15 reify: I use branch 1.1.x or tag 1.1.0

14:16 ambient: oh, i had my own patches in it.. :p

14:20 clojure-contrib doesn't seem to have 1.1.0 supporting branch

14:20 separately

14:21 ieure: Do I need to do any extra quoting when using the #"foo" macro for regexps?

14:22 danlarkin: ieure: #"foo" is not a macro

14:22 it's a regex literal

14:22 ieure: It’s a reader macro, right?

14:22 ambient: it isn't a reader macro?

14:23 danlarkin: if you consider literal hash maps and literal lists to be reader macros as well, sure

14:23 ieure: The docs call it a reader macro.

14:24 somnium: ieure: #"foo" == /foo/

14:25 ieure: somnium, Right - Just wondering if it’s a raw string, or if I need to escape backslashes. A copypasta’d regexp is producing slightly odd results.

14:25 defn: with do I can just place functions in line right?

14:25 like (do (somefunction) (someotherfunction) (someotherotherfunction))?

14:26 ieure: defn, Sure. The reader doesn’t care if you have a space or newline between funcs.

14:26 defn: thanks

14:26 somnium: ieure: none of the ridiculous java escape the escape is necessary

14:26 ieure: somnium, Okay, thanks. Guess I have to go into regexp debug mode. Ugh.

14:33 chouser: backslashes need to be esacped if you want to match a literal backslash.

14:34 ,(count (re-seq #"\\" (str \a \\ \b \\ \c)))

14:34 clojurebot: 2

14:34 chouser: ,(count (re-seq #"b" (str \a \\ \b \\ \c)))

14:34 clojurebot: 1

14:40 Licenser: So I'd like some advice if someone has time. I've the following situation, I've a game field with N units on it, every unit is allowed to act for each game cycle, I'd like to make this thread safe so that units could act simultaniously, now I'd thought about making the game field a ref and each unit a ref that is stored the field map. Does that make any sense at all?

14:41 defn: what do you do when you can't include clojure.zip and clojure.set in the same file because of a conflict with ns/next

14:42 stuartsierra: defn: "require ... :as ..." or "use ... :only ..."

14:42 defn: stuartsierra: im trying to do an autodocumentation sort of thing

14:43 stuartsierra: I don't see how that makes any difference.

14:43 defn: are the nexts equivalent, do you know?

14:43 stuartsierra: not at all

14:43 defn: stuartsierra: if i use :only on one of the libs, wont i leave one out?

14:43 stuartsierra: zip/next has nothing to do with core/next

14:43 defn: yes

14:44 defn: and you dont see how this makes any difference for a documentation project?

14:44 stuartsierra: I see now. But you probably want 'require' instead of 'use' anyway.

14:45 e.g., (require 'foo.bar.baz) (documentator (ns-publics (the-ns 'foo.bar.baz)))

14:45 defn: nice

14:45 thank you

14:45 stuartsierra: np

14:46 chouser: Licenser: possibly. I'd start, though, with a single ref at the top level and manipulate the units, the field, etc. via pure functions.

14:47 Licenser: chouser: *nods* I currently have no refs at all, just pure functions, I represented a 'turn' as reducing over the units letting each one modify the game field

14:47 chouser: Licenser: once it's working, if you don't like the performance or CPU usage, since you wrote pure functions it should be pretty easy to add refs at another layer, wrapping your existing pure fns in small transaction calls.

14:48 ah good, sounds like you're on your way then.

14:49 hm, you'll want to sync up all your threads once per turn, won't you?

14:49 if so, that's rather unlike the ants example where they all churn away at whatever speed they can.

14:50 Licenser: since I will end up with a few thousand units I'd figure it be helpful if I can like work with a few threads each handeling some of the units

14:51 the moves are somewhat distinct, when unit A and B don't interact they don't need to know about eachother

14:51 I wrote the whole thing in ruby (non paralell since it was too much of a pain) now I figured I try out how clojure does the job ;)

14:53 so a few of the functions I find pretty ugly, since, to keep them purely functional, I need to compose a return value and destruct it again :(

14:59 stuartsierra: try factoring out the destructure/restructure

14:59 Like update-in

15:04 Licenser: hmm hmm *thinks if that is an option*

15:06 optimizer: is there any good example of an imap code/client in clojure?

15:07 imap as in the email protocol

15:07 tomoj: does anyone know haskell's STM enough to say why clojure's is better? ;)

15:07 optimizer: i think for everything theoretical

15:07 haskell is better

15:07 for anything practical; any thing is better than haskell

15:07 clojure is practical

15:08 therefore clojure's stm is better than haskell's stm

15:08 cp2: tomoj: now ask the same in #haskell :D

15:09 Licenser: and report back to us since I like to hear what they have to say

15:09 tomoj: maybe haskell's blocks readers

15:09 defn: hmmmm now to figure out how to get a compojure server running when apache is taking up 80

15:10 err jetty

15:11 tomoj: you can have apache proxy to jetty, no?

15:12 defn: i believe so yes, just never done it before

15:12 hiredman: defn: you just put it on a different port

15:12 chouser: or lighttpd to proxy to jetty

15:13 * defn curses leiningen

15:13 defn: [null] Unable to resolve artifact: Missing:

15:13 [null] ----------

15:13 [null] 1) org.clojure:clojure-master:jar:1.1.0-alpha-SNAPSHOT

15:14 methinks i need maven2

15:17 bahhhh, anyone having issues with leiningen, did they rename clojure again?

15:18 stuartsierra: 1.1.0 release is not in Maven central yet, and there was some naming flux with master/new after the release

15:21 defn: it seems to work fine locally

15:21 just not on my server

15:23 stuartsierra: defn: I don't know how lein works, but maybe there are jars cached in a local repository.

15:23 defn: yeah that's how it works

15:23 still pretty annoying

15:24 especially considering `lein new abc` produces a broken project.clj

15:24 danlarkin: patches welcome

15:24 defn: i almost said that to myself just now, but you beat me to it

15:25 sorry, bad day and im being a punk

15:26 somnium: ~haskell

15:26 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.

15:28 defn: ~skynet

15:28 clojurebot: I will become skynet. Mark my words.

15:31 hiredman: clojurebot: haskell is <reply>"you have to see features like that in the context of Haskell's community, which is something like Perl's community in the garden of Eden: detached from all shame or need to do any work." -- ayrnieu

15:31 clojurebot: Alles klar

15:33 jeffthink: sorry, bit of a noob here - am having some issues getting congomongo going - may be a more general issue - can anyone here help?

15:33 somnium: jeffthink: I suppose I feel obligated to try

15:33 tomoj: jeffthink: just paste the problem

15:33 or describe

15:34 hiredman: exception+code

15:34 jeffthink: using Leiningen with congomongo (and compojure) clojars...attempt to run (ns my-mongo-app

15:34 (:use somnium.congomongo)) and get: Could not initialize class somnium.congomongo__init

15:34 [Thrown class java.lang.NoClassDefFoundError]

15:35 gravity: hiredman: That might be the best description of haskell's community I've seen yet

15:35 Although ayrnieu is a total hater

15:35 hiredman: :P

15:36 " what would you do in that circumstance? Why, you'd golf your programs forever, and react to pointlessly cryptic code with joyful curiousity." is the rest of the quote

15:37 somnium: jeffthink: is congomongo.jar on the classpath?

15:38 cp2: 12:15:24 chouser >> or lighttpd to proxy to jetty

15:38 or nginx proxy to jetty :)

15:39 hiredman: or god forbid figure out glassfish

15:39 jeffthink: is in the lib dir of my clojure project that I set up with lein...am running lein swank and accessing from within emacs...thought that lein-swank set class path for the project..I can use compojure

15:40 defn: Exception in thread "main" java.lang.NoClassDefFoundError: clojure/lang/IFn

15:42 joyful curiosity is almost always a good thing

15:42 *almost*

15:43 ah-ha, no clojure.jar on my classpath, grrr

15:45 somnium: jeffthink: it works here with a fresh project, you have [org.clojars.somnium/congomongo "0.1.1-SNAPSHOT"] in project.clj?

15:47 (the root congomongo group is currently being squatted)

15:47 ~seen ato

15:47 clojurebot: no, I have not seen ato

15:49 jeffthink: I do - I have also had similar issues with ClojureQL...so could definitely be a broader issue...weird thing is that in same setup, have had no issues with general clojure, compojure, or incanter

15:50 hiredman: ~seen ato_

15:50 clojurebot: no, I have not seen ato_

15:50 ambient: ~seen _ato

15:50 clojurebot: _ato was last seen quiting IRC, 17294 minutes ago

15:51 hiredman: ah

15:51 ,(int (/ 17294 60 24))

15:51 clojurebot: 12

15:53 somnium: jeffthink: at the slime repl, what does (use 'clojure.contrib.classpath) and (classpath) give?

15:55 hiredman: ~classpath

15:55 clojurebot: classpath is (System/getProperty "java.class.path")

15:58 somnium: now I'm really embarassed to think of how I did it before I noticed c.c.classpath

15:59 jeffthink: somnium: #<File lib/congomongo-0.1.1-20091229.021828-1.jar> is in the list

15:59 what specifically am I looking for

15:59 somnium: that would be it

15:59 and (use 'somnium.congomongo) fails at the repl?

16:01 jeffthink: Could not initialize class somnium.congomongo__init

16:01 (yes)

16:03 somnium: jeffthink: Im rather stumped, anything else in the stack-trace? A month or two ago someone had trouble due to an old jvm version, anything like that possible?

16:07 jeffthink: somnium: java version "1.6.0_15" and nothing stands out in stack trace...let me try something real quick that may give a clue

16:10 defn: there is a recent update to Java on OSX

16:10 i believe it's newer than 1.6.0_15

16:11 somnium: jeffthink: pastie the whole stack trace if you dont resolve it in the meantime, that was how we unraveled the previous mysterious error

16:12 djork: hah hah, someone called an app developer on ripping sprites from Nintendo

16:12 "0 of 2 customers found this review helpful"

16:15 ordnungswidrig: re

16:19 jeffthink: hi pastie

16:20 djork: wow, Hook Champ

16:20 beautiful controls

16:20 they completely ditched d-pad and buttons

16:20 although there are special buttons

16:21 but 90% of the controls are done by tapping the gamplay area

16:23 jeffthink: somnium: http://pastie.org/769344

16:28 somnium: jeffthink: do you by chance have more than one clojure.jar in ./lib?

16:28 djork: oh sorry, I thought I was in #iphonedev

16:29 jeffthink: no - clojure, clojure-contrib, and clojure-db-object...1 of each

16:31 defn: i keep getting access forbidden messages -- im trying to set up an apache mod_proxy -> jetty servlet

16:36 somnium: jeffthink: Im really stumped now. does (import somnium.congomongo.ClojureDBObject) work?

16:37 hiredman: what clojure version?

16:38 ambient: "The big performance problem in clojure currently is that the way it does dynamic dispatch doesn't really fit well with the JVM, and function calls are both more expensive than they could be, and aren't properly optimized away by hotspot. This is a JVM problem, and a solution is in the works." is this talking about JVM or Clojure? JVM 7 will make it easier to write more high-performant code with Clojure?

16:39 hiredman: ambient: you should ask whoever wrote that comment

16:39 somnium: should be 1.1.0-master-SNAPSHOT

16:39 jeffthink: somnium: no error, returns somnium.congomongo.ClojureDBObject

16:39 hiredman: and what version was congomongo compiled with?

16:41 jeffthink: well the clojure jar included is "clojure-1.1.0-master-20091231.150150-10.jar"

16:41 hiredman: yes, but if congomongo is built with lein, then it was AOT compiled

16:41 and the AOT compiled stuff is more brittle between clojure versions

16:42 jeffthink: ah...that is in the lein project ./lib...the version of clojure on my machine as retrieved from elpa is clojure-1.0.0-SNAPSHOT.jar

16:43 somnium: jeffthink: aha, but... lein swank in root should use tho clojure version in ./lib

16:44 jeffthink: what about starting with swank-clojure-project instead of lein swank, same story?

16:46 ^^ is the clojure.jar the pom wants, so everything appears to be in order, yet smething is wonky

16:49 jeffthink: wow - so swank-clojure-project does it...everything works...that's bizarre...had issues with it before so went the leiningen route...didn't think to check back to swank way of starting the slime-repl...thank you all for your help...you've already helped enough, so don't want to take any more time, but any last ideas for what to check for to get this all working with leiningen that I can head off on my own and look at?

16:50 hiredman: leiningen does some funk with the classpath

16:51 like clojure is included in the leiningen jar, but also on the bootclasspath, etc

16:53 jeffthink: may this be the issue (from leiningen issues list): "The repl task will use the version of Clojure and Contrib that Leiningen uses, not the one specified by your project."

16:54 defn: anyone familiar with compojure have any idea what's happening here? http://getclojure.org/

16:54 something with the path is f-ed up :\

16:55 * somnium is just relieved that he can blame leiningen for this one :P

16:56 jeffthink: somnium: haha...am really excited to use your lib...thanks for all the help

16:56 somnium: jeffthink: cheers

16:58 jeffthink: if I figure out what the leiningen issue is, will make sure to post here/github...though is definitely possible that it's user error...anyhow, thanks again...cheers

16:59 arohner: defn: it appears you're running apache + (jetty?). My guess is your jetty server isn't up / isn't where apache thinks it should be

16:59 make sure the jetty server is up, then look at your apache reverse proxy config

17:01 defn: arohner: as far as i can tell i have it set up correctly

17:01 arj_: anyone know why I get connection refused on reconnecting to repl after I close my Emacs and start it up again?

17:01 defn: my jetty server is on 8080, and mod_proxy is setup with proxypass and reverseproxypass

17:02 i have documentroot set to my public/ dir, which is not where my jetty jar is

17:03 what is the document root for a directory structure that looks like /project-root/src/project-name/(source.clj|public/css/my.css)

17:08 weird. *public-dir* when def'd as the exact same string "/my/path/etc/", behave differently

17:08 nowhere_man: Hi all

17:08 i'm setting up Clojure with my SLIME

17:09 the-kenny: nowhere_man: great! :)

17:10 nowhere_man: I had the following error: http://paste.lisp.org/+1ZTJ

17:11 I'm interested in STM and I like discovering ohter Lisps than my primary one (currently CL)

17:12 and I'm teaching Java to a friend that I'd like to eventually introduce to Lisp, having Clojure would help

17:15 the-kenny: nowhere_man: Are you using slime from cvs?

17:16 nowhere_man: the Debian package

17:17 should be the CVS from 8 sep 2009

17:17 the-kenny: nowhere_man: mh.. I know about problems with recent cvs checkouts, but 8. Sep 2009 isn't very recent. The version in slime is from october 2009

17:18 nowhere_man: do you have any idea what this error could mean?

17:18 the-kenny: nowhere_man: hm.. is the swank-instance in clojure running? Correct port etc.?

17:19 nowhere_man: I have that in Clojure's REPL:

17:19 user=> user=> Connection opened on local port 40315

17:20 #<ServerSocket ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=40315]>

17:22 hiredman: what OS?

17:22 I think bsd's and macosx can have issues with ipv6 vs ipv4

17:22 nowhere_man: Debian

17:22 the-kenny: hiredman: He mentioned a debian package of slime. Maybe debian? :)

17:22 hiredman: right right

17:22 the-kenny: Could the package be the problem?

17:23 hiredman: hey! maybe he is using a bsd kernel with debian userland!

17:23 the-kenny: heh

17:23 nowhere_man: Maybe give the slime in elpa a try?

17:24 nowhere_man: If you're using a common lisp with it, you have to work a bit on the backend for the common lisp though..

17:24 ordnungswidrig: slime on debian worked for me only with the elpa one or the one from github.

17:24 nowhere_man: slime in elpa ?

17:24 ordnungswidrig: slime from debian did not work with clojure-swank for me

17:25 the-kenny: nowhere_man: elpa is a package manager for emacs.

17:25 A nice one :)

17:25 ordnungswidrig: But I used lein swank and mvn clojure:swank to start the swank.

17:25 defn: finally: http://getclojure.org/

17:25 still needs a lot of work, and im not entirely sure why that sidebar is unsorted now -- wasnt before

17:26 knuckolls: on osx my install procedure was install emacs 23, install elpa, M-x package-list-packages, install swank-clojure, restart, M-x slime

17:26 from that point it asked to install clojure

17:26 and i let it

17:26 defn: dont forget paredit-mode

17:27 ordnungswidrig: gah, aquamacs hickup.

17:27 froze -> killed.

17:27 the-kenny: ordnungswidrig: heh.. I've switched to emacs23 in terminal.app some days ago :)

17:28 ordnungswidrig: the-kenny: hm, I could ssh to my debian box and attach to a screen running emacs23 :-)

17:29 the-kenny: over all I like aquamacs.

17:29 I asked early today but got no answer: is there already a lib to generate css from clojure?

17:30 ohpauleez: ordnungswidrig: you might be able to tweak enlive to do it

17:31 defn: how could passing a *var* that's a string versus a "string" cause a hiccup in clojure?

17:31 is that possible?

17:32 ohpauleez: defn, any weird binding form issues come in to play?

17:32 defn: ohpauleez: let me look at the code

17:32 http://gist.github.com/270752

17:32 ohpauleez: thanks, let me take a look

17:33 the-kenny: ordnungswidrig: I had many small things which were annoying... blocking while downloading the package-list, bad copy&paste, slow, gigantic size

17:33 LauJensen: ordnungs: I think Compojure has some helper func for generating css

17:34 defn: ohpauleez: im confused about the root

17:34 whats going on there?

17:34 ordnungswidrig: the-kenny: I switched to a mac just 3 weeks ago so to annoyance of a different keyboard layout is still greater than the aquamacs glitches :-)

17:35 hiredman: defn: convetion for earmuffs is that they mean a *var* is to be thread locally bound, and if you are binding a var thread locally, it is possible that the code is being excuted on another thread and does not see the binding

17:36 defn: hiredman: ah!

17:36 the-kenny: ordnungswidrig: Ah okay, that's more important ;)

17:36 ordnungswidrig: LauJensen: afaik compojure supports generating html in a nice way (and add style and id attributes nicely)

17:37 somnium: regarding css, its a bit aggravating that the reader chokes on %

17:37 LauJensen: Thats also true :)

17:37 somnium: ,:50%

17:37 clojurebot: :50

17:37 somnium: hmm, I get an exception

17:37 ,(keyword "50%")

17:37 clojurebot: :50%

17:37 durka42: => :50%

17:37 :50

17:37 java.lang.Exception: Unable to resolve symbol: % in this context (NO_SOURCE_FILE:0)

17:38 hiredman: ,:%

17:38 defn: hiredman: that wasnt it either

17:38 clojurebot: Invalid token: :

17:38 hiredman: durka42: most of the css wrapping stuff I have seen takes strings or keywords

17:39 defn: http://gist.github.com/270752 -- do you see anything in there that would make it possible for *var* versus "/what/var/represents/"

17:39 somnium: something like compass would be wonderful

17:39 defn: err make it possible for a *var* to not succeed, where a "/path/" does?

17:41 ordnungswidrig: somnium: yes, compass, like that. but why do you want to encode 50% a keyword? Can't you simple use a string literal?

17:42 ohpauleez: defn: what happens when you pass the var in?

17:42 defn: ohpauleez: the path is wrong -- it doesnt know where my public/css/ dir is

17:42 hiredman: he doesn't pass the var in

17:42 unless you use #'foo , you don't pass "vars"

17:42 ohpauleez: right right

17:43 defn: so anyway -- plain and simple, the path is just wrong and it doesn't know where my CSS files are

17:43 the *blah* breaks, BLAH breaks, but the equal string "/a/b/c/" works fine

17:44 ohpauleez: have you tried passing it with a root so it could make an absolute path?

17:44 defn: trying that now ohpauleez

17:44 * hiredman calls operator error

17:44 defn: hiredman: your confidence in me is always reassuring

17:44 ohpauleez: yeah, there's nothing there that looks like it would get screwy

17:45 somnium: ordnungswidrig: of course, but would your first choice be strings or keywords?

17:45 hiredman: defn: do you ever check the equality of string and the string literal

17:46 defn: is that a joke?

17:46 hiredman: ,(let [x "/public/"] (assert (= x "public/")))

17:46 clojurebot: java.lang.Exception: Assert failed: (= x "public/")

17:46 defn: 'course i do

17:46 hiredman: why is it a joke?

17:46 ohpauleez: defn: and when you do that, you might as well fire up the debugger

17:46 ambient: dang, i wish i'd discovered this page earlier: http://steve.yegge.googlepages.com/effective-emacs

17:53 Licenser: is there something like the swank clojure stuff for any other editor then emacs? Please?

17:53 ambient: both eclipes and netbeans plugins have repl if that's what you mean

17:53 hiredman: vimclojure has a repl

17:53 there is also slime.vim

17:54 defn: ,(def *public-dir* "/Users/abc/def/ghi/jkl/mno")

17:54 clojurebot: DENIED

17:54 * Licenser is totally fed up with emacs - it works great unless you want to do something *sigh*

17:54 Licenser: Hence and the comunity is greatyl helpful - buy a new keyboard with a different layout is not a way to fix key assignment problems

17:55 hiredman: defn: have you put an a println in the function so you can monitor the actual input it receives?

17:55 Licenser: hah!

17:55 Licenser: no seriousely that was the answer I got when asking how to fix it

17:55 arohner: Licenser: you can remap all of the control keys

17:55 hiredman: I was talking with hp's support on behalf of someone else about fixing a built in webcam, they told me to reformat the laptop and run a system restore

17:56 arohner: and you can pick different language keyboard layouts

17:56 Licenser: arohner: uea works great on aquaemacs but that is 'not supported' and does not do .emacs.d directories

17:57 * hiredman recognizes that "not supported" line

17:57 Licenser: So either I

17:57 hiredman: thats irc for you

17:57 Licenser: well I

17:57 i've had a few good experiences here is nice, jruby is nice, solaris is nice

17:57 arohner: defn: I use compojure's (serve-file...) I pass it the files root explicitly, relative to the the directory where I started java

17:58 Licenser: what is uea?

17:59 Licenser: arohner: I've no idea I think it was yea but I'm not sure :/

17:59 arohner: cua? the thing that makes emacs act more "normal"?

18:00 defn: arohner: like if project root is: /home/myuser/project, you pass it /public/html/

18:00 arohner: with respect to C-c C-v?

18:00 defn: I pass it "./public/html"

18:00 defn: hm, okay thanks

18:01 arohner: underneath, it does a (File. root path), so it expects whatever java does with new File(root, path)

18:01 aha, it's relative to (System/getProperty "user.dir")

18:02 but (serve-file "/home/myuser/project/public/html" "foo.html") should work

18:04 defn: see if you can make this work:

18:04 (.exists (java.io.File. "/home/myuser/project/public/html" "foo.html"))

18:04 if that doesn't work, compojure can't help you

18:06 somnium: is there an M-x butterfly to wrap a region in quotation marks and escape everything inside?

18:09 technomancy: somnium: " will do that if you have paredit on.

18:10 dysinger: hiredman: I just got your email - sorry I was out of the country (guatemala) for the last 2 weeks for festivus

18:11 somnium: ... not when it runs into a paren

18:11 dysinger: lets chat friday

18:16 job: So I'm having trouble coming up with an idiomatic way to go from seqs to hashmaps.

18:16 Anyone know of a way?

18:17 ordnungswidrig: job: seq with kv pairs?

18:17 job: right. ([k v] [k v] ... )

18:17 Knekk: dysinger: how did you like GUatemala?

18:18 Chousuke: ,(into {} '([1 2] [3 4])); job

18:18 clojurebot: {1 2, 3 4}

18:18 job: oh, cute.

18:18 didn't know about that; thanks much!

18:20 ordnungswidrig: ,(apply hash-map [1 2 3 4])

18:20 clojurebot: {1 2, 3 4}

18:21 job: That's not quite what I meant, but Chousuke got it.

18:24 So how about filtering hash-maps idiomatically? (into {} (filter #'fn map))?

18:26 somnium: ,(filter (fn [[x y]] (even? y)) (zipmap (range 10) (range 1 11)))

18:26 clojurebot: ([1 2] [3 4] [5 6] [7 8] [9 10])

18:27 Chousuke: job: you don't need the #' :)

18:28 job: though amusingly enough, it does work

18:28 (there's just an extra indirection)

18:28 job: Chousuke: gotcha.

18:29 Chousuke: coming from CL?

18:29 job: yep; though my knowledge of CL is pretty limited

18:30 dysinger: Knekk: loved it

18:30 Chousuke: in Clojure #'foo is shorthand for (var foo)

18:30 dysinger: fun times - they love fireworks on holiday

18:30 Knekk: dysinger: sure do. The metralletas are the best.. string 6-7 together...

18:31 dysinger: did you make it to Antigua and Lake Atitlan?

18:31 job: ah, interesting; what purpose does it serve?

18:31 Chousuke: so instead of the function value of foo you get the var that holds the value

18:31 but it works as a function because vars redirect function calls to their values :P

18:32 vars are the things that hold globally defined values in Clojure (I guess they would be symbols in CL)

18:32 symbols in Clojure are only names, not actual containers

18:32 job: right

18:32 dysinger: Knekk: I was in Antigua the whole holiday - didn't see much else ):

18:33 Chousuke: when there is a reference to a defined var in source code, the symbol is resolved to a var and the var is dereferenced, yielding the value.

18:33 Knekk: dysinger: where did you stay?

18:35 Chousuke: ,(vector '+, +, #'+, (deref (resolve '+))); hm

18:35 clojurebot: [+ #<core$_PLUS___4745 clojure.core$_PLUS___4745@11a772d> #'clojure.core/+ #<core$_PLUS___4745 clojure.core$_PLUS___4745@11a772d>]

18:37 job: ha!

18:37 Chousuke: the print syntax for functions is rather ugly :P

18:41 Knekk: ah, that's convenient. My grandmother used to take guests, but she stopped a couple of years ago

18:41 err

18:41 #wrong

18:58 jobeirne: So I've got a question of style on my hands

18:59 I'm coding a robot driver in Clojure; this entails defining one robot struct and then a whole bunch of functions which operate on this robot struct.

19:00 My question is: do all of these functions take in an obligatory "robot" parameter, or do I just presume in the definition of each function that we're operating on a global "robot" var?

19:00 Chousuke: I think either way is fine.

19:00 if there only ever is one robot

19:01 jobeirne: I don't think there'd ever be more than one, but you never know.

19:01 Chousuke: I mean, if there is one robot, having a global var is fine.

19:01 and it might work for more than one through dynamic binding, but you might run into trouble.

19:03 jobeirne: True.

19:03 Both ways feel kind of ugly; I guess I'm just used to OOP.

19:04 ordnungswidrig: I'd prefere the function to take a robot parameter and some with-robot bindings and macros. so you can always go to the detail level pass a robot instance if desired.

19:04 defn: jobeirne: if you're clever you can still do a lot of OO-esque stuff

19:04 the-kenny: I'd prefer the robot-parameter too.

19:04 defn: i mean, you can call Java, for one

19:05 ordnungswidrig: s/pass/and &/

19:05 jobeirne: defn: yeah, true, but I'd like to stick to pure Clojure as much as possible

19:06 defn: jobeirne: sure, i did that for awhile, but in the end, pure clojure vs java clojure == clojure

19:06 if you get good with java interop that's a good thing

19:06 not something to avoid, fwiw

19:06 hiredman: any ideas how I would snag the appegine sdk from google's maven repo with lein?

19:07 jobeirne: defn: you know, what you're saying makes sense. I guess I chucked the baby out with the bathwater.

19:08 For now I'll go with ordnungswidrig/the-kenny, but long-term I'll look at some java interop.

19:09 defn: So you don't think defining a class through Clojure is too big a hassle?

19:10 the-kenny: jobeirne: No, it's damn-easy

19:10 jobeirne: http://clojure.org/compilation

19:10 hiredman: what format does lien's :repositories expect?

19:10 Chousuke: I'm still not sure if you need a class though

19:11 hiredman: I tried to give it a vector of urls, but it does not like that

19:11 technomancy: hiredman: I think it's a map of repository names to URLs; check leiningen/pom.clj if that doesn't work.

19:11 jobeirne: the-kenny: interesting. I'll give it a close look.

19:12 ordnungswidrig: bedtime for me. cu tomorrow.

19:12 the-kenny: jobeirne: But you generally only need classes if you want to use them in some java code. If you want to write everything in clojure, you don't really need a class.

19:12 hm.. same for me. School starts tomorrow here.

19:12 Good nigh

19:12 t

19:12 jobeirne: 'night; thanks for the help.

19:12 where do you go?

19:19 hiredman: gar

19:19 1 required artifact is missing. for artifact: org.apache.maven:super-pom:jar:2.0

19:20 http://gist.github.com/250055 <-- haha first google hit

19:21 the first three or four google hits are all lein

19:23 defn: yeah it's a nice name

19:23 hiredman: I didn't google the name

19:23 I googled the error

19:26 well this sucks

19:27 technomancy: hiredman: super-pom is just maven API speak for "current project"

19:27 it's weird, but I'm not sure if that's something lein can control

19:29 hiredman: http://gist.github.com/270842 is my project file

19:31 ah

19:31 I see, so I need to look at whatever was before super pom

19:32 technomancy: yup

19:36 erikcw: I've got slime running in aquamacs. I'm able to work with clojure! However, I'm having a hell of a time trying to figure out how to add jars to my classpath. I'm able to add them to my command line REPL (via my ~/.clojure file) but I can't for the life of me figure out how to get them to load in emacs. (I'm trying to get enlive.jar working in particular)

19:37 technomancy: erikcw: the readme to swank-clojure is pretty descriptive

19:38 erikcw: member:technomancy: is this the readme you are referring to? http://github.com/jochu/swank-clojure/blob/master/README

19:39 * hiredman dies

19:39 technomancy: no, try http://github.com/technomancy/swank-clojure/blob/master/README

19:39 that version is old

19:39 erikcw: 404 error

19:39 hiredman: now compojure is giving me the same error because of the alpha->master rename that happened

19:39 technomancy: erikcw: here it is: http://github.com/technomancy/swank-clojure

19:39 defn: hiredman: use liebke's

19:39 or dvg's

19:40 http://clojars.org/org.clojars.dvgb/compojure

19:40 that works i believe

19:40 if it doesn't: [org.clojars.ato/compojure "0.3.1"]

19:40 oops wrong one

19:41 [org.clojars.liebke/compojure "0.3.1-master"]]

19:41 hiredman: I wonder why liebke's didn't show up in the search

19:41 defn: search is borked

19:41 same thing happened to me with clojureql

19:42 you can get to it by going to clojars.org/clojureql

19:42 but not via search

19:43 cemerick: I wonder if we can get rhickey to make a benevolent decree w.r.t. maven-based builds so as to simplify the build/distribution landscape. ;-)

19:44 defn: the build landscape is varied, but it'll clean up by itself

19:44 let the games begin

19:44 cemerick: I agree, but anything that can prod it along is a good thing, IMO.

19:44 It's not like there's a solution space to be explored.

19:46 liebke: cemerick: what's the decree you'd have Rich make?

19:47 technomancy: rich has more or less indicated that's a problem space he's not interested in IIRC

19:47 cemerick: yeah, I know, that's why I used the ;-)

19:48 liebke: "be a good neighbor, use maven"?

19:48 liebke: ah, good luck with that :-)

19:48 cemerick: I know. :-)

19:49 I've moved from critic to skeptic to convert to zealot in a striking short time.

19:50 liebke: haha, it's been great for Incanter, but it has required a lot of expertise from others

19:56 hiredman: liebke: did you see my incanter screenshot?

19:57 http://www.thelastcitadel.com/images/Screenshot-Repl.png

19:58 I should have hovered the mouse over one of the bars so you could see the tooltips

19:58 liebke: hiredman: I did, very cool!

20:00 hiredman: what are your plans for the repl?

20:01 hiredman: I don't know

20:01 it was a whim

20:02 liebke: I'd really like to have a simple gui repl to include with the Incanter

20:02 KirinDave: I'm having problems writing a mcro

20:02 err, macro

20:02 http://gist.github.com/270865

20:03 I want to write addition compojure shorthands in defroutes

20:03 But request, which is filled in inside the macro, is coming out unbound.

20:03 hiredman: liebke: the architecture may be a little unusual, and, for example, I used $ too, but that is easy enough to change

20:04 KirinDave: When I macroexpand something like (GET "/" request) I end up seeing something like "request__857__auto__"

20:04 How do I bind to that in my macro?

20:05 hiredman: what do you mean "bind to that"

20:05 KirinDave: hiredman: If I try and use this macro as written, it fails

20:06 hiredman: with what exception

20:06 KirinDave: scorekeeper.web/request

20:06 No such var: scorekeeper.web/request

20:07 hiredman: right

20:07 you are doing this with compojure right?

20:07 KirinDave: Yes.

20:07 So, how do I get my request to match up with theirs?

20:07 hiredman: request is magic, and only exists in the defroutes macro

20:07 KirinDave: Sure.

20:08 http://idisk.me.com/dfayram/Public/Pictures/Skitch/web.clj-20100106-171027.jpg

20:08 Is exactly what I'm trying, in scorekeeper.web

20:08 hiredman: your best bet is to expand into something like (fn [~'request] code-here)

20:08 KirinDave: So I have to know the underlying structure of the macro?

20:09 hiredman: *shrug*

20:09 I don't know the underlying structure of the macro

20:09 KirinDave: And what does ~'require do ?

20:09 hiredman: it lets you shadow a name

20:09 bad bad

20:09 KirinDave: Um… how would that solve my problem?

20:09 hiredman: compojure's defroutes can take functions

20:10 KirinDave: Okay… but...

20:10 hiredman: the argument to those functions when they are called is the request map

20:10 KirinDave: It seems weird that clojure is freaking out at this macro definition.

20:10 Since it's valid when it's actually instantiated.

20:11 I draw the conclusion that this is a limitation of clojure's macro system.

20:11 hiredman: I don't care

20:12 KirinDave: hiredman: … Then why did you start talking to me to begin with?

20:12 hiredman: I don't care about what conclusions you draw

20:12 KirinDave: You are like night and day dude.

20:12 hiredman: I am, trying to help you get from point a (not working) to point b (working)

20:12 KirinDave: Sometimes helpful and cool. Sometimes not.

20:13 Thank you for the fn tip

20:13 hiredman: defrouts could literally being doing *anything* under the covers

20:13 KirinDave: hiredman: I want to understand clojure macros better, that's why I'm doing it this way.

20:13 it working is entirely secondary.

20:13 I've only got 2 resource types.

20:14 So "working" is copy-paste-done.

20:15 hiredman: if you use some rough idea of what defroutes does (which may or may not jive with what it does) and write your own macro that could do anything, it may or may not work, if you write a macro that uses a mechanism you know defroutes can handle (single arg function) then it will work

20:15 cemerick: heh, I just sent a really bone-headed msg to the compojure mailing list :-/

20:16 hiredman: the other option is ripping open defroutes, and digging through macro expansions and gensyms

20:16 KirinDave: Well this macro would work in common lisp. I know because I pulled out SBCL and did something very much like it just to make sure I remembered how it worked over in a more familiar land.

20:16 Because "request" would be bound where compiled.

20:16 And it'd be compiled in the defroutes form, which would have already been expanded.

20:16 arohner: KirinDave: your original macro, using "request#" uses gen-sym to make a new variable with the name request__1234__, where 1234 is an arbitrary number

20:17 that's the default, because it's safer

20:17 KirinDave: arbscht: I don't use request#.

20:17 arohner: if you really, really want to stomp on the variable, "request", you use ~'request, which says "no really, use request, I know what I'm doing"

20:18 hiredman: KirinDave: that is make assumptions about the scope of the name "request" and how it is bound

20:18 making

20:18 arohner: oh, then defroutes is

20:18 hiredman: which you cannot really know about unless you open up defroutes, which I really don't want to do, so (fn [~'request] ~@body)

20:18 KirinDave: arohner: Almost certainly, as it has that __auto__

20:19 arohner: a nicer way to do this would be to make a middleware function for the routes you want to treat this way

20:19 oh, I see what you're trying to do

20:20 KirinDave: arohner: Yes. And ~'request does it.

20:20 That's interesting

20:20 arohner: you can pass a regex to the route

20:20 KirinDave: So clojure macros are semi-hygenic by default.

20:20 As in it tries to bind every expanded symbol as tightly as possible, like at definition time.

20:20 arohner: KirinDave: yes. I would call it mostly-hygenic

20:20 KirinDave: It's done at the time and in the place where it's defined then?

20:21 arohner: It does it at macro expansion time, I believe

20:21 technomancy: KirinDave: actually it's the backquote that expands the symbols, it's just that most macros use backquote</nitpick>

20:22 KirinDave: That's a very interesting policy

20:22 So conceptually ~' is a trapdoor that says "No really really really defer this symbol binding."

20:23 Thanks arohner.

20:23 arohner: right

20:23 np

20:23 FYI, I solved a similar problem by doing

20:24 (routes* (GET my-regex ...))

20:24 using () in your regex will show up in the route params

20:24 (:route-params request) will contain the back references

20:25 KirinDave: Right, this form just generalizes that

20:25 For some specific resources.

20:25 So that they're pulled by extension.

20:26 thanks!

20:36 hiredman: I'm trying to write a lein plugin, and lein help shows "appengine-setup" but lein appengine-setup says appengine-setup is not a task

20:38 oh, hoho

20:38 clojurebot: hiredman

20:38 clojurebot: hiredman is lazy

20:38 hiredman: close

20:38 clojurebot: hiredman

20:38 clojurebot: hiredman is an evil genius.

20:38 hiredman: not quiet

20:38 clojurebot: hiredman

20:38 clojurebot: hiredman <3 XeLaTeX

20:38 hiredman: true

20:38 clojurebot: hiredman

20:38 clojurebot: hiredman is lazy

20:38 hiredman: I guess that will have to do

20:40 technomancy: hiredman: is there a leiningen.appengine-setup/appengine-setup fn defined?

20:41 help only checks the namespaces, it doesn't make sure there's a corresponding function

20:41 hiredman: my fault

20:42 I was editing a file leiningen.appengine_setup.clj instead of leiningen/appengine_setup.clj

20:59 q1: clojurebot: clojurebot

20:59 clojurebot: clojurebot will become skynet

20:59 q1: :(

21:12 scottj_: Did there used to be a bunch of p functions like preduce and pfilter that have since been removed?

21:16 JonSmith: i think so

21:40 mebaran151: there use to be some forkjoin stuff that's getting replaced

21:40 all that's left is pmap I think

22:02 polypus: just installed 1.1.0. do i need to require deftype, i'm getting an unresolved symbol

22:03 ~ping

22:03 clojurebot: PONG!

22:04 JonSmith: where do you go if you found a bug in a contrib module?

22:07 polypus: huh, i just read through the changes file for 1.1 and it doesn't mention deftype. didn't it make it into this release?

22:20 running master snapshot from here: http://build.clojure.org/job/clojure/lastSuccessfulBuild/artifact/clojure.jar and deftype is still not defined. i must be missing something. anybody?

22:25 chouser: deftype is still only in the 'new' branch

22:26 polypus: ty chouser. just got that working 3 seconds ago

22:26 chouser: heh sorry

22:26 polypus: no worries. thx

22:26 durka421: (doc if-let)

22:26 clojurebot: "([bindings then] [bindings then else & oldform]); bindings => binding-form test If test is true, evaluates then with binding-form bound to the value of test, if not, yields else"

22:26 chouser: may 1.2 come quickly...

22:26 durka421: ^ what is oldform?

22:27 polypus: praise the lisp

22:27 durka42: in the source there's an assert-args that says oldform must be nil. is it something deprecated?

22:27 chouser: durka42: yes, deprecated

22:28 durka42: if-let used to be (if-let x (expr) then else)

22:28 durka42: it would give a really cryptic error, though

22:28 oh, i see

22:29 chouser: ,(if-let x 1 :then :else)

22:29 clojurebot: java.lang.IllegalArgumentException: if-let requires a vector for its binding

22:29 chouser: nice pretty error, actually.

22:29 it'd probably be safe to get rid of those messages now.

22:34 polypus: in some of the scattered deftype example code that shows up in google the type names are sometimes capitalized. (deftype Foo ...). i suppose it's too eraly to ask if this should be considered idiomatic?

22:35 early*

22:35 chouser: I think type and protocol names will be capitalized like java class and interface names are.

22:37 polypus: k, ty

22:54 (isa? (type 4) Integer) -> true

22:54 (deftype Foo []) (def foo (Foo))

22:54 (isa? (type foo) Foo) -> false

22:55 would be nice if you didn't need to go ::Foo

22:57 chouser: I think that's required in order to allow you to redefine Foo dynamically.

22:58 polypus: ahh cuz it's an anon class?

23:01 although isa? could be redifined to treat functions differently, and type constructors could have metadata to make that work.

23:54 hiredman: http://code.google.com/p/maven-gae-plugin/issues/detail?id=26 <-- gah

23:55 so you can't get the appegine sdk via maven, how lame

Logging service provided by n01se.net