#clojure log - Dec 13 2010

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

0:29 ossareh: zach kills me with how good aleph is!

0:30 Lajla: Raynes, I think you should call her sexbot

0:45 ossareh: Lajla: false advertising?

0:46 Lajla: ossareh, I worship Your Shadow

0:46 ossareh: hobbies yield better results.

2:10 zmyrgel: hi, if I have (:use (foo bar)) in my file's ns macro, shouldn't I be able to refer constants defined in foo.bar?

2:10 now I just get Unable to resolve symbol error

3:41 amalloy: zmyrgel: yes, you should be able to refer to def'ed variables. though (:use foo.bar) is a bit simpler if you're not doing other foo.baz imports

3:52 _na_ka_na_: ,(compare '(1 2 3) '(1 2 3))

3:53 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.lang.Comparable

3:53 _na_ka_na_: ,(compare (vec '(1 2 3)) (vec '(1 2 3)))

3:53 clojurebot: 0

3:53 _na_ka_na_: why can't I compare PersistentLists ^^

3:54 amalloy: _na_ka_na_: good question

3:55 &(map (comp supers class) [() []])

3:55 sexpbot: ⟹ (#{clojure.lang.Sequential clojure.lang.IPersistentCollection java.io.Serializable java.lang.Object clojure.lang.Counted java.lang.Iterable clojure.lang.IPersistentStack clojure.lang.Obj clojure.lang.IObj java.util.Collection clojure.lang.IPersistentList java.util.Li... http://gist.github.com/738808

3:57 amalloy: _na_ka_na_: i mean, the answer is what you'd expect: () doesn't implement Comparable. but why is that? i don't know any better than you do

3:57 &(apply compare (map seq [[1 2]

3:57 sexpbot: java.lang.Exception: EOF while reading

3:57 amalloy: &(apply compare (map seq [[1 2] '(1 2)]))

3:57 sexpbot: java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to java.lang.Comparable

4:05 kryft: Oo, there's a clojure course coming up at Helsinki University.

4:06 opqdonut: yes, I'm teaching :)

4:06 Licenser: morning

4:09 kryft: opqdonut: Sattuuko se olemaan jatko-opintokelpoinen? :P

4:09 opqdonut: kryft: juttelen tänään opintoesimiehen kanssa, varmaan onnistuu

4:09 kryft: opqdonut: Also, if I want to attend the course, is it a problem that I'll be in London until the end of April?-)

4:10 opqdonut: :D I'm sure we'll figure something out

4:10 if you want the credit

4:11 the course is going to be workshop-like, students can work on their own projects or given exercises

4:11 kryft: Great.

4:11 opqdonut: that'll leave us with more time to focus on those who haven't done lisps before

4:12 but there'll be mini-lectures on advanced stuff like performance tuning

4:12 I'm hoping 1.3 will come out before the course starts... :)

4:13 kryft: I haven't done lisps before, although I do feel I've grasped the basics of the functional programming paradigm.

4:14 opqdonut: the material will be on the web

4:15 as I said, we'll figure something out. you can email me when the course starts or something

4:15 kryft: Great. :) When does it start?

4:16 opqdonut: well that's what I'm going to sort out today :D

4:16 the course will probably be during period III

4:16 so about 17.01.-06.03.

4:17 but we might do something like have teaching in pIII but let people hand in stuff during pIV too

4:17 kryft: opqdonut: Oh, and the credits would be nice because then I could study at work with a clean conscience. ;)

4:18 opqdonut: yes of course. if you participate you will get the credits. and I'm quite open to "vaihtoehtoiset suoritusmuodot"

4:20 kryft: opqdonut: I have some work-related ideas for small projects that I was planning to do anyway after reading The Joy of Clojure (eg. implementing a dimensionality reduction algorithm that I've previously written in C++).

4:20 opqdonut: with parallelism?-)

4:20 kryft: Yes. :)

4:20 opqdonut: soudns good

4:20 but I gtg ->

4:21 (you might want to join the lambda mailing list if you're into stuff like this, see http://lambda.fi)

8:33 jcromartie: oi vey, so let me tell you what's a bad idea

8:34 approaching data obfuscation by selecting every distinct value in each column of each table, transforming it, and updating that distinct value with the new value

8:34 6 hours for one column in one table

8:39 kzar: I have a ref of a vector of stuff, I want to filter the vector taking what I need and at the same time removing it from the original vector. I can't figure out how to update the vector in such a way that I get the removed values returned without duplicating the work

8:40 (So I get a vector of the stuff I've filtered for and the original vector that's referenced is updated so that only things that didn't match the filter are left.)

8:41 chouser: kzar: I think you might need loop/recur for that.

8:41 kzar: chouser: Cool OK I rekon I can figure it out in that case :D

8:42 chouser: If there's an existing HOF that'll do that, it's not coming to mind at the moment.

8:44 kzar: HOF

8:45 chouser: High Order Function

8:45 kzar: heh

8:45 chouser: oh

8:45 kzar: Lowest order joke, sorry heh

8:51 Licenser: cookies

8:52 islon: is this the right way to define a private var? (def ^{:private true} background Color/WHITE)

8:52 ?

8:53 stuartsierra: yes

8:53 Licenser: what is the reason for not having def-?

8:53 I mean there is defn- too

8:54 islon: thats exactly what I was thinking

8:55 Licenser: I wondered that a time ago, then just forgot it, but now that you mention it I wonder why tzhere is no def- I am sure there is a very reasonable explenation since I doubt Rick or any other of the core defs for that matter would just forget something like that

8:55 ,,,,,, <- put them where apropriate

8:55 clojurebot: java.lang.Exception: Unable to resolve symbol: <- in this context

8:56 raek: get assoc dissoc ______

8:56 Licenser: update-in?

8:57 raek: get-in assoc-in _________ update-in

8:57 Licenser: oh cheater!

8:57 s450r1: kzar: doesn't split-with get you most of the way there?

8:57 chouser: update-in fills all three slots

8:57 Licenser: see that is why it is a good answer :P

8:57 so I'm not even sure what the question was

8:58 kzar: s450r1: Oh yea, I'm just writing it now but I didn't think of using split-with good idea

8:58 s450r1: This is good practice for me :D

8:59 chouser: I don't think split-with returns what he wants, and runs pred twice for every input element until it returns false

8:59 fliebel: kzar: (juxt filter remove)

8:59 chouser: fliebel: I think that returns what he wants, but runs pred twice for every input element. :-)

9:00 Licenser: I think to think I found a bug ccw

9:00 fliebel: chouser: true

9:00 kzar: it's elegant though

9:00 tonyl: morning

9:00 islon: does it work? (defmacro def- [name value]

9:00 `(def ^{:private true} ~name ~value))

9:04 kzar: although doing it that way with juxt makes us calculate the new value outside of updating the ref, so we can't use alter

9:04 s450r1: chouser: thanks for the correction

9:04 chouser: ,(map #(map second %) ((juxt filter remove) first (for [i (range 10)] [(odd? i) i])))

9:04 clojurebot: ((1 3 5 7 9) (0 2 4 6 8))

9:06 fliebel: kzar: Using alter wont work anyway, because you can't return the values you want, set, and still return values somewhere else.

9:07 kzar: I havn;t worked with refs much, but is'nt the whole point you start a stransaction and do whatever you like inside it?

9:07 bartj: I have the following scenario:

9:07 defined a buffered writer, some print statements, defined method

9:07 chouser: ,(loop [[x & xs :as c] (range 10), f [], r []] (if c (if (odd? x) (recur xs (conj f x) r) (recur xs f (conj r x))) [f r]))

9:07 clojurebot: [[1 3 5 7 9] [0 2 4 6 8]]

9:07 bartj: method has a couple of print statments but this time with *out* being bound to a file

9:08 but despite the call to the method being *after* , it gets printed first!

9:09 is there some precedence w.r.t *out* being given precedence over BufferedWriters ?

9:10 fliebel: bartj: have you tried (flush)?

9:10 (wild guess)

9:12 raek: bartj: are you sure this is not caused by that you return a lazy seq out from the binding form?

9:13 (binding [*out* ...something...] ...some-lazy-seq...) --> (binding [*out* ...something...] (doall ...some-lazy-seq...))

9:15 bartj: raek, I seem to return a PersistentList

9:15 fliebel: kzar: ##((juxt #(apply concat (take-nth 2 %)) #(apply concat (take-nth 2 (next %)))) (partition-by odd? [1 2 2 3 4 5 5 7 8 9]))

9:15 sexpbot: ⟹ [(1 3 5 5 7 9) (2 2 4 8)]

9:17 raek: laziness plus binding is often a source of problems...

9:17 kzar: fliebel: to be honest some of those ideas are going over my head

9:18 fliebel: kzar: It's pure evil. It least make the apply a reduce.

9:18 bartj: raek, lists are not lazy, no?

9:19 kzar: fliebel: heh

9:19 raek: PersistentLists (from 'list' or conjing onto () or nil), no

9:19 fliebel: kzar: look up partition-by, and you'll understand… maybe.

9:20 kzar: fliebel: heh OK, gimme a min I'm going to try my idea for solving it

9:20 fliebel: kzar: sure :)

9:22 Will sexpbot on Twitter only respond to replies, or also to mentions?

9:23 ivey: sexpbot is on Twitter now?

9:23 Raynes: using my code, or has it changed? I haven't had time to look at it in a while

9:28 fliebel: Raynes: Seems sexpbot is down on Twitter?

9:38 kotarak: Single pass separate-by. Can this be de-uglified? http://paste.pocoo.org/show/304306

9:44 karmazilla: kotarak: what's it do?

9:49 kotarak: karmazilla: it returns [(filter pred coll) (remove pred coll)] in one pass

9:50 karmazilla: hopefully as lazy as possible

9:51 karmazilla: kotarak: I guess somehow using reduce in there would make it less ugly

9:51 fliebel: kotarak: Did you see my 'solution'?

9:52 kotarak: fliebel: eh. No?

9:52 fliebel: karmazilla: I think so to… one min

9:52 * kotarak scrolling upwards

9:52 kotarak: fliebel: you mean juxt?

9:52 fliebel: &((juxt #(reduce concat (take-nth 2 %)) #(reduce concat (take-nth 2 (next %)))) (partition-by odd? [1 2 2 3 4 5 5 7 8 9]))

9:52 sexpbot: ⟹ [(1 3 5 5 7 9) (2 2 4 8)]

9:53 kotarak: fliebel: reduce smell like "non-lazy"

9:54 fliebel: kotarak: True

9:54 But how can you make something that returns a vector lazy?

9:54 kotarak: fliebel: the requirements are: as lazy as possible, only one pass of predicate check

9:55 fliebel: the contents are lazy

9:55 and thread-safe of course (re requirements)

9:55 fliebel: So you're doing a lazy asynchronous recur? :)

9:56 kotarak: fliebel: well, it's synchronous: when asked for it it happens on the calling thread.

9:57 fliebel: kotarak: But you add elements to both queues as much as needed for the one that is consumed, right?

9:57 kotarak: fliebel: yes. This is obviously necessary.

9:58 * fliebel reread kotarak's code

9:59 fliebel: It's an interesting problem for sure :)

10:00 kotarak: fliebel: and it is kind of tricky re threads. atoms don't work, refs don't work... I think one needs a locking here.

10:01 fliebel: kotarak: I'm not sure I understand.

10:01 karmazilla: to prevent two threads from calling pred on the same element, one needs mutual exclusion

10:01 kotarak: fliebel: transactions get merged with surrounding ones, so we kind use refs, because the our changes might get replayed if the surrounding ref retries.

10:01 kzar: Can you duplicate a mutable value to somewhere immutable so you know it's safe to use later?

10:02 kotarak: fliebel: atoms don't work, because we cannot handle things in one call.

10:02 fliebel: still some kind of sync is required. as karmazilla said: one might realise the true and the false seq in parallel.

10:03 karmazilla: the choices seem to boil down to eager, synchronized or thread-unsafe

10:03 fliebel: ouch… it's more complicated than I thought.

10:04 islon: how do i remove the reflection warning from (proxy-super paintComponent g)?

10:04 kotarak: hmmm the drawback of this solution is, that one seq can block the other if the items are ill-distributed in terms of satisfying the predicate... In particular on an infinite seq. *grmpf* Maybe two passes are still better?

10:05 fliebel: kotarak: simpler for sure...

10:05 kotarak: fliebel: nice golf anyway :)

10:05 fliebel: golf?

10:06 LauJensen: karmazilla: Hey - Coming this thursday for the Clojure meetup in Cph ?

10:06 kotarak: fliebel: code golf - some play to solve a fun problem

10:06 fliebel: ah

10:06 karmazilla: LauJensen: yes I am :)

10:06 LauJensen: karmazilla: Look forward to seeing you there :)

10:07 karmazilla: LauJensen: me too. I wanted to go last time, but other plans got in the way :-/

10:08 LauJensen: karmazilla: Last time we had some improv fun with Moustache and Enlive, next up is Cucumber I think

10:08 fliebel: kotarak: Must… Think… About… A… Better... Solution...

10:08 kotarak: fliebel: hehe :)

10:08 karmazilla: LauJensen: which I really look forward to. BDD is a pretty vague concept to me still

10:09 LauJensen: karmazilla: Fortunately Martin (mjul) seems to be somewhat of an authority on the issue

10:09 karmazilla: nice

10:09 kzar: (let [val (nth @some-ref 2)] ...somechanges... val) is screwing me because val changes as some-ref does, how do I get the value val in a safer way?

10:20 oh unless it's something to do with laziness

10:23 LauJensen: Has anybody made some Google Maps integration for Clojure?

10:24 fliebel: kotarak, kzar: https://gist.github.com/739089

10:26 kotarak: Am I right that this is lazy al the way through, and only evaluates pred once?

10:26 kotarak: kotarak: I think so.

10:28 fliebel: But the sequence must not include nils.

10:28 fliebel: the input sequence that is

10:29 fliebel: kotarak: True. But other than that, it seems to work like a charm.

10:30 kzar: fliebel kotarak: Here's my version http://paste.lisp.org/display/117638

10:30 It's aim is a bit different from yours, it's also slightly broken the results are wrong

10:32 fliebel: $sed -kzar s/it's/its/

10:32 sexpbot: <kzar> its aim is a bit different from yours, its also slightly broken the results are wrong

10:32 fliebel: hey, I din't gave you the g option, sexpbot!

10:33 kotarak: kzar: You cannot reliably deref an agent. (you can that is, but you cannot be sure to not miss something if you do it two times)

10:33 kzar: fliebel: Thanks I struggle with grammer / spelling

10:34 gtrak: but the second it's is right

10:34 fliebel: kzar: It's not important, I was just trying to figure out sexpbot.

10:34 kzar: heh well I care, I'm working on it

10:35 fliebel: gtrak: That is why I complained, I didn't add the g option at the end. Real sed would've only replaced the first one.

10:35 gtrak: ah

10:35 kzar: kotarak: Hmm balls so maybe my idea is pretty much broken

10:36 gtrak: do you guys generally prefer clojure for utility type stuff?

10:37 fliebel: gtrak: Meh, JVM, classpath, startuptime… I prefer Python for that kind of stuff.

10:38 gtrak: yea I like python too

10:41 karmazilla: fliebel: some Either type/api could make your version support nil values, I think

10:42 fliebel: karmazilla: I think so to...

10:44 kzar: fliebel kotarak: http://paste.lisp.org/display/117638#1 this one is working pretty well but you might hate it after all the clever solutions you found heh

10:45 kotarak: kzar: split-with is cheating: it's two pass ;-P

10:46 fliebel: karmazilla: I like my solution, so I'm not going to bother making it ugly with extra conditionals and checks.

10:46 kzar: I might make a three pass version just to annoy everyone

10:49 kotarak: fliebel: fixed for nils http://paste.pocoo.org/show/304345

10:49 fliebel: Although this really creates a lot of short-lived garbage objects... (<- premature optimiser in me...)

10:50 fliebel: kotarak: I think I prefer mine, as long as I don't need nil values :)

10:51 Raynes: fliebel: You still need to prefix with & to evaluate code on twitter.

10:52 fliebel: Raynes: Does ## work as well?

10:52 Raynes: Yes.

10:52 fliebel: And a mention rather than a reply?

10:53 Raynes: I didn't see an API function for replying.

10:53 I'll look later.

10:53 fliebel: Raynes: No, I think it's awesome to be able to do ##(prinltn "hi") and /cc @sexpbot

10:53 sexpbot: java.lang.Exception: Unable to resolve symbol: prinltn in this context

10:55 bartj: how can I ask clojure.java.io/writer to open a file in append mode?

10:56 :append true

10:58 kzar: fliebel kotarak: http://paste.lisp.org/display/117638#2 <- my one pass seperate by

10:59 karmazilla: looks eager

11:00 bartj: are the options to clojure.java.io/writer sent as a hash-map?

11:00 kzar: karmazilla: crap I didn't think of that side of things

11:02 kotarak: kzar: Sorry, couldn't resist: made things a bit more "idiomatic" for this style of programming: http://paste.lisp.org/display/117638#3 Also: your solution gives the results in the wrong order. (because of cons to lists)

11:04 karmazilla: I think fliebels unzip-like approach is good

11:04 kzar: kotarak: Oo thanks

11:21 FireSnake: hello anyone here use appengine-magic?

11:22 can anyone hear me at all?

11:23 ohpauleez: FireSnake: Loud and clear, I don't use it though

11:23 FireSnake: how come I can't hear everyone else?

11:24 fliebel: FireSnake: It's just rather quite in here.

11:24 FireSnake: what do you all come here for then?

11:24 if not to talk?

11:24 fliebel: Hammocking :)

11:25 FireSnake: ? What's hammocking?

11:25 or just joking around

11:25 fliebel: FireSnake: http://blip.tv/file/4457042

11:26 FireSnake: won't load in my page

11:26 Vinzent: FireSnake, probably you should ask your question and we'll try to help you

11:27 FireSnake: I'm trying to deploy a Google App Engine app and don't know how to set the default war file

11:28 fliebel I can't open your link

11:29 on Ubuntu Firefox

11:29 how does everyone in here deploy their clojure web apps?

11:30 fliebel: FireSnake: Unfortunate :( You might Google it: "Hammock-driven Development" Though it's not that important.

11:35 Does anyone have inspiring insights or code on how to find the best mach for a map like the ones coming from frequencies against a whole list of them? Ouch, I can't even explain what I mean.

11:36 edw: cascading

11:37 fliebel: edw?

11:38 lrenn: FireSnake: have you googled "clojure google app engine"? There seems to be quite a bit of info floating around.

11:39 FireSnake: lrenn yes I have and am in the middle of my tutorial but don't know how to set the default war file

11:41 lrenn: FireSnake: /join #compojure

11:42 FireSnake: ok thx

11:42 r0man: LauJensen: I have some basic google maps stuff over here: https://github.com/r0man/google-maps-clj

11:42 LauJensen: r0man: Thanks I'll take a look, but I already rolled my own

11:42 lrenn: FireSnake: sorry, didn't actually mean to send you there just yet. was trying to see how many folks were in there. They might have more experience with it than the folks here.

11:49 fliebel: Why doesn't reduce take more colls, just like map?

12:06 Awesome, I can do language detection :)

12:09 LauJensen: fliebel: me too, Ive detected you're speaking english

12:11 fliebel: LauJensen: Hah! Wrong, it's actually Denglish. (English spoken by Dutch people, according to "I always get my sin")

12:12 (zin ~= desire)

12:13 LauJensen: But what I meant to say is that I managed to compare the output of (frequencies "some text") to decide which language it is.

12:14 amalloy: fliebel: the behavior of reduce working on multiple maps is not obvious. should f take N arguments, or what?

12:15 fliebel: amalloy: Yes, this is the same for map, right?

12:15 hiredman: if reduce takes multiple collections, does it an init value or not?

12:16 fliebel: hiredman: Good, point… What if…

12:17 cemerick: it's still reducing to a single value…why not?

12:17 * cemerick is mostly playing devil's advocate

12:17 amalloy: cemerick: because it can't figure out which args are init values

12:17 (reduce f x y)

12:17 fliebel: cemerick: What if there isn't a init value? Would you take the first of the first, of a seq of all firsts?

12:18 amalloy: is x a coll, or an init value?

12:18 hiredman: cemerick: I'm just saying it's debatable, so by not taking multiple collections we can avoid debate

12:18 clizzin_: so i was dumb and misunderstood a serialize function that actually serialized to a clojure map instead of a string, and then wrote that map to a file, where it's represented by one map entry per line. is there a way i can read this back in and make it a clojure map again?

12:18 fliebel: amalloy: Also true....

12:19 clizzin_: the file looks something like: [:foo1 {:bar1 0.00134 :bar2 4.34934}]\n[:foo2 {:bar1 3.4562 :bar2 9.24343}]

12:20 fliebel: So the way to do this is (reduce f i (map vec col col col))

12:20 hiredman: vector

12:20 vec doesn't do what you want

12:20 kotarak: ,(read-string "[:foo1 {:bar1 0.00134 :bar2 4.34934}]\n[:foo2 {:bar1 3.4562 :bar2 9.24343}]")

12:20 clojurebot: [:foo1 {:bar1 0.00134, :bar2 4.34934}]

12:21 kotarak: clizzin_: I guess you just read the stuff back in with—eh—read.

12:22 ,(read-string (str "[" "[:foo1 {:bar1 0.00134 :bar2 4.34934}]\n[:foo2 {:bar1 3.4562 :bar2 9.24343}]" "]"))

12:22 clojurebot: [[:foo1 {:bar1 0.00134, :bar2 4.34934}] [:foo2 {:bar1 3.4562, :bar2 9.24343}]]

12:22 kotarak: ,(into {} (read-string (str "[" "[:foo1 {:bar1 0.00134 :bar2 4.34934}]\n[:foo2 {:bar1 3.4562 :bar2 9.24343}]" "]")))

12:22 clojurebot: {:foo1 {:bar1 0.00134, :bar2 4.34934}, :foo2 {:bar1 3.4562, :bar2 9.24343}}

12:23 clizzin_: kotarak: thanks! was not aware of the read-string function, that looks like just what i want.

12:24 kotarak: clizzin_: you might also want to read several times from a reader incrementally using read instead of read-string. YMMV

12:24 fogus`: cemerick: Don't cha know... nothing worth talking about happens in software outside of the Bay area. Sheesh

12:25 cemerick: fogus`: Yeah, they've only got COBOL books down here at the 5 and dime.

12:26 ejackson: fogus`: and in the UK we spell it Clojoure.

12:26 fogus`: "self-righteous metropolitan exceptionalism" -- wow!

12:26 cemerick: fogus`: too harsh? :_)

12:26 :-)

12:27 fogus`: cemerick: Well, I posted it to HN for you. :-) http://news.ycombinator.com/item?id=2001177

12:27 cemerick: DOOM awaits me, surely.

12:27 fogus`: cemerick: It's no more harsh than it needs to be.

12:28 technomancy: cemerick: I've got a rocket launcher if you need to borrow one.

12:28 chouser: I'm in Fort Wayne, loving my job. No argument here.

12:28 kzar: I'm an idiot wherever I go heh

12:28 cemerick: fogus`: I happened to hear a half-dozen offhand comments in that direction last week, one personally in my direction. Had to put it out there.

12:29 chouser: oh, and I've been to the bay area on business and have simply no interest at all in living there.

12:30 cemerick: chouser: in that case, you will simply never amount to anything! ;-)

12:30 * chouser nods

12:30 cemerick: technomancy: huh, I thought you were in portland!

12:31 * cemerick stands corrected

12:31 fogus`: I did the whole Sillicon valley interview tour a few years ago and while it was very exciting to see it for the first time, I didn't feel a connection with the area

12:31 technomancy: Portland is where I'd be if I weren't in Seattle

12:32 cemerick: Right…SEAjure. Dummy. :-(

12:32 technomancy: this is my favourite post on the bay area mindset: http://gilesbowkett.blogspot.com/2008/05/never-hate-only-ever-destroy.html

12:33 cemerick: Yeah, that's classic.

12:34 pjstadig: i think there may be some business arguments to being near VCs and corporate customers, but i'm not nearly an expert in this

12:35 if you're going to bootstrap and sell direct to consumers, then there's probably nearly zero reason to *have* to be in the Bay area

12:35 great technical talent lives everywhere, as we know at sonian

12:36 cemerick: Of course, the corporate customers are surely everywhere, and not just in sfbay.

12:36 pjstadig: true and there's always this thing called plane travel

12:36 ejackson: its nice to be near universities because of the interesting people that tend to be around

12:36 cemerick: And I always ignore any arguments that might include deference to VC-anything.

12:37 s/ignore/discount

12:37 sexpbot: <cemerick> And I always discount any arguments that might include deference to VC-anything.

12:37 cemerick: Maybe much to my detriment.

12:37 chouser: oh, I'm sure I'd have a wider selection of great jobs if I were willing to move to Silicon Valley. But I have some selection of great jobs right here, and moving there would simply not be worth it.

12:37 pjstadig: yeah i agree with you, i think the argument is weak, but i think its the only argument you can make

12:37 cemerick: ejackson: That's probably a much better indicator for a good area to be in.

12:38 ohpauleez: cemerick: Awesome post man

12:39 technomancy: chouser: the thing about jobs is you only need one =)

12:40 chouser: technomancy: exactly

12:40 cky: chouser: You can move to the Triangle, where Relevance is, and work in Clojure. :-P

12:40 ohpauleez: I will say that being near universities or interesting user groups/hacker-spaces that are pushing the envelope is nice

12:40 cky: chouser: It's a lot cheaper living than Silicon Valley. :-P

12:40 ohpauleez: you can find those almost anywhere, but you almost always find them in large cities

12:41 chouser: cky: yup. Or I can live right here, which is cheaper than both, and work in Clojure. :-)

12:41 cemerick: ohpauleez: thanks :-)

12:41 cky: chouser: :-P

12:41 chouser: Where is Fort Wayne, anyway?

12:41 * cky should Google it up, actually.

12:42 chouser: cky: http://maps.google.com/maps?oe=UTF-8&q=fort+wayne&ie=UTF8&hq=&hnear=Fort+Wayne,+Allen,+Indiana&gl=us&ei=DVsGTZeRHM-4ngfH-cHlDQ&oi=geocode_result&ved=0CCsQ8gEwAA&ll=40.32142,-85.561523&spn=7.637564,10.327148&t=rm&z=7

12:42 ugh. sorry, that's ugly

12:43 fogus`: cemerick: This is a nice juxtaposition to your post. http://svstartup.com/~svstartu/index.php?title=Main_Page

12:43 cky: chouser: It's okay. At least I could tell from the URL that it's in IN.

12:43 cemerick: fogus`: yeah, I saw that at the top of HN, so I figured I should go ahead and retweet the post :-)

12:46 fogus`: Living in the DC area, there is a related idea that if you're not working in Govt contracting then you're less than human.

12:46 In my experience anyway... maybe pjstadig has different experiences

12:47 amalloy: chouser: /msg sexpbot bitly <URL>

12:50 he also supports isgd, and (i think) tinyurl

12:50 zemariamm: hello everyone

12:50 ohpauleez: hi zemariamm

12:51 zemariamm: back to clojureland after some time away :)

12:51 I just started using leiningen

12:51 however I'm having a problem which I believe is pretty common

12:51 (since I found a bunch of posts about it on the clojure group :) )

12:52 here's the deal, I need to use some external jar on my app, this works fine during development

12:52 I just place them under my lib/ dir

12:52 and no problem

12:53 however I need to build a standalone jar

12:53 so lein uberjar

12:53 however

12:53 that command will first call "lein clean"

12:53 and delete my external jar and the compilation fails

12:53 kumarshantanu: zemariamm: you may find this thread useful -- http://groups.google.com/group/leiningen/browse_thread/thread/88a4052507197cbb

12:53 zemariamm: how do you guys solve this ?

12:55 kumarshantanU: thanks I'll have a look

12:58 amalloy: zemariamm: istr the easiest way is to install the jar to your local repo and then depend on it

12:58 zemariamm: so

12:59 I can put it under ~/repository/

12:59 and add this :repositories { "localShared" "file://~/m2"} to my project.clj , right ?

12:59 I meant ~/m2/repository

12:59 kumarshantanu: zemariamm: yes, but you should put the files under ~/m2 then

13:00 yes, right

13:00 zemariamm: awesome, going to try it :)

13:00 amalloy: zemariamm: ~/.m2 is already on your repo path, i think

13:00 kumarshantanu: amalloy: what is istr? any URL?

13:00 amalloy: $google istr

13:00 sexpbot: First out of 58400 results is: International Society for Third Sector Research(ISTR)

13:00 http://www.istr.org/

13:00 amalloy: damn

13:00 i seem to recall

13:00 kumarshantanu: ^^

13:02 gtrak: $lein repl

13:02 zemariamm: humm

13:02 still doesn't find it

13:02 so , I added :repositories { "localShared" "file://~/.m2"}

13:02 to my project.clj

13:02 and added the external jars under ~/.m2/repository

13:03 amalloy: zemariamm: i'm afraid my maven know-how begins and ends with "cake/lein use it; ~/.m2 is important somehow"

13:03 zemariamm: lool

13:03 yet my maven knowledge is about zero

13:03 :)

13:04 kumarshantanu: zemariamm: you may need to follow this http://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html to install the JAR in the repo

13:04 zemariamm: ah thanks, I'll have a look

13:04 kumarshantanu: because it needs a pom.xml file too, which is generated when you do a "mvn install"

13:04 zemariamm: I see

13:05 kumarshantanu: Maven is insane, you see ;-)

13:06 zemariamm: forgot to mention, you wil need to install Maven2 if you want to run "mvn install"

13:06 zemariamm: got it

13:06 this seems to help too: http://groups.google.com/group/clojure/browse_thread/thread/3a20228de255afa9

13:08 kumarshantanu: zemariamm: what's interesting is -- if you run "mvn install" for the local JAR then you don't need that ["localShared" "~/m2/"] thing

13:09 zemariamm: humm

13:09 kumarshantanu: because the local JAR is already part of the local maven2 repo

13:09 zemariamm: I'm still trying to hack something out , a simple shortcut :)

13:10 amalloy: zemariamm: mvn install is a shorter cut :P

13:10 Licenser: aloa

13:11 zemariamm: hehehe

13:11 ok, I'm sold, going to try maven :)

13:11 Licenser: you can also run lein install I think

13:11 then everything works splendid without the other stuff

13:12 kumarshantanu: Licenser: you can? I thought "lein install" works for a project.clj only

13:13 Licenser: yes but when he wants to add stuff for the project.clj he seems to have one

13:13 mvn instal only works on pom.xml as well right?

13:14 kumarshantanu: "lein install" degenerates into (1) generate POM (2) mvn package and (3) mvn install

13:14 Licenser: it still works :P also it shields you from writing 200+ lines XML files for maven

13:14 kumarshantanu: or the equivalent

13:15 gtrak: more like copy-pasting 200+ lines :-)

13:15 Licenser: still 200+ lines

13:15 gtrak: maven's not THAT bad

13:15 Licenser: I have to use it on winows so yes it is :P

13:15 at least for me

13:15 ohpauleez: he's a witch, kick him out of the channel :)

13:15 gtrak: heh me too

13:16 Licenser: what I'd wish was if there was a way to write a project.clj then 1:1 translate it to the corresponding pom.xml

13:16 ohpauleez: Everytime I have to start using maven on a project, a childhood memory dies, and somewhere, a kitten dies

13:17 Licenser: what is childhood?

13:17 kumarshantanu: as the folklore goes: once there was a bright programmer who went to work for a Java enterprise; he reported mentally unstable the next day...it was later heard he was actually asked to debug the build process involving 4096 lines of pom.xml ;-)

13:17 gtrak: jesus

13:18 why such a round number?

13:18 Licenser: I don't belive a word

13:18 it surely were more then 4k lines :P

13:18 ohpauleez: haha

13:18 cemerick: gtrak: take heart, those of us in #clojure that use maven simply ignore the hyperbole. You're far from alone. :-)

13:18 zemariamm: nice, maven installed

13:19 gtrak: haha, well, it's waht I'm used to with java, but i agree maven has a lot of ceremony you're forced to go through

13:19 zemariamm: I see a groupId, artifactId version and packaging, where can I learn about this ? Since I can't omit it (it will give me an error back)

13:19 cemerick: gtrak: it's the ceremony/capability ratio that you want to worry about :-)

13:19 gtrak: pretty arbitrary zemariamm

13:19 Licenser: I don't mind maven I mind the pom.xml and the sometimes horrible documentation and overcomplexity

13:20 zemariamm: gtrak: awesome, that's the answer I was looking for :)

13:20 gtrak: just make sure they line up

13:20 Licenser: zemariamm: to learn maven you are required to know maven!

13:20 zemariamm: Licenser: LOOOOOL

13:20 :)

13:20 gtrak: also, you might want to make sure there isn't already an existing pom, but I guess you know that?

13:20 ejackson: ACK - I'm going to cook supper.

13:21 kumarshantanu: zemariamm: lein [org.apache/foo "1.1.0"] -- translates to groupId=org.apache artifactId=foo version=1.1.0

13:21 gtrak: if it's in a repo online, it'll be cleaner

13:21 zemariamm: ahh, awesome

13:30 LauJensen: kumarshantanu: same for cake

13:30 zemariamm: fellas, I think it worked!

13:31 kumarshantanu: LauJensen: Yes project.clj is the same for lein and cake now I think

13:31 LauJensen: kumarshantanu: not quite, but we're working on the unification

13:32 kumarshantanu: LauJensen: oh okay

13:33 zemariamm: cool

13:33 zemariamm: :D

13:33 guys thanks so much for the help

13:33 i owe you a couple of beers

13:34 I'll post every step on a blog post or something like that, it's kind of useful :)

13:34 kumarshantanu: zemariamm: +1

13:38 Licenser: out of curiosity what are the advantages/disadvantages of cake and lein

13:38 save for one being tastier from the name

13:39 kumarshantanu: lein can fight the ants, and cake attracts them ;-)

13:39 * kumarshantanu ducks after the comment

13:39 zemariamm: humm

13:40 guys, related question

13:40 I've my main function defined as expected

13:40 and I have no problem

13:40 Licenser: but I can eat cake and I can't eat lein, well I think I could but it would be illegal

13:40 zemariamm: running "lein run"

13:40 (I specify :main in the project.clj file)

13:40 however I cant run a standalone jar

13:41 i get back a Exception in thread "main" java.lang.NoClassDefFoundError

13:42 kumarshantanu: zemariamm: does "lein uberjar" followed by "java -jar uberjar-name.jar" work?

13:42 zemariamm: nope, I get back a Exception in thread "main" java.lang.NoClassDefFoundError: qrdecoder/core

13:42 qrdecoder/core has my main function

13:43 kumarshantanu: zemariamm: did you declare :gen-class in the ns of the file containing -main ?

13:43 zemariamm: yep

13:43 (it works with "lein run")

13:45 Licenser: hmmm hmmm

13:46 kumarshantanu: zemariamm: did you specify the main name in project.clj?

13:46 zemariamm: yep: " :main qrdecoder.core"

13:46 if I didnt specify it, lein run would break I think

13:47 amalloy: zemariamm: one thing i like about cake is the persistent jvm. i think lein is adding that feature soonish, or maybe already has

13:47 zemariamm: amalloy: what's cake ?

13:47 technomancy: amalloy: it has interactive mode that keeps JVMs resident, yes

13:48 amalloy: oh, Licenser was the one who asked that questions, not you zemariamm. sorry about that

13:48 zemariamm: amalloy: np

13:48 kzar: Am I right in guesing "B cannot be cast to clojure.lang.IFn" means I'm trying to call a byte as if it where a function?

13:48 kumarshantanu: zemariamm: I have seen this NoClassDefFoundError couple of times myself, but can't remember what solved it -- there is a checklist for getting standalone JARs to run

13:48 amalloy: kzar: ##((byte 1))

13:48 sexpbot: java.lang.ClassCastException: java.lang.Byte cannot be cast to clojure.lang.IFn

13:49 kzar: amalloy: Oh, then what does it mean by B?

13:49 zemariamm: kumarshantanu: you mean, building the standalone jar without uberjar ?

13:50 amalloy: kzar: not sure. maybe you actually have a class named B somewhere? i think (IFn)(byte 1) in java would be a compile error, not a run-time error, but i could be wrong

13:50 kumarshantanu: zemariamm: no "lein uberjar" followed by running the standalone JAR

13:50 gtrak: first arg in a list is evaluated as a function unless you quote

13:50 amalloy: &(^"B" (byte 1))

13:50 sexpbot: java.lang.ClassCastException: java.lang.Byte cannot be cast to clojure.lang.IFn

13:50 gtrak: &'(byte 1)

13:50 sexpbot: ⟹ (byte 1)

13:51 amalloy: gtrak: we know

13:51 gtrak: so what's (byte 1) mean otherwise?

13:51 kumarshantanu: &(^"[B" (byte 1))

13:51 sexpbot: java.lang.ClassCastException: java.lang.Byte cannot be cast to clojure.lang.IFn

13:51 gtrak: confused

13:51 amalloy: &(byte 1)

13:51 sexpbot: ⟹ 1

13:51 gtrak: hmm

13:51 zemariamm: kumarshantanu: http://stackoverflow.com/questions/3677372/lein-jar-and-lein-uberjar-not-setting-the-main-class-properly

13:52 kzar: byte turns a number into a byte, useful sometimes when you need a byte for java interop

13:52 gtrak: ah, so having double parenthesis evaluates it again

13:52 kzar: gtrak: I need to turn my seq of numbers into a byte array so I have to apply byte and then call byte-array

13:52 kumarshantanu: gtrak: what are you trying to do?

13:52 amalloy: gtrak: not "evaluates it again"

13:52 "after evaluating it, calls it as a function"

13:52 gtrak: evaluates it

13:53 &(1)

13:53 sexpbot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

13:54 amalloy: kzar: ##(into-array (map byte [1 2 3]))

13:54 sexpbot: ⟹ #<Byte[] [Ljava.lang.Byte;@be9943>

13:54 clizzin_: if i want to apply a function to all the values in a map, is (zipmap (keys m) (fn (vals m)) the most idomatic/efficient way to go about doing this?

13:54 that's what i've been doing for a while, but it just occurred to me that perhaps there's a better way -- having to get the keys out seems kind of unnecessary.

13:54 amalloy: &(use 'clojure.contrib.generic.functors)

13:54 sexpbot: java.io.FileNotFoundException: Could not locate clojure/contrib/generic/functors__init.class or clojure/contrib/generic/functors.clj on classpath:

13:55 kzar: ((byte-array (apply byte (range 100))))

13:55 ,((byte-array (apply byte (range 100))))

13:55 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (21) passed to: core$byte

13:55 kzar: ,((byte-array (map byte (range 100))))

13:55 clojurebot: java.lang.ClassCastException: [B cannot be cast to clojure.lang.IFn

13:55 amalloy: &(use 'clojure.contrib.generic.functor)

13:55 sexpbot: java.io.FileNotFoundException: Could not locate clojure/contrib/generic/functor__init.class or clojure/contrib/generic/functor.clj on classpath:

13:55 kzar: there we go, B means Bytearray

13:55 amalloy: whatever. clizzin_, clojure.contrib.generic.functor/fmap does what you want

13:55 kzar: amalloy: Cool thanks, I'll do it like that

13:56 amalloy: kzar: [B means byte[]

13:56 zemariamm: kumarshantanu: I opened teh jar, I do have qrdecoder/core$_main.class

13:56 amalloy: i could tell you that if you hadn't said it was B

13:56 zemariamm: it should be it right ?

13:56 clizzin_: amalloy: thanks

13:56 Surgo: silly newbie macro question...I'm attempting to set a var of a name given as the macro parameters (at compile time), and later access it...but it seems when I run (def) in a macro, it doesn't make the var accessible non-locally (or at least when I try to resolve it it's not there).

13:57 amalloy: Surgo: it should work. make a paste?

13:57 Surgo: code example: http://pastebin.com/eCBHqv31 . Run with abcd, then I try resolving abcd after the macro runs...and nothing.

13:57 kumarshantanu: zemariamm: I think you should rather have core.class because it's supposed to be gen-class'ed (but not sure at the moment)

13:57 Surgo: (well, there is something, "Unable to resolve symbol" :P)

13:58 amalloy: Surgo: you want this var accessible at compile-time, or at runtime?

13:58 Surgo: compile-time

13:58 it'll actually be gone by the time run-time comes around

14:00 zemariamm: kumarshantanu: by reading the docs I think you are absolutely right

14:00 amalloy: Surgo: it's somewhat tricky, because def is a special form that needs its argument as a literal

14:01 (def fname) defines a var called fname, not one whose name is the contents of fname

14:01 zemariamm: kumarshantanu:oh shit, I had gen-class instead of :gen-class in my ns definition

14:01 Surgo: amalloy: yeah, that's what I want (the var being called fname)

14:01 amalloy: oh. really?

14:01 Surgo: its contents should just be (list)

14:01 amalloy: okay

14:01 kumarshantanu: zemariamm: the funny part about the ns macro is - if you mis-spell something in this macro it may not throw any error and still ignore it

14:02 zemariamm: so watch out for that too

14:02 zemariamm: :D

14:02 amalloy: but...your code doesn't look that way. why are you taking fname as a parameter

14:02 zemariamm: rebuilding :)

14:02 amalloy: if you want the name to always be the literal symbol/string "fname"

14:02 Surgo: oh, I see the confusion

14:03 I want the name to be different, depending on what "fname" is -- it should just be called fname. Maybe this communication would be easier if I tried to state what I was trying to do :-P

14:03 amalloy: Surgo: i can see what you're trying to do, you just keep claiming you're trying to do something else :)

14:03 Surgo: I think that might have something to do with how little I know what I'm talking about

14:03 zemariamm: kumarshantanu: thanks so much, it finally rans, with another error, but a different one :)

14:04 runs*

14:04 kumarshantanu: zemariamm: \m/

14:04 Surgo: what I want...the var to be named based on the parameter given (fname), but whose contents is just (list). Am I still misunderstanding?

14:04 zemariamm: the error I get back is exactly this one: http://stackoverflow.com/questions/4354293/jar-produced-with-lein-uberjar-fails-on-noclassdeffounderror , researchign it

14:04 amalloy: no, you've now stated what you meant all along

14:04 hurrah!

14:05 Surgo: thank you

14:05 amalloy: so the way to do that is `(def ~fname (list))

14:05 Surgo: hopefully as I become less of a newbie to all of this I will become better at communicating

14:05 zemariamm: leinigen 1.4.0 bug ?

14:06 kumarshantanu: zemariamm: (1) lein clean (2) rm -rf lib (3) lein ubderjar

14:06 amalloy: but that is a little tricky, because it expands into code that defs, rather than doing the def itself; the def won't happen unless (mactest foo) is in code that is doing something at compile time already

14:06 Surgo: hmm...wouldn't that cause the code to be run at run-time?

14:06 kumarshantanu: s/ubderjar/uberjar/

14:06 sexpbot: <kumarshantanu> zemariamm: (1) lein clean (2) rm -rf lib (3) lein uberjar

14:06 zemariamm: going to try it

14:07 it works!!!!

14:07 I ended up adding :keep-non-project-classes true

14:07 amalloy: Surgo: you can't really do it otherwise, because at the time that mactest is itself compiled (not the call to mactest), it doesn't have the name of the var to def, and it needs a compile-time literal

14:07 zemariamm: to my project.clj

14:07 Surgo: it's not really clear to me what a (do `(def ~fname (list)) (do-other-stuff)) would do, actually

14:08 amalloy: hrm, maybe there's another way to get to the same effect without needing a persistent var

14:08 amalloy: you *might* be able to do it by creating another macro that builds mactest-like macros that know what to def at compile-time, but that is getting pretty intricate

14:09 Surgo: what I'm trying to do is simply allow piecewise function composition using pattern matching (like ML), so what I figured was I'd define a macro that just stuffed all the piecewise definitions in a list named the same as the function (to guarantee uniqueness), then have a final macro that composed them into an actual (defn)

14:09 no real reason to do this, just trying to learn clojure :)

14:10 amalloy: Surgo: (eval `(def ~fname (list))) would work for sure, if you ever get desperate enough to use eval

14:12 Surgo: brilliant! though if I could bother you to help me understand how that's different than a plain (def fname (list))?

14:13 I mean, seems to me at first to just be the evaluation of fname

14:13 amalloy: Surgo: yep

14:13 that is the only difference

14:13 Surgo: ah

14:14 amalloy: and because def doesn't evaluate its first argument, it is a necessary difference

14:14 Surgo: and def, being a special form, barfs at (dev (eval fname) (list))

14:14 (just tried it)

14:14 chouser: Pop quiz!

14:14 Surgo: thank you very much, this has been quite informative and helpful

14:14 amalloy: (eval fname) probably wouldn't work anyway

14:14 or i guess it would, i dunno

14:15 chouser: hm, wait a sec.

14:15 Surgo: now let's see if I can finish that macro array

14:15 amalloy: chouser: now that we've had time to prepare, is it still a pop quiz?

14:15 chouser: yes it is

14:15 the question is:

14:16 what clojure.core function or macro whose name starts with "with-" has nothing to do with dynamic scope?

14:16 amalloy: with-command-line-args?

14:16 or whatever it's called

14:17 chouser: that is, it doesn't refer to binding or try/catch in its docstring or source

14:17 amalloy: I think that's in contrib somewhere

14:17 amalloy: oh, so it is

14:17 hiredman: the local vars thing?

14:17 chouser: that's dynamic scope

14:17 technomancy: with-meta

14:17 hiredman: maybe with-open, I always forget if that uses binding or let, must be let

14:17 chouser: is it?

14:17 danlarkin: with-open uses try/finally

14:18 chouser: and uses try/finally to pop thread bindings

14:18 zemariamm: guys I'm out, thanks so much for the help :D

14:18 hiredman: chouser: are you sure?

14:19 ah, I guess it does

14:19 let+binding

14:20 amalloy: anyway, technomancy surely wins the prize for with-meta

14:21 hiredman: chouser: so why does having try/catch disqualify from "nothing to do with dynamic scope"

14:21 chouser: try/catch is dynamic scope

14:21 amalloy: hiredman: try/catch is how clojure gets dynamic scope, isn't it?

14:21 chouser: oh, missed it.

14:21 technomancy: right, with-meta

14:22 hiredman: amalloy: no

14:22 chouser: (defn foo [] (throw x)) (try (foo) (catch ...))

14:22 hiredman: chouser: ok, but try/finally?

14:22 chouser: throw x happens in the dynamic scope defined by try/catch

14:22 same thing with try/finally

14:23 amalloy: i think hiredman's point is the finally has no access to whatever was thrown

14:23 chouser: ah, interesting point.

14:23 hiredman: it also get's executed regardless of something being thrown

14:24 chouser: & (remove #(re-find #"binding|try" (clojure.repl/source-fn %)) (filter #(re-find #"^with-" (str %)) (keys (ns-publics 'clojure.core))))

14:24 sexpbot: java.lang.ClassNotFoundException: clojure.repl

14:24 chouser: aw

14:24 , (remove #(re-find #"binding|try" (clojure.repl/source-fn %)) (filter #(re-find #"^with-" (str %)) (keys (ns-publics 'clojure.core))))

14:24 clojurebot: java.lang.NullPointerException

14:24 chouser: :-P

14:24 hiredman: really, my point is, I should get points for with-open

14:24 chouser: heh

14:24 (inc technomancy)

14:24 Tordmor: Let's say I have a quoted form in a var like (def f '(+ 3 4)) how would I turn this into a function?

14:24 hiredman: the binding it creates are all lexical

14:25 sexpbot: ⟹ 2

14:25 chouser: (inc hiredman)

14:25 sexpbot: ⟹ 1

14:25 technomancy: I used tab-completion on slime; I don't know if that's cheating.

14:27 amalloy: (inc slime)

14:27 sexpbot: ⟹ 1

14:27 Surgo: the clojure docs say you can't change the root binding of a var with set!; so, how would you change it? (it's kind of silly but it'd be nice if that was the next sentence in the docs)

14:27 amalloy: Surgo: ##(doc alter-var-root!)

14:27 sexpbot: java.lang.Exception: Unable to resolve var: alter-var-root! in this context

14:27 amalloy: Surgo: ##(doc alter-var-root)

14:27 sexpbot: java.lang.SecurityException: You tripped the alarm! alter-var-root is bad!

14:27 chouser: Surgo: you're generally not meant to

14:28 amalloy: sexpbot: stuff it

14:28 Tordmor: How would I build a clojure function at runtime?

14:29 Surgo: Tordmor: you can just (eval f), given your above example

14:30 amalloy: Tordmor: (fn [x] (eval `(let [~'x ~x] ~@myfn-code))), if you want to pass it x as an argument

14:30 gtrak: &(find-doc "alter-var-root")

14:30 sexpbot: ⟹ ------------------------- clojure.core/alter-var-root ([v f & args]) Atomically alters the root binding of var v by applying f to its current value plus any args ------------------------- clojail.core/sandbox ([tester & {:keys [timeout namespace context jvm?], :o... http://gist.github.com/739467

14:33 gtrak: &(eval (list inc 1))

14:33 sexpbot: java.lang.SecurityException: You tripped the alarm! eval is bad!

14:33 gtrak: &(list inc 1)

14:33 sexpbot: ⟹ (#<core$inc clojure.core$inc@16968c4> 1)

14:34 gtrak: does that work?

14:34 amalloy: gtrak: yes

14:34 gtrak: ok cool :-)

14:34 amalloy: but you have to be careful if you want a function that isn't in clojure.core like inc is

14:34 gtrak: how so?

14:34 amalloy: (eval `(inc 1)) is a fair bit safer

14:35 gtrak: b/c it figures out namespaces for you?

14:35 amalloy: gtrak: if you return (myfoo 10) and the caller hasn't :use'd myns, then myfoo will be an error when they run it

14:35 gtrak: &`inc

14:35 sexpbot: ⟹ clojure.core/inc

14:35 gtrak: got it

14:36 amalloy: ` resolves the namespaces in the context of building the list rather than executing it, as you have demonstrated

14:37 cky: Maybe it's just a personal style thing, but when there are no unquotes, I vastly prefer to use quote, not quasiquote.

14:37 That way, when I read the code, I know that nothing in there is going to get evaluated.

14:37 &'(inc 1)

14:37 &`(inc 1)

14:37 sexpbot: ⟹ (inc 1)

14:37 ⟹ (clojure.core/inc 1)

14:38 cky: amalloy: That makes more sense.

14:38 gtrak: cky: not sure I get what you mean

14:38 Surgo: This is strange...when I set up the var in the macro, using alter-var-root, to cons another list on, it gets altered appropriately within the macro, but when I resolve the var outside of the macro, it doesn't change. When I try accessing it in another macro, it is changed. Is there some scoping information I'm missing here?

14:39 cky: gtrak: amalloy has just explained why '(foo bar) is not the same as `(foo bar) in Clojure.

14:39 gtrak: My background is in Scheme, where the two are no different at all.

14:40 Surgo: or...hmm. could it be that the binding is different because this is a 'pure' functional thing, and it still thinks that me in the REPL is using the old binding so it hasn't gotten rid of it yet

14:40 cky: &'(non-existent 1)

14:40 sexpbot: ⟹ (non-existent 1)

14:41 cky: &`(non-existent 1)

14:41 sexpbot: ⟹ (clojure.core/non-existent 1)

14:41 cky: O_o

14:41 gtrak: so, it's late symbol resolution vs early?

14:41 what's the issue?

14:41 amalloy: resolution at macro time, yes

14:41 fogus`: &'(clojure.core/non-existent 1)

14:41 sexpbot: ⟹ (clojure.core/non-existent 1)

14:42 gtrak: &'(random-symbol 1)

14:42 sexpbot: ⟹ (random-symbol 1)

14:42 gtrak: &`(random-symbol 1)

14:42 sexpbot: ⟹ (clojure.core/random-symbol 1)

14:42 gtrak: huh?

14:43 oh weird

14:43 `(asdflasdf)

14:43 &`(asdflasdf)

14:43 sexpbot: ⟹ (clojure.core/asdflasdf)

14:43 gtrak: that's a little weird

14:46 fogus`: gtrak: What do you suspect would happen if you ran: (eval `(non-existent 1))?

14:46 chouser: gtrak: sexpbot must be evaluating our expressions in the clojure.core namespace

14:46 & *ns*

14:46 sexpbot: ⟹ #<Namespace sandbox6362>

14:46 chouser: hm

14:47 gtrak: i would think it would just ignore it

14:47 fogus`: gtrak: wrong person. :-( sorry.

14:47 chouser: sexpbot must be reading our expressions in the clojure.core namespace

14:50 alpheus: Can anyone direct me to an example of destructuring with :strs?

14:51 chouser: & (let [x {"one" 1, "two" 2, "three" 3}, {:strs [one two three]} x] ['counting one two three])

14:51 sexpbot: ⟹ [counting 1 2 3]

14:53 chouser: alpheus: ^^^

14:54 alpheus: oh, you don't quote the strings

15:02 How would I represent a key that is a string containing a space?

15:05 Tordmor: alpheus: As a string?

15:08 ohpauleez: alpheus: You could string replace each space with an underscore, and keyword that string

15:08 but it won't be reversible

15:08 alpheus: Yes, I'm trying to destructure a map having some keys that are strings with spaces.

15:08 ohpauleez: example "here is a_string" => :here_is_a_string => "here is a string"

15:09 if you only need the first two, just do a string replace

15:09 alpheus: The map is externally defined, since it comes from a csv file that I'm loading.

15:10 ohpauleez: well, trim the string, then replace all spaces with underscores, then call keyword on it

15:11 alpheus: I can think of various ways to solve the problem, but I can't find a definition of what destructuring with :strs is actually supposed to do. The example that chouser gave above is the only example I've seen so far.

15:12 I'm sure I've just missed it, not saying that the docs are deficient or something.

15:19 amalloy: alpheus: it's supposed to do exactly what chouser's example does...(ie, like :keys but with "foo" instead of :foo)

15:35 fogus`: :strs comes in handy when dealing with maps built from a JSON source

15:54 jweiss_: Can I extend a protocol to another protocol?

15:55 eg, if i have a protcol Raisable that has a interface with "raise", and i want to extend it to my protocol "Condition" so that every concrete condition can be "raised"?

15:55 nickik: not possible.

15:55 brehaut: jweiss_: i dont think you can [citation needed]

15:56 jweiss_: ok then can two protocols share the same fn?

15:56 i'm guessing now

15:56 not

15:56 brehaut: jweiss_: if namespaced yes

15:57 foo/my-proto-fn and bar/my-proto-fn are different funs

15:57 but otherwise no

15:57 jweiss_: no, what i've got here is that all Conditions are Raisable, but not all Raisables are Conditions.

15:58 so how do i specify the "raise" fn for all Conditions?

15:58 just have to have all their concrete types implement it i guess

16:21 amalloy: jweiss_: i don't think you want two protocols here, really, do you? protocols don't really have a hierarchy

16:22 you want a raise protocol, and two interfaces Raisable and Condition:Raisable; then you can extend the raise protocol to the Raisable interface

16:30 clizzin_: what's a typical use case for constantly? it seems like a weird function to have...

16:30 dnolen_: ,(interleave [1 2 3 4] (constantly 'foo))

16:30 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$constantly$fn__3551

16:31 pjstadig: when you think you want to do something like #(foo) you want constantly instead

16:31 hiredman: dnolen_: you are thinking of repeatedly

16:31 dnolen_: ,(interleave [1 2 3 4] (constantly (fn [] 'foo)))

16:31 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$constantly$fn__3551

16:31 dnolen_: hiredman: yeah

16:31 (doc constantly)

16:31 clojurebot: "([x]); Returns a function that takes any number of arguments and returns x."

16:31 ohpauleez: when you want to use constant, but off of a function value

16:32 hiredman: constantly is useful for representing constants when you are dealing with higher order functions

16:32 ohpauleez: that's also a good way to phrase it

16:32 hiredman: update-in, swap!, send-off, send, etc

16:34 kzar: booya my step sequencer no longer crashes Java

16:34 duncanm: in slime/swank, isn't there a way to get the last result from the REPL?

16:34 something like $1, or #1 ?

16:34 %1 maybe?

16:35 ohpauleez: *1

16:35 you can get the last three

16:35 duncanm: ohpauleez: yes!

16:35 ohpauleez: *1 *2 *3

16:35 duncanm: ohpauleez: it was you who told me about this last time ;-)

16:35 ohpauleez: :)

16:35 duncanm: I'm glad I can help

16:35 super useful

16:36 duncanm: ohpauleez: indeed

17:08 clizzin: ohpauleez, hiredman: re constantly, i get the general idea of wanting to save the output of a higher-order function, but why not just bind that in a var? the code i'm looking at takes a seq or vector foo and binds foo-fn to (constantly foo). i feel like there's a performance improvement here but am not sure why/how.

17:09 amalloy: clizzin: you don't get the idea; you're upside-down

17:10 say you want to call a library function asks you to pass it a function; it's going to call that function ten times with different arguments to decide how to populate a list it gives you

17:11 but your program is really simple and you want the list to just be full of zeros. so you call (libfn (constantly 0))

17:12 making more sense now?

17:12 clojurebot: Titim gan éirí ort.

17:16 clizzin: amalloy: i see. okay, i get both that case and the case in the code i'm reading now. awesome. thanks!

17:18 ohpauleez: clizzin: Also, think about a framework, that needs to always start with a default reply

17:19 it's easy to make that a function call, and then redefine that function call in other namespaces or what-have you

17:19 making stubbing easier, while keeping the calling and composition of functions of the framework intact

17:23 Nikelandjelo: Which variant is correct (defn tst [^long x] ... ) or (defn tst [^:long x] ...) ?

17:24 amalloy: Nikelandjelo: the first

17:24 (or maybe neither? i don't think clojure functions can accept primitive args before 1.3)

17:26 ohpauleez: amalloy Nikelandjelo: right, before 1.3, you could only cast in a let and use the primitive there

17:26 otherwise, you could only type hint (objects) for java purposes

17:27 Nikelandjelo: Thanks. I still use 1.2 I should switch to 1.3 :)

17:27 I read, 1.3 version is slower than 1.2 Is it still actual?

17:28 ohpauleez: Nikelandjelo: There were some speed regressions for certain tasks in 1.3. When those get discovered, they get fixed rather quickly

17:28 I have never personally hit any of them, and in fact have been able to write pretty fast 1.3 stuff

17:40 edw: `choose': is this a standard clojure procedure?

17:41 amalloy: edw: i choose things all the time. what do you want "choose" to do?

17:41 edw: I'm looking at some sample code, and choose is undefined.

17:41 amalloy: &(doc choose)

17:41 sexpbot: java.lang.Exception: Unable to resolve var: choose in this context

17:41 jcromartie: critique please! (inspired by Compojure's route/clout mechanism) https://gist.github.com/c9522a2f56722f2a0d8e

17:42 ohpauleez: it's in contrib

17:42 and in incanter

17:42 amalloy: edw: link it? it's probably in their use/require

17:42 ohpauleez: http://clojuredocs.org/clojure_contrib/clojure.contrib.probabilities.finite-distributions/choose

17:43 edw: Ah. Thanks. I searched through core but not contrib: finding the contrib doc page is sometimes surprisingly difficult.

17:43 jcromartie: all the "normalize" is a little clunky

17:43 I could clean that up

17:43 amalloy: edw: yes, google helpfully provides old-old links to wrong places. you could try clojuredocs.org, which is usually pretty good

17:43 ohpauleez: yes, I have just defaulted to ClojureDocs, and if I refuse to use a browser, I usually just hit the API with python

17:50 jcromartie: what is the leiningen project/script/ directory for?

17:50 ohpauleez: I use it for one off scripts I need. Like my repl-init script

17:51 or provisioning scripts, for example

17:51 jcromartie: provisioning?

17:51 ohpauleez: like for kicking off builds or pushing something to a staging server

17:52 I'm sure I abuse it, but that's what I put in there

17:54 jcromartie: heh, I don't think there's a defined use

17:54 seems handy though

17:54 like for usage examples, perhaps

18:03 clizzin: jesus, quora is devastatingly slow

18:05 amalloy: am i guaranteed that (= (byte 1) 1), or may that stop being true, eg as part of the auto-promotion changes in 1.3?

18:06 clizzin: ^ whoops, wrong room =(

18:08 ohpauleez: amalloy: I think you'll be ok

18:09 do not quote me on that, I haven't seen the latest work that has gone into that

18:24 dnolen_: amalloy: you will need to use == in 1.3.0 to avoid things like (= 1M 1) ; false, and (= 1.0 1) ; false

18:27 amalloy: dnolen_: thanks

18:33 joegallo: finished up 102, will merge into qa tomorrow, heading out.

18:33 wrong channel, I'm a moron.

19:36 amalloy: can someone look at http://is.gd/iHwv0 in paredit for me? mine refuses to delete anything in the last defn because of unbalanced " characters, but (a) they're balanced, and (b) it thought they were balanced enough to enter paredit mode

19:51 devinus: just curious, but why can't clojure do TCO the way scala does it?

19:57 chouser: devinus: it could, but 'recur' is nicely explict -- if you think you have written something tail-recursive when you haven't, 'recur' will give you an error

19:57 amalloy: devinus: my quick search indicates that how scala does it is "barely"

19:57 though personally i like chouser's reason

19:57 devinus: chouser: oh nice

19:58 chouser: if you think you've written something tail-recursive with a plain function call, but you haven't, you won't know until you blow the stack at runtime

19:58 amalloy: chouser: or you ask chouser about it :)

19:58 chouser: as far as I know, Scala only does automatic tail recursion optimisation in cases where 'recur' would work in clojure

19:59 gtrak: yea... if you're coming from static languages it feels worth it to know what's going to happen, i think people from scheme think it's less elegant

20:00 at least that's how I think of it

20:00 no reason to have any doubt whether it'll tail-recur or not, the compiler will tell you

20:00 it's not like you don't have to think about it when you're writing scheme

20:01 chouser: right

20:02 and Clojure can't give full TCO (in mutual recursion cases etc.) while keeping Java calling conventions, so you'd have to know that caveat too.

20:02 gtrak: hmm, how do you do that anyway?

20:02 brehaut: gtrak: scheme does have a difference in that everything is rewritten to continuations though right?

20:02 gtrak: actually I don't know

20:03 I took a course on it a long time ago, and now I'm learning clojure :-)

20:03 hiredman: brehaut: doesnn't have to be, that is just a technique for implementing scheme

20:03 brehaut: gtrak: it was definately the case with steele's original scheme. i dont know if it still holds

20:04 hiredman: cheers

20:13 Adamant: brehaut: only if CPS is used

20:14 brehaut: Adamant: can you clarify for me; do you mean for the scheme implementation or the scheme users program?

20:14 Adamant: implementation

20:14 at the user level, everything is not continuations

20:14 brehaut: yes thats what i thought

20:14 Adamant: although you can use CPS at user level if you want

20:15 having explict recur is definitely ugly for people used to Scheme, like me

20:16 sadly adding TCO to the JVM is not a current priority

20:16 they're busy with the dynamic support it seems

20:17 brehaut: real? i thought they were busy painting the bike shed

20:18 Adamant: brehaut: I was whining on here about that and got asked to put my money where my mouth was by Rich

20:18 brehaut: fair nuff :)

20:18 Adamant: I tried, but the JVM folks aren't interested at the current juncture

20:18 they are interested though

20:18 gtrak: apparently the apple jvm had TCO

20:19 but now it's hosed?

20:19 Adamant: yeah, Apple now hates Java

20:19 of course Apples hates everything not Apple

20:19 gtrak: still, their TCO must not be platform specific, right?

20:20 Adamant: gtrak: no idea, and the basic thing is the guys working on extended the JVM don't want the trouble right now

20:20 they're loaded to the gills with dynamic support

20:20 gtrak: ah

20:20 Adamant: TCO is one other thing to add they don't have time for, even if other people do most of the coding

20:23 it will definitely have an effect on stack walking stuff, which for one thing lots of the security mechanisms do

20:28 tomoj: I haven't found myself missing TCO

20:34 brehaut: tomoj: its incredibly rare that i even have to bust out a recur

20:36 joshua__: (:require ((net.cgrand.enlive-html :as html)

20:36 (compojure.route :as route))))

20:36 whats wrong with that?

20:37 brehaut: joshua__: you arent quoting your symbols?

20:37 hmm no

20:38 joshua__: will give more info in a second..

20:39 tomoj: you don't need to quote there

20:39 joshua__: I'm trying to do something like: http://pastebin.com/SrwSpSyx with only one :require

20:39 brehaut: joshua__: try (:require [net.cgrand.enlive-html :as html] [compojure.route :as route])

20:39 (asuming this is in a ns form)

20:43 gertalot: hey everyone! I'm trying to figure out a way to do something similar to prewalk-replace or postwalk-replace, that only changes at most a single element (not every element like these functions)

20:43 and I'm stuck (or I wouldn't bother you) :)

20:44 or a clojure.core/replace that only replaces the first occurrence of something that's replaceable

20:45 clizzin: how can i pass a static java function as an argument to map? i just tried (map java.lang.Math/log foo), but it looks like clojure tries to look for a static field instead of a method. any way to do this without just using an anonymous function?

20:46 notsonerdysunny: Hello everybody I required clojure.contrib.generic.math-operations as gm and now I want to bind the default / with gm// but it is telling me that the gm// is not a correct token .. so how can I / with gm// ?

20:47 scgilardi: clizzin: afaik there isn't. using an anonymous function is a good choice.

20:47 clizzin: thanks scgilardi

20:54 scgilardi: notsonerdysunny: I haven't done what you're trying to do, but does the qsym macro (http://richhickey.github.com/clojure-contrib/generic.arithmetic-api.html) help?

20:55 joshua__: brehaut: thanks that worked (would have told you sooner but I had to close the webserver, using compojure without gae this time and not sure how to do interactive development just yet)

20:55 brehaut: joshua__: no problem

20:58 notsonerdysunny: thanks scgilardi

20:58 that worked

20:58 scgilardi: cool

21:00 brehaut: joshua__: i use moustache for my routing and for everything other than redefining routes holding the repl open and using (use :reload my-ns.foo) is sufficient to do interactive development

21:00 joshua__ ive got something messed up though which means if i change my routes i have to quit the repl because it breaks something on the jetty server and ive been too lazy to fix it

21:02 joshua__: the other thing to consider is looking at lazytest ( https://github.com/stuartsierra/lazytest ) im pretty sure it does a simple watch on your clj files and reloads them when they change and reruns any appropriate tests

21:12 joshua__: brehaut: I found a simple way to do it, though I don't like it as it always throws an exception. I can wrap my handler in a (var hanlder) when passing it to jetty. Hopefully I'll find a way that doesn't cause an exception when you compile, despite working. Reading: http://groups.google.com/group/compojure/browse_thread/thread/5606760b86cfd49c

21:15 I think I've got a solution to the exception thrown despite it working.. how do I catch exceptions in clojure?

21:26 brehaut: joshua__: you might be surprised to discover that you use try catch http://clojure.org/special_forms#Special%20Forms--(try%20expr*%20catch-clause*%20finally-clause?)

21:28 joshua__: brehaut: Just got it working not ten seconds ago. You can see my solution here: http://pastebin.com/Bv0Y2DVF

21:29 brehaut: better doc of how to use the try catch is what slowed me down the most, but this helped: http://en.wikibooks.org/wiki/Clojure_Programming/Concepts when I searched it for examples of try

21:30 notsonerdysunny: ~(clojure.contrib.generic.arithmetic/* (struct clojure.contrib.complex-numbers/complex-struct 10 20)

21:30 clojurebot: ant clean and rebuild contrib

21:30 notsonerdysunny: (struct clojure.contrib.complex-numbers/complex-struct 2 1))

21:31 ~(clojure.contrib.generic.arithmetic/* (struct clojure.contrib.complex-numbers/complex-struct 10 20) (struct clojure.contrib.complex-numbers/complex-struct 2 1))

21:31 clojurebot: compiling clojure is rarely necessary to do yourself.

21:31 notsonerdysunny: ~(clojure.contrib.generic.arithmetic/* (struct clojure.contrib.complex-numbers/complex-struct 10 20) (struct clojure.contrib.complex-numbers/complex-struct 2 1))

21:31 clojurebot: pcl → clojure is http://blog.thinkrelevance.com/2008/09/16/pcl-clojure

21:32 notsonerdysunny: the s-expression (clojure.contrib.generic.arithmetic/* (struct clojure.contrib.complex-numbers/complex-struct 10 20) (struct clojure.contrib.complex-numbers/complex-struct 2 1)) gives me the exception

21:33 No method in multimethod '*' for dispatch value: [clojure.lang.PersistentStructMap clojure.lang.PersistentStructMap]

21:33 [Thrown class java.lang.IllegalArgumentException]

21:33 can anybody help me understand what is happening here?

21:51 amalloy: notsonerdysunny: c.c.g.a doesn't support the types in c.c.c-n, it just leaves space for you to add your own implementation

21:53 &(require 'clojure.contrib.generic.arithmetic :as 'math)

21:53 sexpbot: java.io.FileNotFoundException: Could not locate clojure/contrib/generic/arithmetic__init.class or clojure/contrib/generic/arithmetic.clj on classpath:

21:58 notsonerdysunny: thanks amalloy ..

22:17 I am defining a protocol which defines the functions +,-,*,/ .. so I am excluding those symbols when I do :refer-clojure but I would like to give an alias to say something like c+ c- c* and c/ how can I do this?

22:25 amalloy: (:require clojure.core :as c) should do it

22:28 okay, i was close. this works: (ns foo (:require [clojure.core :as c]))

22:31 defn: yeah i always forget when to wrap in []

22:32 amalloy: notsonerdysunny: ^^

22:34 tomoj: notsonerdysunny: use :rename instead of :exclude?

23:03 notsonerdysunny: thanks tomoj ..

23:03 that did the trick

23:05 amalloy: &(let [[a & [b & c]] [1 2 3 4]] [a b c])

23:05 sexpbot: ⟹ [1 2 (3 4)]

23:15 Guest28208: do you ever really need to call "apply"?

23:15 amalloy: Guest28208: yes

23:15 Guest28208: like when?

23:16 cky: Guest28208: When you need to take the arguments from a list.

23:16 amalloy: in general: when you get a list from some outside source that had no choice but to give you a list, and need to treat them as separate arguments to a function

23:17 Guest28208: ok. makes sense

23:17 thx amalloyand cky

23:17 amalloy: eg, (concat [1 2] [3 4]) should clearly return [1 2 3 4], but what if someone passes you the vector [[1 2] [3 4]]

23:17 joshua__: Do you still serve files in compojure with serve-file?

23:18 nervermind

23:20 auser: how do you go over a string, character by character?

23:21 amalloy: auser: strings are seqs of chars, so map et all work

23:21 auser: ah, cool

23:21 thx

23:21 amalloy: you probably have to call (seq) on it first

23:21 hippiehunter: does anyone else ever have any trouble with slime after disconnecting/reconnecting swank? Ive reconnected but it just keeps saying "connection closed" whenever i try to do anything slime related

23:28 amalloy: i can never quite remember how to use :or map destructuring

23:29 anyone have a pointer for me?

23:30 Raynes: &(let [{:keys [x y] :or {y 2}} {:x 3}] (+ x y))

23:30 sexpbot: ⟹ 5

23:30 amalloy: thanks. i usually try :or {:y 2}

23:30 so far it hasn't worked, but i'm still hoping

23:32 tomoj: &(let [{:keys [x y] :as opts :or {x 1}} {:y 2}] [x y opts]) ; seem funny?

23:32 sexpbot: ⟹ [1 2 {:y 2}]

23:33 tomoj: guess not

23:33 hippiehunter: raynes: do you have that response bound to a key? I think thats the single most frequent question ive seen in here, and you answer it everytime.

Logging service provided by n01se.net