#clojure log - Nov 03 2011

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

0:01 * srid posted a codereview question at http://codereview.stackexchange.com/questions/5777/

0:07 zakwilson: I want to start a repl in my namespace from my -main function. What's the easiest way to do this? Looking at clojure.main/repl, it doesn't seem to be able to do that.

0:14 hiredman: zakwilson: why not?

0:15 zakwilson: hiredman: because I'm bad at reading documentation. Looks like :init #(in-ns 'my-ns) does the trick.

0:28 brehaut: enlive nerds: thoughts on (defn enlive-render-wrap [f] (fn [req] (update-in (f req) [:body] #(if (:tag %) (enlive/emit* %) %)))) ? (removing template, and just using snippets, relying on the middleware to render)

1:27 callen: korma looks nice.

1:33 ibdknox: callen: hopefully ;)

3:33 callen: https://github.com/getwoven/clj-time/blob/master/src/clj_time/core.clj trying to use this code, having a weird issue specific to inside a defn.

3:33 (defn unix-now [] (use 'clj-time.core) (in-secs (interval (epoch) (now))))

3:33 that fails

3:34 simply using the namespace inside a repl works.

3:34 hiredman: yeah, don't do that

3:34 callen: hiredman: feel free to explain the idiomatic approach.

3:34 hiredman: use is a global

3:35 callen: what should I use? in-ns?

3:35 hiredman: why do you want to use either?

3:35 don't use any of them like that

3:35 callen: I need to use clj-time.core

3:35 it has a namespace defined

3:35 how do I make my helper function work?

3:35 hiredman: so put a (:use clj-time.core) in your (ns ...) form

3:35 Raynes: You don't. You want to use the namespace in your ns form.

3:36 ibdknox: woah

3:36 Raynes: What's up?

3:36 ibdknox: they used Noir in the 2nd edition of programmin clojure?

3:36 programming*

3:37 callen: Raynes hiredman my naive attempt at doing what you just said failed.

3:37 Raynes: If you makes you happy, I plan to use it in my book as well.

3:37 hiredman: well, learn how to do and do it better

3:37 callen: as you said, it's a global and appears to break other things.

3:37 hiredman: I asked for the idiomatic approach.

3:37 hiredman: read the docs, read some code

3:37 callen: hiredman: I have the pragprog book in front of me.

3:37 hiredman: I gave it to you

3:37 callen: hiredman: and the code.

3:38 ibdknox: callen: the idiomatic approach is to do one of two things

3:38 callen: in your ns declaration (ns my-things.foo ..)

3:38 hiredman: if you failed to make the idiomatic approach work, you need to read more docs, look at more examples

3:38 ibdknox: callen: you can either do :use or :require

3:38 callen: I don't know the idiomatic approach, I just spent half an hour ctrl-f'ing through the book

3:38 why :use instead of use?

3:39 Raynes: Because that's what ns takes.

3:39 ibdknox: callen: in general, if you do use, you want to do it like so (:use [some-thing :only [the-thing-I-need]])

3:39 callen: a new and interesting error that I don't understand.

3:39 clojurebot: error-kit is http://pragprog.com/magazines/2009-07/when-things-go-wrong

3:39 ibdknox: callen: if you do require, you then need to prefix your usages with the alias you give the required namespace: (:require [clj-time.core :as time])

3:40 callen: (:use 'clj-time.core [in-secs interval epoch now]) like so?

3:40 Raynes: callen: We don't even know what your doing. We don't know what your code is, how you're running it, what error you're getting, etc.

3:40 callen: Raynes: I tried to isolate the question so that it wouldn't be necessary.

3:41 Raynes: Isolate the code and show us a small example that is breaking. It'll be easier to help you like that.

3:41 callen: I did print my function.

3:41 ibdknox: callen: (:use [clj-time.core :only [in-sexs interval epoch now]])

3:41 callen: (defn unix-now [] (in-secs (interval (epoch) (now))))

3:41 that's what's breaking

3:41 says in-secs doesn't exist.

3:41 Raynes: Show us the entire file.

3:41 ibdknox: in a gist

3:41 Raynes: Yes.

3:41 gist.github.com

3:41 callen: this is partially mutilated

3:42 in my attempt to follow your advice.

3:42 ibdknox: that's ok

3:42 Raynes: Well, mutilate it less partially and show us the file.

3:42 Or just show us the unmutilated file.

3:42 I'm sure we can take it. :p

3:42 ibdknox: totally can't. I might explode

3:42 Raynes: We need to see how you're using clj-time. Your ns declaration and stuff.

3:42 callen: https://gist.github.com/1335982

3:43 in-secs, interval, epoch, now are all clj-time

3:43 ibdknox: yep

3:43 callen: and are all representative of how the library's documentation instructs itself to be used.

3:43 ibdknox: so you just need what I wrote before

3:43 callen: I tried that.

3:43 ibdknox: (:use [clj-time.core :only [in-sexs interval epoch now]])

3:43 but not sexs

3:43 callen: ibdknox: look dude, it's in the comments

3:43 ibdknox: lol

3:43 no

3:43 you did something entirely different

3:44 look at my form

3:44 and your form

3:44 callen: see it

3:44 trying it

3:44 java.lang.IllegalStateException: Var irc/unix-now is unbound.

3:44 ?_?

3:45 Unable to resolve symbol: in-secs in this context

3:45 still doesn't work.

3:45 updating gist.

3:46 ibdknox: https://gist.github.com/1335982

3:46 ibdknox: you still don't have the same form

3:46 (:use [clj-time.core :only [in-secs interval epoch now]])

3:46 note that there's no apostrophe and that it's all wrapped in a vector

3:47 yours has a quote

3:47 and is missing the vector

3:47 I'm surprised that compiles

3:47 callen: clj-time.core [Thrown class java.lang.ClassNotFoundException]

3:48 (:use [clj-time.core :only [in-secs interval epoch now]])

3:48 it's identical now.

3:48 and it fails with that exception.

3:48 hiredman: ibdknox: please make a note of the location of the closing paren of the ns form

3:48 ibdknox: it needs to be part of your ns declaration

3:48 hiredman: yeah, just noticed

3:49 I will gist exactly what that should look like

3:49 one sec

3:49 https://gist.github.com/1335992

3:50 callen: ^

3:50 callen: I already got it

3:50 Raynes: callen: Unrelated entirely to your project, but if you're doing IRC-related stuff, check out http://github.com/Raynes/irclj sometime. It wont help you if you're just doing this as a learning experiment, but it might be interesting to you in the future. lazybot runs off of it.

3:50 callen: the datetime object is fucked up

3:50 Raynes: love it, thank you.

3:51 ibdknox: thank you for the help, why does the namespace stop before all the func defs?

3:51 ibdknox: I'm taking my cue from code that I'm building upon, but didn't write de novo.

3:51 ibdknox: shouldn't all the defs/defns be part of the ns?

3:51 ibdknox: at least if I'm following the example of other code I've seen.

3:51 Raynes: You *can* use and require namespaces dynamically, but you should almost never want to.

3:51 ibdknox: callen: think of it as setting a marker

3:52 callen: everything after here, until you find another ns decl, or something that resets the marker (like in-ns) is part of this one

3:52 we can't expand macros with the bots can we?

3:52 callen: ibdknox: then how does the reference in the defn which isn't part of the ns have a valid reference to clj-time.core's functions?

3:52 brehaut: Raynes: if ypu are pimping irclj does that mean you are working on it again?

3:53 Raynes: ibdknox: Sure, as long as it isn't bad.

3:53 brehaut: Not at the moment, but I fully intend to partially rewrite it once I've got some time.

3:53 Like, after the conj and I get caught back up with my book.

3:53 ibdknox: callen: because use loads all of the symbols from that other namespace into the current one

3:53 callen: sweet. all my code works now.

3:53 ibdknox: ,(doc refer)

3:53 clojurebot: "([ns-sym & filters]); refers to all public vars of ns, subject to filters. filters can include at most one each of: :exclude list-of-symbols :only list-of-symbols :rename map-of-fromsymbol-tosymbol For each public interned var in the namespace named by the symbol, adds a mapping from the name of the var to the var to the current namespace. Throws an exception if name is already mapped to somethin...

3:54 brehaut: Raynes: fair enough :) if im not busy at the time, i'd be happy to help

3:54 callen: ibdknox: that doesn't make a huge amount of sense to me.

3:54 ibdknox: yeah that's not very clear

3:54 callen: ibdknox: I'm used to python which has a very flat and easy to understand scoping/namespace mechanism.

3:54 Raynes: ibdknox: Not trying to pimp lazybot here, but if you do that kind of thing in lazybot, he gists the truncated output for you.

3:54 ibdknox: oh?

3:54 Raynes: brehaut: That's be great.

3:54 &(range 10000)

3:54 callen: ibdknox: I have no idea why references loaded via :use would be pushed out of an inline namespace into the one above it.

3:54 lazybot: ⇒ (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 ... failed to gist: Connection reset

3:54 Raynes: Well, that's too long.

3:55 But you get the point.

3:55 ibdknox: yeah

3:55 callen: sorry inline namespace?

3:55 callen: the ns ends before the rest of the code

3:55 that, structurally to my limited understanding, looks like it has ceased to be relevant at that point.

3:55 the fact that it can mutate what is accessible in what is outside of it makes little sense to me.

3:55 ibdknox: ##(macroexpand ns)

3:55 lazybot: java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/ns

3:56 ibdknox: ##(macroexpand '(ns))

3:56 lazybot: clojure.lang.ArityException: Wrong number of args (0) passed to: core$ns

3:56 ibdknox: ##(macroexpand '(ns blah))

3:56 lazybot: ⇒ (do (clojure.core/in-ns (quote blah)) (clojure.core/with-loading-context (clojure.core/refer (quote clojure.core))))

3:56 ibdknox: lol

3:56 Raynes: Well, your ns doesn't 'end' until the file is done.

3:56 ibdknox: callen: like I said, it sets a marker

3:56 callen: then why declare the ns?

3:56 Raynes: ns sets the ns for the code.

3:56 Because it sets...

3:56 ibdknox: because you need to know what ns you're in

3:56 lol

3:56 callen: then why do people put stuff inside the ns block if you don't need to?

3:57 * Raynes is not sure how we can explain this better than we currently are, unfortunately.

3:57 ibdknox: you *do* need to

3:57 callen: my code works

3:57 ibdknox: yes it does

3:57 lol

3:57 Raynes: Not that's necessarily your fault for not understanding. Could easily be our fault for failing to explain things properly.

3:57 callen: what changes if I move my defns and defs inside the ns?

3:57 Raynes: The problem is that I'm writing a book, and if I can't explain it...

3:57 ibdknox: I'm not sure, probably something terrible

3:58 callen: after herbert, I don't trust writing a book as a mark of expertise.

3:58 Raynes: The problem is that you think ns does something that it does not do.

3:58 callen: ibdknox: if you can't explain the difference, then how do you know you should do it one way or the other?

3:58 Raynes: I have no idea at all what it does.

3:58 Raynes: The parentheses do *not* indicate the scope of the namespace.

3:58 ibdknox: callen: sorry, are you trying to be jackass now?

3:58 Raynes: ns sets the namespace for the *entire file*.

3:58 callen: I've established that.

3:58 no, I'm not

3:58 I'm actually quite sad and tired right now

3:58 and just trying to understand code that already works.

3:58 ibdknox: perhaps you should sleep

3:59 callen: I won't until I understand this properly.

3:59 you won't be rid of me that easily.

3:59 Raynes: Things might be clearer when the sun rises.

3:59 ibdknox: lol

3:59 ejackson: sleep is my ultimate debugging tool

3:59 callen: Chapter 2.4 "Vars, Bindings, and Namespaces" in the pragprog book doesn't explain it very well, at least from my POV

4:00 ibdknox: as Raynes said, the only thing you really need to understand is that you set the namespace for the entire file

4:00 it's idiomatic to place your uses and requires there

4:00 callen: and as I said earlier, I understood that much.

4:00 I don't understand the point of it yet.

4:00 Raynes: No, I don't think so.

4:01 callen: is it to group everything you're doing in that file into that var?

4:01 ibdknox: no.

4:01 it's to group it in the namespace

4:01 Raynes: Everything you're questioning relies on Clojure setting the scope of the ns to the ns macro's scope itself, which is not the case and thus invalid.

4:01 ibdknox: this isn't actually different from python...

4:01 Raynes: You actually might be looking into it too much.

4:01 callen: I already sdaid I understood that.

4:01 I keep trying to tell you

4:01 ibdknox: haha

4:01 callen: I understand that it sets it well past the end-paren.

4:01 ibdknox: alright man

4:01 callen: I am trying to understand the rest of its purpose.

4:02 ibdknox: You've got it all.

4:02 there isn't one

4:02 Raynes: I'm tired and quite sad right now.

4:02 ibdknox: don't use it :)

4:02 hahaha

4:02 callen: I am trying to explain that I understand a particular iota of the question at hand

4:02 and you keep re-raising the single iota I *do* understand

4:02 and aren't fucking listening to me

4:02 when I say I understand that one bit

4:02 and that we established that earlier

4:02 than you patronize me

4:02 and laugh at me when I try to get you to understand that

4:02 this channel was better a year ago.

4:02 ibdknox: callen: you're antagonizing the people trying to help you

4:03 Raynes: You're raising questions that don't actually exist, I think. I can't tell. Do you actually have a question to ask?

4:03 ibdknox: I'm not sure how much better I can react

4:03 callen: Raynes: I asked earlier and was told they didn't know the answer.

4:03 Raynes: I'll ask again.

4:03 Raynes: The last thing you asked was "what happens if I put the defs in the ns declaration" which makes utterly no sense given what you claim to already understand.

4:03 hiredman: ibdknox: /ignore

4:03 Raynes: We're not trying to patronize you or be mean to you or anything like that.

4:03 We love to help.

4:03 callen: Raynes: currently my ns closes after a :use and an :import. (end-paren)

4:03 hiredman: that doesn't help either.

4:04 hiredman: you're borderline trolling when you publicly declare you're ignoring people.

4:04 Raynes: now, I have my defs and defns after that end-paren, that is, it's not part of the syntactic portion of the ns.

4:04 Raynes: Right.

4:04 callen: Raynes: I understand FULLY that they are going to be in the ns.

4:04 Raynes: What I do not understand is that if I shift it to the syntactic portion of the ns, what it changes, if anything.

4:04 Raynes: in idiomatic Clojure code, it's usually part of the ns body.

4:04 Raynes: such as in clj-time.core

4:04 from what I can tell.

4:04 Raynes: Uh, really?

4:04 callen: Raynes: I am asking why and what it changes if anything.

4:05 Raynes: Can you show me an example?

4:05 callen: Raynes: I could be wrong, let me double-check.

4:05 ibdknox: callen: there's never code aside from :use :require, and a couple others inside of an ns decl

4:05 callen: fuck, no, nevermind.

4:05 Raynes: nope. the way my code is written is idiomatic.

4:05 Raynes: Anyways, I'm not going to ignore people when I still have at least a partial chance at helping them.

4:05 callen: Raynes: nevermind.

4:05 Raynes: I was mistaken.

4:05 Raynes: hence confusion.

4:06 ibdknox: that explains a lot, thank you.

4:06 ibdknox: we tried to clear that up, sorry it took so long.

4:06 Raynes: Nobody here but maybe hiredman actually wants to see people dissatisfied with the help they receive in this channel.

4:06 ;)

4:07 callen: Raynes ibdknox thank you both for tolerating my long enough to eliminate the source of my confusion.

4:07 s/my/me/g\

4:07 Raynes: callen: Anyways, you can probably understand now why it sounded silly to us and like you weren't listening. What you were asking really didn't make much sense at all! If we got snarky, it's because we were probably getting a little frustrated at trying to make sense of it all. If we came off that way, I think I speak for both of us when I apologize for it.

4:08 ibdknox: that's an official record for me: over 12 hours on the HN front page

4:08 /win

4:08 Raynes: Good work./

4:08 ejackson: ibdknox: nice one !

4:09 callen: ibdknox: what'd you post?

4:09 ibdknox: callen: korma

4:09 callen: ibdknox: oh god I am excited about that one!

4:09 Raynes: http://news.ycombinator.com/item?id=3188609

4:09 ibdknox: though in terms of points, http://iwbyp.chris-granger.com got more

4:09 amusingly noir was lower than both

4:10 callen: Raynes: part of the problem is that I am a bit of a lone-wolf and can end up uh... waldeinsamkeit.

4:10 Raynes: God, Noir is so great.

4:10 ibdknox: lol forrest loneliness?

4:10 callen: Raynes: so I come to weird conclusions and misunderstandings that can require a lot of stack-unrolling to get to the bottom of.

4:10 Raynes: Hah. I found a new word.

4:10 callen: ibdknox: lost in the woods.

4:11 Raynes: $trans gr en waldeinsamkeit

4:11 lazybot: Languages not recognized.

4:11 Raynes: Oh yeah, that's broken anyway.

4:11 ibdknox: callen: I know, I speak German :)

4:11 callen: ibdknox: it expresses how I've approach programming, to my chagrin, very well.

4:11 approached*

4:12 I'm quite envious of people that can speak of this or that mentor they had in uni.

4:12 ibdknox: now I kind of feel like I should go buy the programming clojure book

4:12 Raynes: I've never had a mentor.

4:12 ibdknox: neither have I

4:12 I never had a formal CS education

4:12 callen: ibdknox: you mean the book that failed to save me from my own bizarre conceptions?

4:12 Raynes: As a matter of fact, the only time I've ever met another programmer was at a conference.

4:12 Last year, no less.

4:12 callen: ibdknox: ditto. most of my CS background is pirated bibliographies and OCW.

4:13 ibdknox: callen: apparently noir is in the 2nd edition

4:13 callen: ibdknox: been working as a programmer for 5, nearly 6 years.

4:13 ibdknox: whoa @ noir

4:13 Raynes: conj?

4:13 Raynes: Yes

4:13 callen: well I have the log-structured data I wanted now.

4:13 now I can start loading this into a database.

4:14 I might have to write a parser first though.

4:14 yeah, parser first. balls.

4:14 ibdknox: it dawned on me the other day that I'd been programming professionally for just shy of 8 years

4:14 callen: Raynes ibdknox thanks again, I can rest well now. Goodnight.

4:15 ibdknox: which is a bit ridiculous

4:15 Raynes: Night.

4:15 callen: ibdknox: tell that to the junior below me who is one year younger than me and has been working professionally for a few months.

4:15 ibdknox: he finds me bewildering

4:15 ibdknox: I was explaining b-trees and database indexes to him the other day

4:15 ibdknox: said junior has two masters degrees.

4:15 Raynes: I'd hate to see him meet me.

4:16 ibdknox: haha Raynes would eat him for breakfast

4:16 callen: essprain?

4:16 ibdknox: I'm 24.. and I'm old ;)

4:16 callen: I'm 23, and old, and tired.

4:16 Raynes: I'm 17, and mostly just hungry.

4:16 callen: I'm positive the motorcycle is making me older.

4:17 ibdknox: hah and I'm apparently a beowulf cluster lol

4:17 I'm excited to actually meet fogus

4:18 he strikes me as a fun guy

4:18 Raynes: Met him. He's short.

4:18 Fun, but short.

4:18 ibdknox: haha

4:18 callen: lol whut

4:18 Raynes: Shorter than I expected in any case.

4:18 ejackson: old ? you kids.

4:18 callen: <--- audibly cracking up

4:18 ibdknox: ejackson: I meant it sarcastically

4:18 callen: ejackson: I know plenty of 50 year old unabomber types that love Forth.

4:18 ibdknox: ejackson: though compared to Raynes...

4:18 ejackson: well, yes.

4:19 Raynes: I expected some big guy with sunglasses until I nearly stepped on him on my way to my room.

4:19 ibdknox: lol

4:19 he's that short?

4:19 I'm only 5'7"

4:19 Raynes: Well, he is about as short as I am.

4:19 callen: 5' 9" here.

4:19 which is?

4:19 Raynes: Probably around the same height, I think.

4:19 5'5 or so.

4:19 Maybe 5'4.

4:19 callen: that's short

4:19 ejackson: I thought he was a giant green Minotaur...

4:19 ibdknox: huh, you're right, I expected him to be much taller

4:20 callen: ditto.

4:20 ibdknox: alright.. I've been up way too damn long

4:20 callen: me too.

4:20 it's pacific time, but still bad enough.

4:20 I have work tomorrow as always.

4:20 lkgnmdsklfhmdfgh

4:20 ejackson: ibdknox: hehe, I'm just waking up here England time.

4:20 callen: cheers all. It'll be a two-gallon coffee mug day.

4:20 g'night

4:21 Raynes: It is precisely 3:17AM right now.

4:21 ibdknox: ejackson: haha well then, all day to play with Korma ;)

4:21 Raynes: Night boys and girls.

4:21 ejackson: cheers kids :P

4:21 callen: Raynes: That's 1320308288 to you, heathen!

4:22 Raynes: ejackson: Night gramps.

4:22 ibdknox: lol

4:23 ejackson: get off my damn lawn !

4:23 ibdknox: in case anyone is interested: HN/twitter brought in about 5000 viewers to sqlkorma.com

4:23 ejackson: nice stat indee.

4:23 ibdknox: I like looking at where they're from, it always ends up surprising me some

4:24 more than half were outside the US

4:24 ejackson: that's promising

4:25 ibdknox: the UK was the top of the european countries actually

4:25 ejackson: well done

4:25 ejackson: oh, that was me with some perl

4:25 ibdknox: haha user-agent: curl

4:26 damn :p

4:26 alright. I'm outta here. Catch you folks later

4:26 ejackson: later

5:03 Blkt: good morning everyone

8:10 jscott1989: hey, if i want a linked list, so i can maintain an arbitrary order (specifically where i can insert and element at any position) how would i go about that?

8:13 ignore my stupid question

8:13 :)

8:13 solved it

9:11 bpr: is there a way to explore java packages? I'm thinking something like a cross between clojure.contrib.repl-utils/show and clojure.core/ns-*

9:16 scottj: well you can inspect packages in Slime but it doesn't give much that's useful

9:50 clgv: Is there any documentation support for functions with options in clojure yet?

9:50 This is often annoying when you have several layers where the options are passed through.

9:55 dpritchett: Raynes: Really dug the tryclojure on heroku post. Well done.

9:55 cemerick: clgv: beyond enumerating the options in a docstring, you mean?

9:56 clgv: cemerick: that is one good thing. I would go further and try some transitive analysis on the options for function calls that have options as well

9:57 cemerick: clgv: If you enumerate the options in a keyword destructuring form, they'll also show up in (:arglists (meta #'foo))

9:58 FYI: The official unofficial homes of 'Clojure Programming', coming soon from O'Reilly: http://twitter.com/ClojureBook and http://clojurebook.com

9:58 clgv: cemerick: nice url you captured there^^

9:59 cemerick: I also got clojure-book.com and clojureprogramming.com, but I decided to go simple. :-)

10:02 davidrupp: cemerick: Looking forward to buying the ebook. Any idea why it's not available through the normal (non-Safari) Rough Cuts?

10:03 clgv: oh, I didnt know that you shortcut it like that (defn f[x & {:keys [bla blubb]}] ...) to not have to create a hashmap yourself

10:04 but it seems to work on 1.3

10:04 cemerick: davidrupp: No idea, sorry. Are you talking about their direct early access thing? I heard something about it, but have no control/visibility into those sorts of things.

10:05 I can try to beat the bushes on that…

10:05 davidrupp: Yeah, most of their ebooks are available for direct download, no Safari required, even in Rough Cuts.

10:05 Not a huge concern.

10:06 cemerick: You can download it through safari AFAIK…

10:19 clgv: I think about this syntax: (defn+opts f [x] [opt1 [opt2 10]] ...) is this idiomatic or is there a better way to specify the optional params with default values?

10:22 cgray: hi, where do macros go so that the clojurescript compiler can find them?

10:23 kephale: clgv: i'm a little confused by opt1 not having something after it but what about (defn f [x & {:keys [opt1 opt2] :or {opt1 blah opt2 10}}] …)

10:23 clgv: kephale: no, I try to improve that defn statement to something more useful

10:24 kephale: I aim for specifying default values but also being able to omit them

10:25 kephale: clgv: aha cool… one of my complaints about the current approach (although it isn't exactly relevant to this situation) is that the value of :keys is technically implied by the value of :or since everything must have a default

10:26 clgv: hmm but maybe I have to separate it as well

10:29 kephale: or have a single map where you explicitly specify nil for things that don't have defaults, which wouldn't be pretty

10:30 neotyk: Good morning everyone!

10:30 licenser: has anyone managed to get clojure-jack-in work with cake?

10:31 kephale: i think i like the syntax you suggest, but maybe making a bit more uniform with the existing approach: (defn+opts f [x & [opt1 [opt2 10] …] body)

10:31 oops, missing a ]

10:34 clgv: kephale: I dont like the & ^^

10:34 it suggest the other semantic I think

10:34 maybe I introduce a sign for it. should be possible. lets check

10:35 kephale: maybe a pipe

10:35 clgv: or a question mark since they are optional

10:36 kephale: hrm perhaps, though in the case where x is some function predicate that could get confusing

10:36 clgv: kephale: example?

10:36 TimMc: ,(let [| 5] (* | 2))

10:36 clojurebot: 10

10:37 clgv: (defn+opts f [x ? {opt1 9, opt2 10}] ... ) and (defn+opts f [x ? [opt1, [opt2 10]] ... ) looks well

10:38 ok I'll note question mark and pipe

10:38 kephale: (defn+opts f [float? ? options] …)

10:39 clgv: hmm the pipe has more visual impact. thats true

10:39 is it used for anything yet?

10:40 kephale: well apparently TimMc wants to use it as a variable

10:40 clgv: lol, that's no harm - he can continue to do that^^

10:41 my implementation can ignore that^^

10:41 like defrecord uses '& as variable name ;)

10:45 cark: clgv: so you're going to make your own destructuring too ?

10:45 throwing away the good work of our language developers for estetics only ?

10:47 clgv: cark: no I do not. I improve optional parameter handling for my project

10:51 cark: that's a whole cnan of worm you're opening here

10:51 consider this :

10:51 ,(let [f (fn [& {[a1 a2] :a}] [a1 a2])] (f :a [1 2]))

10:51 clojurebot: [1 2]

10:52 cark: there is destructuring going on

10:52 clgv: cark: I do not have to consider this. I guess you did not get my intentions ;)

10:52 cark: recursive destructuring should i say

10:53 ohwell ok =)

10:56 clgv: you recheck when it's ready and I found it stable enough to put it on github ;)

10:58 cgray: has anyone successfully used macros with clojurescript? i'm having trouble getting the compiler to find them...

10:59 PPaul: is there a function that is like project, but returns a set of hash-maps with with all the keys but the ones project was given?

11:00 or do i have to do something like project, and difference?

11:05 Chousuke: PPaul: sounds like you could just use dissoc to remove the keys

11:06 PPaul: yeah, but project works over a set of hashes

11:06 sticking to set stuff while working with sets seems like the right thing to do

11:10 i think i don't need it anyway, oh well

11:10 ^_^

11:20 how do i map over a hash-map... (map first/second {}) works, but when i do (map (fn [key val] val) {}) i get errors related to the num of args passed to the function

11:20 is it because i'm not destructuring?

11:20 (fn [[key val]] val) is what i should use?

11:21 woo, answered my own question

11:28 TimMc: PPaul: Why not use val?

11:29 ,(map val {:a 1, :b 2})

11:29 clojurebot: (1 2)

11:29 PPaul: i want to use both

11:29 TimMc: OK.

11:30 PPaul: i projected, and i want to create a new hash with the projection (it's a compression alg)

11:30 cgray: is there a way to get cljsc to tell me what its classpath is?

11:30 ,(vals {:a 1, :b 2})

11:30 clojurebot: (1 2)

11:31 PPaul: i have a static method that takes in 2 Str args... is this the right sig for it?

11:31 (:gen-class

11:31 :methods [#^{:static true}[statsTransform [String String] void]]))

11:32 also, can i use void return even if it does return something (i'm guessing i can because all clojure functions return)

11:33 licenser: Raynes: you're there mate?

11:47 ljos: What is best practice for writing to file in Cljoure? I

11:48 licenser: ljos: depends on what you want, spit is a very easy way :)

11:48 ljos: I only need easy. Nothing fancy :)

11:49 licenser: that spit is your friend

11:49 ,(doc spit)

11:49 clojurebot: "([f content & options]); Opposite of slurp. Opens f with writer, writes content, then closes f. Options passed to clojure.java.io/writer."

11:50 ljos: Thank you :)

11:50 licenser: you're more then welcome :)

11:51 ljos: Another question. I know this is not excactly best practice, and it sounds like I'm doing things I shouldn't, but is there a way I can capture global variables?

11:52 So if I have (def a 1) (defn retra [] a) (let [a 3] (retra)) I want that to return 3, but let doesn't capture globals.

11:53 dnolen: ljos: you want binding.

11:53 ljsos: and you need to declare a to be dynamic

11:53 (def ^:dynamic a 1)

11:54 ljos: I'm assuming you're using 1.3.0

11:54 ljos: ok. Sweet! And yes I am.

11:55 Thank you.

11:57 PPaul: (:gen-class

11:57 :methods [#^{:static true}[statsTransform [String String] bool]]))

11:57 bool is throwing a compile error

11:57 ljos: binding will only work inside it's own lexical scope right? It won't do stupids things like actually changing the variable for functions outside of the scope that might be running at the same time under other scopes?

11:57 PPaul: what should i use instead (i can't find what options i have in docs or gen-class help sites)

11:58 ljos: its*

11:58 dnolen: ljos: it's dynamic binding. It will change that vars value until it exits.

11:58 any code that is code called within it will see the new value.

11:59 PPaul: nm i have to use boolean (really not familiar with java anymore)

11:59 ljos: dnolen: yes, but if I have code running in parallel, will it see it?

11:59 That is not within the binding.

12:00 dnolen: ljos: dynamic binding is thread local. however threads spawned by the current will also see the new value.

12:01 hugod: assuming those threads are spawned by a clojure core function…

12:01 ljos: dnolen: That was what I asked. So the change won't be global, only within the lexical scope of the binding, right?

12:01 dnolen: ljos: dynamic scope

12:03 ljos: dnolen: ah. I read on what dynamic is vs lexical, I had some missconception of what lexical meant. Thank you for the help. That answered everything really..

12:04 dnolen: ljos: np

12:14 ThreeCups: I'd like to take this map {:a [[0 0] [0 1]], :b [[1 0] [2 0]]} and transform it to this vector [[[[0 0] :a] [[0 1] :a]] [[[1 0] :b] [[2 0] :b]]]. I'm sure there's an elegant way to do it, but I'm stumped

12:20 halfprogrammer: ,((apply map vector ((juxt vals keys) {:key1 1 :key2 2})))

12:20 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn>

12:21 halfprogrammer: ThreeCups: think something like this should work

12:21 ,((apply map vector ((juxt vals keys) {:key1 1 :key2 2}))

12:21 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

12:21 halfprogrammer: ,(apply map vector ((juxt vals keys) {:key1 1 :key2 2}))

12:21 clojurebot: ([2 :key2] [1 :key1])

12:22 halfprogrammer: got it as expected this time :)

12:22 does this serve your purpose?

12:22 ThreeCups: halfprogrammer: Thanks! I think this'll work. Let me give it a try

12:26 Never used juxt before... reading the docs to understand it

12:31 amalloy: ~juxt

12:31 clojurebot: juxt is usually the right answer

12:34 jodaro: i love juxt

12:34 used it for the first time the other day

12:37 technomancy: the biggest problem with juxt is that it's too awesome

12:37 you're always tempted to use it where you shouldn't

12:37 ejackson: a

12:37 spiderman function

12:37 jodaro: you mean like when i go

12:37 (ns ...

12:37 (juxt ....

12:38 scottj: anyone know other lisp dialects that have juxt builtin?

12:38 jodaro: 500 lines

12:38 )

12:38 technomancy: scottj: liskell? =)

12:38 halfprogrammer: ,(mapcat (fn [m] (let [k (key m) vx (val m)] (zipmap vx (repeat k)))) {:a [1 2 3] :b [4 5 6]})

12:38 clojurebot: ([3 :a] [2 :a] [1 :a] [6 :b] [5 :b] ...)

12:39 halfprogrammer: ThreeCups: even this seems to work :)

12:39 ThreeCups: halfprogrammer: thanks again! still trying to wrap my mind around juxt :)

12:40 All functions passed to juxt have to have the same arity, correct?

12:41 halfprogrammer: think the arity is also fixed to 1

12:42 ThreeCups: ,(doc juxt)

12:42 clojurebot: "([f] [f g] [f g h] [f g h & fs]); Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"

12:42 halfprogrammer: ,((juxt + - *) 1 2 3)

12:42 clojurebot: [6 -4 6]

12:42 halfprogrammer: i was wrong :)

12:44 * halfprogrammer juxting ftw

12:44 ljos: Is there a way to use relative paths in spit? I want to do this: (spit "~/newfile" "content of new file") .

12:45 kephale: hurrah for the triumvirate: juxt, comp, partial

12:45 ThreeCups: halfprogrammer: in your first solution, you has this: (juxt vals keys), is that gauranteed to return the vals and keys in the same order?

12:45 technomancy: ThreeCups: it's guaranteed, yes

12:46 pdk: zipmap yo

12:46 halfprogrammer: technomancy: even if the map does not give the guarantee?

12:46 technomancy: halfprogrammer: right, it's deterministic for a single map

12:48 amalloy: ljos: that's not relative, it's absolute with $HOME expansion

12:49 ljos: amalloy: oh.. yeah ofc.

12:49 I'm getting tired.

12:50 amalloy: anyway, you can do it by hand with (System/getProperty "user.home"), or i'm sure there are some libraries out there to make java pretend it's posix

12:50 but normally your shell expands ~, not your filesystem, so java doesn't do it

12:51 TimMc: ,(doc sort-by)

12:51 clojurebot: "([keyfn coll] [keyfn comp coll]); Returns a sorted sequence of the items in coll, where the sort order is determined by comparing (keyfn item). If no comparator is supplied, uses compare. comparator must implement java.util.Comparator."

12:51 TimMc: ,(sort-by #(do (pr %) %) '[5 4 3 2 1])

12:51 clojurebot: 54534352423251413121

12:51 (1 2 3 4 5)

12:52 TimMc: That's disappointing.

12:53 In Ruby you can apparently define shuffle as array.sort_by { rand } because the keyfn (rand) is only called once per index.

12:53 hiredman: clojurebot: what?

12:53 clojurebot: what is moustache

12:53 amalloy: TimMc: it's a tradeoff

12:53 ljos: amalloy: that worked. Thank you.

12:53 TimMc: hrm

12:54 amalloy: suppose the predicate is super-cheap, such as identity. you want to double your storage costs and increase complexity in order to save calling this function?

12:54 whereas clojure makes it trivial to get ruby's behavior

12:54 bobnodes: oh hi

12:54 anyone know of a sandbar replacement?

12:55 amalloy: &(let [f #(do (pr %) %)] (map second (sort-by first (map f ['5 4 3 2 1]))))

12:55 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long

12:55 scottj: bobnodes: noir

12:55 technomancy: ,(sort-by (memoize #(do (pr %) %)) '[5 4 3 2 1])

12:55 clojurebot: 54321

12:55 amalloy: &(let [f #(do (pr %) %)] (map second (sort-by first (map (juxt f identity) ['5 4 3 2 1]))))

12:55 clojurebot: (1 2 3 4 5)

12:55 lazybot: ⇒ 54321(1 2 3 4 5)

12:55 bobnodes: I've spent the last 8 hours trying to make it authorize a simple login form. But this seems completely broken in any recent version

12:55 technomancy: amalloy: beat ya =P

12:56 TimMc: technomancy: Beat me, too. :-/

12:57 amalloy: technomancy: yours doesn't call f at all for duplicate items, which doesn't seem to actually align with the ruby behavior he wanted

12:57 technomancy: hm; yeah I could go either way on that

12:59 amalloy: i guess i could go super-efficient by using pop instead of second :P

13:03 TimMc: amalloy: annotate!

13:03 amalloy: give the man a prize

13:04 TimMc: TimMc: botsnack

13:04 TimMc: Thanks! Om nom nom!!

13:09 pandeiro: ^ amalloy made a much nicer version of my shuffle-by-sort.

13:10 pandeiro: TimMc: i already modified your version to work with cljs but i'd like to take a look, link?

13:10 amalloy: TimMc: i read somewhere that using sort-by rand to shuffle leads to not-very-good shuffling

13:10 so i'm not sure you'd want to do this

13:10 TimMc: amalloy: We were discussing that yesterday.

13:10 amalloy: pandeiro is working in cljs, where shuffle isn't defined.

13:11 pandeiro: (map second (sort-by first (map (juxt rand identity) [5 4 3 2 1])))

13:11 amalloy: TimMc, pandeiro: https://gist.github.com/805546

13:11 TimMc: But use Fisher Yates or Knuth instead.

13:11 amalloy: a functional impl of Fisher-Yates

13:12 with the nice side benefit that it's lazy - you can take only N items out of the front and the rest won't be shuffled

13:14 looking at it again it seems like it would be nicer to implement using lazy-seq directly instead of mapping first over an iterate

13:25 TimMc, pandeiro: updated gist with an impl that is probably more performant

13:28 TimMc: I see a shuffle in there.

13:28 amalloy: TimMc: (fn shuffle ...)

13:28 TimMc: Oh!

13:28 shadowed, got it

13:28 amalloy: $mail fliebel remember back when we were looking at various lazy-shuffle implementations? i finally realized i should be using a transient vector and it's about four times faster than my last impl

13:28 lazybot: Message saved.

13:32 amalloy: $mail fliebel forgot the link! https://gist.github.com/805546

13:32 lazybot: Message saved.

13:35 ThreeCups: ,(into [] {:a 1, :b 2})

13:35 clojurebot: [[:a 1] [:b 2]]

13:35 ThreeCups: Is there a better way to do this?

13:36 duck1123: Is there anything easier than set/difference for removing a value from a set, or better yet, something like a dissoc-in that will work on maps containing sets?

13:36 ThreeCups: ,(vec {:a 1 :b 2})

13:37 technomancy: duck1123: update-in plus disj?

13:37 duck1123: technomancy: disj is what I was missing

13:37 technomancy: yeah. I was a little confused as to why dissoc didn't work on sets at first.

13:38 I think it makes sense since sets aren't associative, but it's a bit surprising at first.

13:39 duck1123: much nicer, thanks

13:45 TimMc: amalloy: Having trouble understanding lazy-shuffle. The innermost "coll" is the remaining elements, right?

13:45 amalloy: yeah

13:45 TimMc: The last line of shuffle... are you doing an exchange?

13:45 amalloy: right

13:46 TimMc: Oh, I get it! You add a random element to the lazy seq, and put the top element in its place.

13:46 amalloy: yes

13:46 TimMc: then pop the duplicate

13:46 Cute.

13:47 ThreeCups: How do I flatten [[1 2] [3 4]] to [1 2 3 4]? (reduce concat [[1 2] [3 4]])?

13:47 chouser: yes, or apply concat or mapcat seq

13:47 amalloy: ThreeCups: strongly prefer not producing [[1 2] [3 4]] in the first place

13:48 gfredericks: amalloy: :D

13:48 ThreeCups: amalloy: one thing at a time :). Thanks for the advice

13:48 amalloy: eg, much nicer to ##(mapcat (fn [[x y]] [(inc x) y]) {1 2 3 4 5 6}) than to ##(apply concat (map (fn [[x y]] [(inc x) y]) {1 2 3 4 5 6})

13:48 lazybot: ⇒ (2 2 4 4 6 6)

13:48 TimMc: for for for

13:48 amalloy: &(apply concat (map (fn [[x y]] [(inc x) y]) {1 2 3 4 5 6}))

13:48 lazybot: ⇒ (2 2 4 4 6 6)

13:49 amalloy: indeed. i always find the for version of the latter somewhat unpalatable though, and it's slower as well

13:50 &(for [[x y] {1 2 3 4 5 6}, item [(inc x) y]] item) ; yuck

13:50 lazybot: ⇒ (2 2 4 4 6 6)

13:54 TimMc: I thought you were all for & juxt these days

13:56 amalloy: it's true

13:59 chouser: 'for' rocks for golfing

14:03 hiredman: I just wish there was something like mapcat for for, you can kind of hack it in, but it's not pretty

14:04 fdaoud: ,(flatten [[1 2] [3 4]])

14:04 clojurebot: (1 2 3 4)

14:05 amalloy: ~flatten

14:05 clojurebot: flatten is clojure.contrib.seq-utils/flatten

14:05 amalloy: ugh

14:05 clojurebot: forget flatten |is| clojure.contrib.seq-utils/flatten

14:05 clojurebot: I forgot that flatten is clojure.contrib.seq-utils/flatten

14:05 raek: ,(flatten [[[1 2] [3 4]] [[5 6] [7 8]]])

14:05 clojurebot: (1 2 3 4 5 ...)

14:06 ibdknox: flatten is one of those scary functions

14:06 raek: ,(apply concat [[[1 2] [3 4]] [[5 6] [7 8]]])

14:06 clojurebot: ([1 2] [3 4] [5 6] [7 8])

14:06 amalloy: clojurebot: flatten |is| rarely the right answer. What if your "base type" is a list? Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

14:06 clojurebot: In Ordnung

14:06 ibdknox: you'll use it, not think about needing to retain a nested collection and then you're screwed

14:07 amalloy: ~flatten

14:07 clojurebot: No entiendo

14:07 ibdknox: lol

14:07 amalloy: hiredman: haallllp

14:08 hiredman: :(

14:10 chouser: amalloy, ibdknox: correct.

14:10 aren't you happy you have my approval? :-P

14:10 amalloy: hiredman: seriously though what did i get wrong there? i know he sometimes gets confused when the factoid has an "is" in there, so i wrapped the first one with pipes to get his attention

14:10 but i'd like to make sure he knows this fact so i can stop crusading

14:11 hiredman: yeah

14:11 ibdknox: chouser: I'm checking that box on my list of things I need before I die :p

14:11 chouser: heh, I bet.

14:11 hiredman: my guess would be you need to escape the following is'es (\is) but the real answer is clojurebot's parser needs an overhaul

14:11 amalloy: ibdknox: chouser will never give you approval to die. you'll be kept alive in a vat, inventing useful new tools

14:12 * ibdknox indulges in his nutrient rich sludge :p

14:12 amalloy: clojurebot: flatten is rarely the right answer. What if you need to use a list as your "base type"? Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

14:12 clojurebot: c'est bon!

14:13 amalloy: in the meantime, i'll just rephrase without "is" :P

14:13 TimMc: flatten?

14:13 clojurebot: flatten is rarely the right answer. What if you need to use a list as your "base type"

14:13 ibdknox: hahaha

14:13 amalloy: ~botsmack

14:13 clojurebot: clojurebot evades successfully!

14:13 ibdknox: ~botsmack

14:13 clojurebot: Owww!

14:13 * amalloy grumbles and goes to fix this in /msg

14:14 amalloy: ~flatten

14:14 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

14:14 chouser: ~for

14:14 clojurebot: for is a loop...in Java

14:15 chouser: ~for

14:15 clojurebot: for is not a loop

14:15 ibdknox: ...

14:15 lol

14:15 chouser: clojurebot: for is complected

14:15 clojurebot: You don't have to tell me twice.

14:15 ibdknox: that seems to be the new word these days :p

14:15 amalloy: chouser: oh boy, tell us about LOOP

14:16 dnolen: clojurebot: LOOP is complect complected

14:16 clojurebot: You don't have to tell me twice.

14:16 * ibdknox 's head explodes

14:17 chouser: though interestingly, 'for' creates a lexical space in which some things can be simpler (not to mention easier) than outside the 'for'

14:18 cgray: amalloy: heh, i was just about to guiltily use flatten before i thought "i'll just have a look at #clojure for a second"

14:18 ibdknox: chouser: hm?

14:19 amalloy: cgray: have you repented?

14:19 accept mapcat into your heart

14:19 cgray: amalloy: indeed, mapcat is really what i wanted

14:20 ibdknox: I've wanted flatten exactly once

14:20 and it was actually the right thing to use

14:20 technomancy: it's pretty trivial to flatten with tree-seq if that's what you really want

14:21 kind of surprised when that got promoted

14:21 ibdknox: it was for my version of that music as data thing: https://github.com/ibdknox/music-as-data

14:21 amalloy: agreed. my guess was that flatten is something that's taught sometimes as an interesting problem and someone wanted to show off that it's easy in clojure

14:22 technomancy: I dunno; for showing off purposes implementing it with tree-seq gets more wows

14:23 lobotomy: wrote another blog post on clojure: http://lobotomys.blogspot.com/2011/11/chess-problem-solver.html

14:23 * amalloy didn't claim his opinion was internally consistent

14:23 lobotomy: this one's a bit long. executive summary: straightforward dfs is straightforward

14:24 technomancy: flatten is literally (partial tree-seq coll? seq), right?

14:24 Raynes: technomancy: Heh, we actually realized we needed to do that in clojail last night. Flatten wasn't flattening maps, so you could bad stuff.

14:24 technomancy: oh, sequential? instead of coll?

14:24 Raynes: &{:foo (eval '(+ 3 3))}

14:24 ibdknox: ,(doc tree-seq)

14:24 lazybot: ⇒ {:foo 6}

14:24 tolstoy: I saw in the Joy of Clojure free chapter something like: (defn [& (keys :foo 1 :bar 2)] …). Is that documented anywhere?

14:24 clojurebot: "([branch? children root]); Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). children must be a fn of one arg that returns a sequence of the children. Will only be called on nodes for which branch? returns true. Root is the root node of the tree."

14:25 Raynes: could do bad stuff*

14:25 amalloy: technomancy: right

14:25 pjstadig: technomancy: wow, you're right that is more readable than flatten :-p

14:25 technomancy: wait, filter complement of sequential? ? dude.

14:25 as pjstadig would say: remove, man.

14:25 =)

14:25 Raynes: tolstoy: http://stackoverflow.com/questions/3337888/clojure-named-arguments

14:25 * Raynes toot toot

14:27 tolstoy: Raynes: Thanks. I guess it's not a canonical technique?

14:27 Raynes: Sure it is. Why wouldn't it be?

14:27 tolstoy: There's not a page on clojure.org. ;)

14:27 ibdknox: hah

14:28 Raynes: I guess it just isn't officially documented. It has been possible for a couple of Clojure versions now.

14:28 tolstoy: I see there's a contrib.

14:28 Raynes: But there are plenty of stuff like that SO post to learn about it.

14:28 tolstoy: Yep.

14:28 ibdknox: huh, I'm surprised there isn't a heading for destructuring

14:28 amalloy: tolstoy: i don't think there's a page on clojure.org documenting that if you want to multiply a number by three you should use (* 3 x), but that's got to be the canonical technique

14:29 ibdknox: it's probably one of most useful, yet least used by new people, things in clojure

14:29 mdeboard: I want destructuring in Python.

14:29 So bad.

14:29 tolstoy: Sometimes I see techniques here and there, and I wonder how I could have found out about them if not randomly searching for something completely different. So, I was hoping there was some secret page I had missed….

14:30 ibdknox: tolstoy: at some level it's a matter of building things on top of the concepts that you know already exist

14:30 amalloy: that's how programming works though. you read source and notice people doing neat stuff that you want to steal

14:30 mdeboard: tolstoy: Reading a couple of good books on the topic is the best way to learn things about new technologies

14:30 tolstoy: amalloy: Ah, come on. I'll not bite. I was just curious if there was a page somewhere that kind of had interesting idioms for typical kinds of things. That's all. I didn't mean to complain or criticize.

14:30 ibdknox: mdeboard: eh, I didn't read any books. I read code.

14:30 mdeboard: amalloy: Eh some techniques are sufficiently advanced that you dont' even know where to begin.

14:30 ibdknox: How long have you been programming with lisps?

14:30 amalloy: mdeboard: for sure, books are good

14:30 ibdknox: mdeboard: this is my first

14:31 amalloy: mdeboard: mine too. started last summer

14:31 * technomancy programs with his fingers

14:31 ibdknox: soooo, 8ish months?

14:31 no

14:31 technomancy: oh, wait did you say "lisps"?

14:31 ibdknox: 10 months

14:31 mdeboard: lithpth

14:31 ibdknox: lol

14:31 technomancy: it's like in the Three Amigos. "We could go for a walk and you could kiss me on the veranda." / "Oh, uh... Lips would be fine."

14:32 mdeboard: ibdknox: It was hard for me to find good projects written with Clojure that provided grokkable examples.

14:32 but I'm a newb to programming in general

14:32 ibdknox: mdeboard: I've been working on that ;)

14:32 mdeboard: technomancy: I program with my face. 1. slam face into keyboard 2. roll 3. ??? 4. Push to github

14:32 ibdknox: I've noticed.

14:32 ibdknox: I have a fun idea that I might try to convince Raynes to help me with

14:33 I want to use Clojail to create a "trynoir"

14:33 amalloy: ibdknox: you should try perl, eh?

14:33 ibdknox: oh god

14:33 I hate perl... even more than I hate PHP

14:33 which is saying something

14:33 Raynes: ibdknox: Sounds like fun.

14:33 Perl 6 is interesting.

14:34 mdeboard: What was the Clojure project that was just on HN a couple days ago? I think cemerick authored?

14:34 Not the SQL DSL

14:34 callen: as a fan of Indian food, I find the nomenclature of that SQL DSL to be pleasing.

14:35 mdeboard: Oh, wait, Python DOES have destructuring, of a sort.

14:36 *args, **kwargs

14:36 Anyway, sorry.

14:37 amalloy: mdeboard: it has tuples and splatting, which does get you a fair chunk of the way there

14:38 mdeboard: amalloy: I'm only familiar with "splatting" in the context of references in C

14:39 Never heard it applied to (not '(C, C++))

14:39 ThreeCups: I have a fn that takes a map and a keyword (fn [m k] ...). I want to either create a new set containing k or conj k into a set that already exists as a value in the map. How could I do this? Or is my old nature imperative style still creeping up?

14:39 amalloy: mdeboard: as i understand it that's what ruby calls the *args construct, and possibly also python? i've never heard of it in C

14:39 sdbo: Does anyone know a particularly good Resque-like backgrounding library for Clojure?

14:39 amalloy: http://stackoverflow.com/questions/2322355/proper-name-for-python-operator

14:39 mdeboard: amalloy: May haev just been a former CS professor's word for it

14:40 technomancy: sdbo: there's this: https://github.com/technomancy/die-roboter

14:40 hasn't seen much real-world usage yet, but it's really simple; only about 100 LOC

14:40 mdeboard: die-bart-die

14:40 technomancy: mdeboard: http://www.cul.de/images/autotoolscg.jpg

14:41 fdaoud: mdeboard: "no one german could be harmful!" ?

14:41 tolstoy: Raynes: Thanks for your pointer. I guess I'm after "restructuring", which led me to: http://blog.jayfields.com/2010/07/clojure-destructuring.html

14:41 mdeboard: fdaoud: nailed it

14:41 fdaoud: :)

14:41 tolstoy: Raynes: I guess I should dip in to Joy of Clojure soonish. ;)

14:42 mdeboard: tolstoy: it's really a great book, only tech book I've ever read straight through like a novel. I mean, until the agents/refs/etc part.

14:42 sdbo: technomancy: that's pretty close to what I was hacking around on building— you just set up the execution context in the worker before calling roboter/work?

14:43 tolstoy: mdeboard: The free chapter pretty much backs up what you say. I've got some pressing problems I'm using Clojure for, but it'll be nice to go back and see how to improve.

14:43 technomancy: sdbo: the execution context meaning database connections, etc?

14:43 fdaoud: mdeboard: +1. It really is tremendously well-written. I wonder who used the word "propensity".. chouser, fogus, or the editor?

14:44 sdbo: technomancy: database connections, namespaces, etc

14:44 technomancy: sdbo: right, pretty much

14:44 mdeboard: tolstoy: I wish I had some problems that were of a nature to warrant solving them with Clojure.

14:45 fdaoud: I don't follow

14:45 technomancy: sdbo: I'm actually working on adding a -main function that you can pass the number of workers you want to set up and things like that

14:46 fdaoud: mdeboard: I was just impressed by the vocabulary. Like in chapter 9, "Newcomers to Clojure have a propensity to hack away at namespace declarations until they appear to work." I admit having to look up "propensity".

14:46 tolstoy: mdeboard: Well, I don't have that. I just do stuff like query mongo, shove data into file, upload, etc, or web apps, or web services.

14:46 mdeboard: tolstoy: Oh, i think I'd get a shoe shoved into inappropriate places if I wrote production code in anything but Python. :P

14:46 tolstoy: mdeboard: But I would really like to see if I can see these tasks in a completely new way.

14:47 mdeboard: fdaoud: Ah

14:47 sdbo: technomancy: this is basically perfect, I think, haha

14:47 tolstoy: mdeboard: Like incoming rabbitmq messages as an infinite sequence, etc.

14:47 mdeboard: tolstoy: Even utilities. Plus it wouldn't be fair. If I got hit by a truck, maintainability of the code base shouldnt' be impacted

14:48 tolstoy: mdeboard: I'm doing our production code in Scala, and all the side-issues (monitoring, etc) in Clojure.

14:49 fdaoud: clojurebot: scala

14:49 clojurebot: {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}

14:49 technomancy: sdbo: the error handling still needs a bit of help, but I think the rest of it is pretty solid

14:49 tolstoy: Hah!

14:49 mdeboard: tolstoy: Ah that's a little more reasonable.

14:50 I think eyes would pop at anythign but Python here.

14:50 tolstoy: I find I really like the type system stuff in Scala (esp. what I can use of Algebraic types). But when I work in Clojure, I don't miss it.

14:50 fdaoud: mdeboard: if you get hit by a truck, don't worry about the maintainability of your code..

14:50 tolstoy: I do miss "linked" actors, though, as a way to manage resources (not necessarily concurrency).

14:50 mdeboard: fdaoud: :P

14:51 sdbo: technomancy: ohhh, does wabbitmq connect to other AMPQ servers? I can't seem to get RabbitMQ running on my cluster

14:51 tolstoy: maintainability: I figure if you can document the interfaces, and keep your apps to single-purpose functionality, someone could just rewrite the thing if they need to.

14:51 technomancy: sdbo: probably, but I haven't tried it

14:52 tolstoy: (But then I'm not writing trading software.)

14:54 sdbo: technomancy: need to run atm, but I'll definitely try this out—perfecto

14:54 technomancy: sdbo: definitely interested in feedback

14:54 kzar: Is there a way to split a decimal number into it's component parts? So for 1.5 I need to get 1 and 5

14:56 amalloy: kzar: uhm. what result do you want from 1.49?

14:56 (my point here is that 1.5 is the same as 1.50000000000)

14:56 kzar: amalloy: Hmm I'm not sure, thing is I need to handle a timezone in decimal. The function I use expects two parameters, hours offset and minutes offset

14:57 mdeboard: kzar: http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/mod

14:57 oh.

14:59 kzar: Oh hang on, how does this sound (int (* 60 (rem offset 1)))

14:59 TimMc: ~XY

14:59 clojurebot: xy is http://mywiki.wooledge.org/XyProblem

14:59 TimMc: hah

15:00 kzar: What are you trying to accomplish?

15:00 jodaro: shot in the dark here, but is anyone using zeromq and clojure?

15:00 kzar: TimMc: Pretty sure I solved it, just tried it out

15:00 amalloy: ~anyone

15:00 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

15:00 technomancy: jodaro: IIRC it's doable but annoying since you have to use some native libs that aren't packaged up nicely

15:01 jodaro: yeah

15:01 i'm through all of that pain, fortunately

15:01 but now i've got new pain

15:01 Raynes: amalloy: Don't be mean. jodaro is mah buddy. <3

15:01 kzar: TimMc: Say 1.5 hours is 1 hour and 30 minutes, so if I do (int 1.5) I get 1 hour and (int (* 60 (rem 1.5 1))) gives me minutes

15:01 TimMc: kzar: Right, but what is this in service of?

15:02 endform: Can anyone tell me the differences between anonymous functions defined with #() and (fn [] ())?

15:02 kzar: I explained above, that's what a function I use needs

15:02 jodaro: sorry, anyone currently active and willing to share

15:02 amalloy: endform: those are the same

15:02 TimMc: kzar: OK. I won't try to dig any deeper.

15:02 amalloy: &'#()

15:02 lazybot: ⇒ (fn* [] ())

15:03 endform: amalloy: I have heard that before, but I get different behavior from them, also when I run `(#()) and `((fn [] ())) the output differs

15:03 amalloy: &(#())

15:03 lazybot: ⇒ ()

15:03 hiredman: () is the empty list

15:03 amalloy: &((fn [] ()))

15:03 lazybot: ⇒ ()

15:03 kzar: TimMc: Javascript offset is given as decimal clj-time offset functions need minutes and hours

15:03 endform: #((Thread/sleep 1000) (+ 1 %)) returns a null pointer exception for me, but the same function written with fn, does not

15:04 amalloy: endform: that's not the same function

15:05 &'#((Thread/sleep 1000) (+ 1 %))

15:05 lazybot: ⇒ (fn* [p1__8621#] ((Thread/sleep 1000) (+ 1 p1__8621#)))

15:05 TimMc: endform: You're trying to call the result of Thread/sleep

15:05 endform: Count your parens.

15:06 endform: TimMc: right, okay,

15:06 TimMc: thanks!

15:06 TimMc: Throw a do in there.

15:06 endform: they differ in that the do is implied then in using the fn form

15:07 TimMc: Sort of...

15:07 endform: i'm not sure if that is the right way of saying that

15:07 TimMc: It's more that a fn accepts multiple forms (and wraps them in a do.)

15:07 amalloy: endform: the () is implied by the #() form

15:07 is how i would describe it

15:07 hugod: jodaro: storm uses zeromq - not sure whether from clojure or from java

15:07 TimMc: &'#(fn [x] x)

15:07 lazybot: ⇒ (fn* [] (fn [x] x))

15:08 TimMc: &'#(fn [x] x x)

15:08 lazybot: ⇒ (fn* [] (fn [x] x x))

15:08 drewr: hugod: from clojure (zilch lib)

15:08 TimMc: hmmph

15:08 licenser: Hi, I have some odd problems with swank/slime lately they refuse to connect and jack-in only gives strange errors like this: http://pastie.org/2805988

15:08 TimMc: Urgh, I see what I was doing.

15:08 &'(fn [x] x x)

15:08 lazybot: ⇒ (fn [x] x x)

15:09 TimMc: OK, right. Quote only reveals reader expansion.

15:09 jodaro: hugod: thanks, looked there (and nathanmarz gave me some tips yesterday)

15:11 tolstoy: licenser: Maybe try 'lein plugin install swank-clojure 1.3.3' on the command line?

15:11 * licenser tries that

15:11 endform: TimMc: do you know where #() is documented? I cannot find it for the life of me on clojure.org

15:12 licenser: tolstoy: so I usually use cake :P that does not make things better I know

15:12 oh at least a longer struck trace :D

15:13 gregh: endform: http://clojure.org/reader under Macro Characters

15:13 jodaro: endform: http://clojure.org/reader#The Reader--Reader forms

15:13 woops

15:13 repost

15:13 endform: radical

15:13 devn_: cowabunga dude.

15:14 licenser: tolstoy: thanks that really got me a step ahead :)

15:14 tolstoy: licenser: The other day I had the problem of starting Emacs via the OSX Doc, and it couldn't find lein in /usr/local, so had to add some stuff to my .emacs file. It all seems simple *after* technomancy helps you. ;)

15:15 devn: Anyone going to the conj smart enough to reserve a hotel for the 9th want to split the cost?

15:15 licenser: teehee

15:15 devn: I just reviewed my reservation and for some reason I thought it'd be a great idea to get a room for the 10th and 11th.

15:15 *facepalm*

15:17 licenser: java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (internal.clj:1) isn't exactly good right?

15:17 callen: devn: I dunno man, that kind of stupid might be infectious.

15:17 devn: what if I catch something? :\

15:18 amalloy: licenser: mismatched binary versions usually

15:18 licenser: oi mismatched binary version? How does that happen o.O?

15:19 amalloy: compile against 1.2 and run against 1.3?

15:19 licenser: ahha sneakuy

15:23 devn: callen: haha

15:24 callen: if the worst kind of stupid I can pass on is sucky calendaring I think I'm in pretty good shape

15:25 gfredericks: okay, I'm sitting down and trying to tackle this 'unbound fn' problem now

15:27 licenser: I start to think clojure hates me because I betrayed it with erlang :(*

15:27 gfredericks: erlang: finally a syntax everyone can agree on.

15:27 Bronsa: is it normal for lein uberjar to take likely a minute to complete?

15:28 *like

15:28 gfredericks: Bronsa: sounds typical to me. Something about cramming all the jars together.

15:28 Bronsa: ok

15:28 gfredericks: lein jar is usually much faster

15:28 Bronsa: let's try

15:28 indeed you're right

15:29 gfredericks: I've just learned to not want to make uberjars every 5 minutes

15:30 maven usually has better ways to do things

15:30 amalloy: gfredericks, Bronsa: uberjar AOT-compiles all your dependencies

15:30 Bronsa: woah,.

15:31 that explains a lot

15:31 licenser: oh it really does, lein swank crashes, cake swank hangs when emacs connects

15:31 amalloy: because your main ns needs to be aot-compiled, which means its dependencies do too

15:32 gfredericks: amalloy: now I know!

15:33 zerokarmaleft: gfredericks: wrt erlang => http://i.imgur.com/eXSQf.png

15:34 gfredericks: zerokarmaleft: :) classic

15:34 jodaro: heh

15:35 licenser: aha found the crulpit

15:36 clojure-contrib is version 1.1.0 and clojrue 1.2.0

15:38 Raynes: licenser: If you're using cake from the develop branch, it also supports clojure-jack-in now.

15:38 devn: Anyone here play with protoge?

15:38 protege*

15:39 gfredericks: devn: yes.

15:39 * gfredericks tries really hard not to say "~anyone~

15:40 gfredericks: s/~anyone~/~anyone"

15:40 licenser: Raynes: that is good to know :)

15:40 gfredericks: (dvorak-type)

15:40 s/type/typo

15:40 * gfredericks gives up

15:45 cemerick: mdeboard: did you find what you were looking for?

15:46 mdeboard: cemerick: I was just trying to remember what the project was (of yours?) that was on HN a couple/few days ago. Not the SQL DSL

15:47 cemerick: mdeboard: all my public open source stuff is at https://github.com/cemerick FWIW

15:47 mdeboard: Maybe I'm misremembering

15:49 licenser: is there a way to do a soft dependence with maven? like saying "If you have clojure contrib, please take 1.2.0"?

15:54 cemerick: licenser: that's an optional dependency

15:55 licenser: cemerick: then clojure should have clojure contrib in the right version as a optional dependencie

15:56 cemerick: hrm, that's a fair point

15:56 hiredman: meh

15:56 licenser: yup

15:56 hiredman: clojure doesn't depend on contrib in anyway

15:57 cemerick: it's water under the bridge at this point anyway

15:57 licenser: hiredman: but it crashes if something else does :P

15:57 cemerick: hiredman: but there's nothing wrong with libs limiting minimum versions of known downstream dependents

15:57 licenser: there is no "clojure-contrib" anymore, anyway

15:58 hiredman: licenser: right, if you do the wrong thing, it crashes

15:58 so just stop doing that

15:58 licenser: hiredman: not me, someone else did

15:58 hiredman: whoever

15:59 licenser: what happened is that one dependencey required clojure-contrib and meven/lein figured to get 1.1.0 while the project uses 1.2.0 of clojure

15:59 hiredman: I understand

15:59 licenser: so if there are optional dependencies and it is known that clojure 1.2.0 does not work with contrib < 1.2.0 why not put it in

15:59 they are from the same 'distributor' in the end

16:00 TimMc: I don't see how it could hurt.

16:00 cemerick: it doesn't, but it also isn't relevant anymore

16:00 licenser: I mean I understand that you don't put a random library like that

16:00 cemerick: yes it is a lot of libraries require old versions

16:00 TimMc: cemerick: Wishful thinking.

16:01 licenser: it isn't if you have SOTA clojure and all your libs do the same ;)

16:01 cemerick: Well, we can't go re-release clojure 1.2.0 with different dependency info.

16:01 TimMc: Why not?

16:01 licenser: of cause but perhaps 1.2.1 ^^

16:01 TimMc: Oh, I see -- not that exact version.

16:01 licenser: or 1.3.1 then

16:01 hiredman: SOTA?

16:01 cemerick: 1.3.x has nothing to do with clojure-contrib at all

16:01 licenser: State Of The Art :)

16:03 TimMc: cemerick: ...and everything that uses 1.2 probably explicitly asks for 1.2.0 or 1.2.1, instead of the awkward [1.2.0,1.3.0)

16:03 licenser: cemerick: still it cranes if a old version of c.c is present

16:04 well the point of it is c.c 1.1.0 seems to be incompatible with 1.2.0+ since a lot of old libs require 1.1.0 it would be nice to have clojure be aware of this and block it :)

16:04 cemerick: licenser: except that would require changing your clojure version to, what, 1.2.2? Might as well require c.c [1.2.0] and be done with it?

16:05 TimMc: technomancy: Can we have leiningen turn 1.2.* into [1.2.0,1.3.0) in deps? :-)

16:05 cemerick: :-O

16:05 * cemerick wishes there was a hair-on-fire emoticon

16:05 licenser: cemerick: for me yes I did that already and am fine I just expect that I am not the only one that runs into this problem and learns the hard way what the cryptic error message java throws on you means

16:05 TimMc: I'm guessing the latter syntax is a Maven-ism.

16:06 gfredericks: are there any common gotchas with maven and SNAPSHOTs?

16:06 licenser: also c.c 1.2 does the same with clojure 1.3

16:06 as in crash

16:06 hiredman: snapdon't

16:06 cemerick: TimMc: also a lein-ism as long as no one attempts to reinvent dependency resolution and repositories

16:06 licenser: so I think binding the contrib version within clojure is a bad idea

16:07 at least I don't see any reason why it would do any harm

16:07 gfredericks: hiredman: so when you work on several maven projects simultaneously, you just version-bump every time?

16:07 licenser: I mean about 10 second of work on the pom of clojure, saves generations of clojuruans the trouble to learn that including libraries means better double check that they don't depend on a old version of contrib

16:07 hiredman: gfredericks: I think I would just cry a lot

16:08 TimMc: hiredman: That's reassuring.

16:08 hiredman: move to lein, use checkout dependencies

16:08 cemerick: bleh

16:08 only helpful if you own the world

16:08 gfredericks: I'm not sure that'd go very well with this java project

16:08 licenser: hiredman: I use lein, it downloaded the wrong c.c happily and crashed in my face with 200 lines of java excpetions

16:08 gfredericks: which depends on my clojure project

16:08 cemerick: gfredericks: what problem are you having in particular?

16:09 hiredman: licenser: wah wah wah

16:09 TimMc: licenser: He was responding to gfredericks re: lein

16:09 hiredman: cemerick: how so?

16:09 gfredericks: cemerick: I keep doing "lein deploy" with my snapshotted project, but my java project keeps building with the same old jar

16:09 licenser: hiredman: You failed to produce any argument just play nay-sayer, mind to explain why?

16:09 gfredericks: cemerick: I can even see in my ~/.m2 that the new jars are comming in with their timestamped names, but the generic jar is still the old version

16:09 licenser: TimMc: ah sneaky :) sorry hiredman

16:10 cemerick: gfredericks: is the Java project using maven?

16:10 gfredericks: cemerick: yeah

16:10 cemerick: It'd try running `mvn -U …` (which will update all snapshot versions).

16:10 gfredericks: cemerick: it's building a war, so I can easily crack it open to see what it included

16:10 cemerick: will try that now

16:10 cemerick: if that doesn't work, nuke the relevant subdirectory in ~/.m2/repository/whatever, and try again

16:11 hiredman: checkout dependencies require…a checkout

16:11 hiredman: licenser: because clojure doesn't depend on contrib? so why would marking it as a dependency make any kind of sense? it is semantically incorrect, you are trying to hack around a problem without solving it by smashing a square peg into a round hole

16:11 cemerick: right, which if you are hacking on several projects at once you have

16:11 cemerick: if I want to use head of some library I'm not working on, then I need to go clone its repo. Not fun.

16:11 gfredericks: cemerick: yeah, that's definitely my backup plan. I'd like it to work properly though, not hackily.

16:12 licenser: hiredman: I see that point that is why I suggested a (how I now learned it is called) optional dependencie

16:12 cemerick: hiredman: right, if *I'm* hacking on the projects in question. Doesn't help if someone else is hacking, and I want to benefit from the hacking without futzing with having their repo.

16:12 hiredman: cemerick: right, but you can then commit and push your changes

16:13 cemerick: gfredericks: it is unfortunately a fact of life that .m2/repository needs flushing every now and then. That's gotten quite a bit better now that aether is maturing, FWIW.

16:13 hiredman: licenser: "dependency" clojure does not depend on clojure-contrib, so even if the result is the effect you want, a solution that ends up marking it as so is incorrect

16:14 cemerick: hiredman: commit to what? If I'm following foo's HEAD, and I'm not involved in the development of foo, then using snapshots I don't have to have a clone of foo (and update my clone of foo, and bar, and baz, whenever they have changes).

16:14 gfredericks: cemerick: the -U seems to have made a difference. I'll add that in, thanks.

16:15 cemerick: checkout deps are a great solution for a single developer, but hardly a general solution

16:15 hiredman: cemerick: hacking on several projects at once implies making changes to several at once

16:15 licenser: hiredman: sorry that is just words that you argue, having named it 'things-that-are-relavant-for-this' just would have not sounded so good as dependencies

16:15 cemerick: hiredman: that's not the only use case of snapshots

16:15 hiredman: cemerick: correct, but is the case gfredericks asked about

16:15 hugod: gfredericks: zi can do checkout dependencies for maven projects, but unfortunately relies on fixes in maven post 3.0.3

16:15 cemerick: gfredericks: should only be necessary when you see things not updating properly; using it all the time will not do friendly things to your build time :-)

16:16 gfredericks: cemerick: :/ I'd hate to have to always check

16:16 my goal here is to automate everything

16:16 I prefer slow to inconsistent

16:17 licenser: anyway since it won't happy anyway I just give it up

16:18 * gfredericks heads out

16:19 srid: can (fn [a [o b]] (o a b)) be shortened any further?

16:20 mdeboard: .

16:21 chouser: srid: in some contexts you could almost replace that with ->

16:21 srid: a and b are numbers, and o is one of the math operators

16:22 this is http://www.4clojure.com/problem/135 btw

16:22 hiredman: bleh

16:22 * srid is trying to get past code golf sore 50

16:22 chouser: Is this new?

16:22 srid: yea

16:22 hiredman: isn't there a #clojure-golf channel or something?

16:22 chouser: heh

16:23 TimMc: it's called #4clojure

16:24 amalloy: ~rimshot


16:25 licenser: I suppose it should really be that clojure-contrib 1.2 declares a dependency on clojure 1.2.

16:25 What was I thinking...

16:26 licenser: TimMc: so that would mean that when releasing c.c 1.2 you already know that 1.3 will be incompatible but yes that would be the better way

16:27 cemerick: If only we had a time machine?

16:27 hiredman: I do

16:27 but I get messages about corrupt backups at least once a month and have to start over, drives me nuts

16:28 licenser: on a bigger scale libraries requiering outdated things can be pretty scary especially if they are not explicit about it what would be the best way to handle this?

16:28 TimMc: cemerick: When you were saying something about "lein-ism", were you saying that that syntax is native to leiningen, or that notion of version ranges is?

16:28 hiredman: avoid those libraries

16:28 TimMc: ugh

16:28 cemerick: TimMc: lein inherits nearly all of the dependency resolution semantics of maven (necessarily so), including version ranges.

16:28 brehaut: hiredman: my time machine did the same for about 3 months, and then the disk died completely

16:29 hiredman: :(

16:29 licenser: that is a rather harsh way but yes it would solve the problem

16:29 TimMc: cemerick: Semantics, OK. But not syntax, surely!

16:29 cemerick: TimMc: insofar as version numbers are strings, yes

16:29 TimMc: Hrm.

16:29 * licenser got his time machine working on a sweet raidZ of 4 2TB disks :D

16:29 cemerick: The syntax is not really problematic. The semantics are more questionable.

16:30 [5,12) isn't exactly unprecedented, etc

16:30 srid: ,(-> 3 (- 1))

16:30 ,(#(-> % %2) 3 '(- 1)) ;; fail

16:30 TimMc: cemerick: I was sure that Maven would represent it as <version><lower include="true">1.2.0</lower><upper include="false">1.3.0</upper></version>

16:30 cemerick: heh

16:30 TimMc: but I gues even the XMLers have a limit.

16:31 hiredman: licenser: you are saying "I want to use library x, but it's dependecies are outdated" and I am saying "well then you cannot use it" and you are responding with "but I really want to"

16:31 licenser: hiredman: nah I say is there a way to make it better

16:31 brehaut: TimMc: youd think so would you…

16:31 srid: chouser: how would you wrap -> that in anonymous function?

16:32 licenser: hiredman: I mean it might be that there is a super simple way I just don't know about :P

16:32 TimMc: srid: -> is a macro, it is a syntax transformer

16:32 he comes, etc.

16:33 licenser: but since none went "oh that again, just do lein show-me-where-the-outdated-contrib-comes-from I guess something else is wrong

16:33 hiredman: the only real correct answer is the library needs to be brought up to date in it's dependencies, or you need to log yourself to its dependencies

16:33 either of which can have large repercussions

16:34 TimMc: ,(println "You OK, clojurebot?")

16:35 licenser: I really want the result to be "No."

16:35 chouser: srid: yeah, I don't see how.

16:35 srid: in general, ` (fn [a [o b]] (o a b)) ` can't be shortened using anonymous functions?

16:36 TimMc: srid: Which 4clojure problem?

16:36 srid: 135

16:36 licenser: hiredman: okay perhaps my approach was wrong. How about making it easier to find those problems or prevent them from crashing in a strange java stack trace that no normal person understand (save for those who had the problem themselves or wrote clojure ;)

16:36 TimMc: licenser: The exceptions are a problem for sure.

16:37 Or maybe there should be a lein troubleshoot plugin!

16:37 hiredman: licenser: a. don't aot unless you are absolutely required b. educate your self, java stack traces are very informative, learn to read them

16:37 TimMc: "It looks like you have incompatible versions of those libs."

16:37 hiredman: Nonsense, there's some crazy shit in those traces, you're just used to it.

16:37 hiredman: b. is really a must for anything

16:38 licenser: even so I figured out how to get me a dependence tree I don't see where contrib 1.1 comes from

16:38 TimMc: They may have gotten better, but they're still mystifying on many occasions. Especially certain syntax errors.

16:38 hiredman: languages are just another abstraction, they can an do break, and you depend on them, so treating them as a black box is dumb

16:38 amalloy: chouser: hah, what a funny way to solve that problem

16:39 srid: ? you stalking people's solutions?

16:39 hiredman: licenser: I don't recall the intermediate debugging steps you went through, but the first cause you mentioned does not indicate that something is pulling in contrib 1.1

16:39 dakrone: b

16:39 amalloy: srid: http://www.4clojure.com/problem/solutions/135

16:39 srid: hmm. not looking, until i compress my solution

16:39 hiredman: it means that some library was aot compiled against some other version of clojure, that was not abi compatible

16:40 arohner: licenser: lein pom && mvn dependency:tree | less

16:40 licenser: hiredman: I know but someone here explained that, the stack trace: http://pastie.org/2806452 indicates that I use clojure 1.3 with something that is compiled for clojure 1.2

16:40 which was pretty close, I use clojure 1.2 for something - that for some reason is compiled with clojure 1.1 namely clojure-contrib 1.1.0

16:41 amalloy: srid: want a hint?

16:41 licenser: now I don't require contrib at all but something does so I went to put 1.2.0 in fixed - solved the crash

16:42 now I did more or les what arohner said to trace down which library is the one that requires 1.1.0 - answer is, none - my core project does

16:42 arohner: is there a function for 'or'ing a bunch of predicates together? #(or (foo? %s) (bar? %s)) -> (magic-fn foo? bar?)

16:43 hiredman: some

16:43 licenser: http://pastie.org/2806467 would be the dependence tree

16:44 amalloy: clojure 1.3 adds every-pred or something like that

16:45 ThreeCups: I'm trying to write a function that take a 2-d matrix of maps and updates a particular map. The function takes a matrix, coords (two ints in a vector), a fn that takes a map and other args, and the other args that are passed to fn. The definition is like this:

16:45 (defn update-cell [matrix coords f & args] (update-in matrix coords f args))

16:45 amalloy: &(#(list % %&) 1 2 3 4) ; sric

16:45 lazybot: ⇒ (1 (2 3 4))

16:45 ThreeCups: But I'm having trouble with args and getting them through to the fn call. I get this error: java.lang.IllegalArgumentException: Wrong number of args (2) passed to: user$eval137$fn (NO_SOURCE_FILE:0).

16:45 If I take out args, then everything works fine, but I want to be able to pass in optional args. Any tips?

16:45 amalloy: ThreeCups: (apply update-in ...)

16:45 TimMc: chouser: Nice! (looking at solution)

16:46 brehaut: i was going to be productive today, and now you all have me trying to solve 4clj problems.

16:46 licenser: aha found the bugger

16:46 ThreeCups: amalloy: Thanks! it worked great

16:49 srid: amalloy: btw, is that (% %&) that hint? i didn't know of this implicit destructuring before. (don't need hint yet)

16:49 amalloy: srid: yes, that was all

16:49 chouser: TimMc: heh, thanks.

16:49 srid: oh ok. and recur is allowed in anonmy functions?

16:49 amalloy: srid: try it and see?

16:50 cgray: in clojurescript, it appears that you can't have a function with the same name as the namespace. is this a bug?

16:50 srid: &#(if % (recur (dec %)) %) 5)

16:50 lazybot: ⇒ #<sandbox6471$eval8674$fn__8675 sandbox6471$eval8674$fn__8675@17019f7>

16:50 srid: that hung my repl; restartring ..

16:50 ibdknox: cgray: it is an issue that has come up before, but I thought someone fixed it

16:51 srid: ,(#(if (pos? %) (recur (dec %)) %) 5)

16:51 cgray: ibdknox: ok

16:51 amalloy: srid: clojurebot is down for the count atm, i think

16:51 devn: :(

16:51 I can play clojurebot...

16:51 TimMc: haha

16:51 devn: ~botsmack

16:52 slowbot

16:52 devn: => 0

16:52 srid: ^

16:52 TimMc: srid: ##(#(if (pos? %) (recur (dec %)) %) 5)

16:52 lazybot: ⇒ 0

16:53 srid: devn: ,(loop [x 1] (recur x)

16:53 TimMc: lazybot is alive

16:54 amalloy: Did you change something about lazybot's eval responses? I get a "?" now instead of an arrow.

16:54 ibdknox: TimMc: utf?

16:55 hiredman: amalloy: did someone do something that locked up clojurebot? down for the coutn how?

16:55 cgray: ibdknox: it looks like the issue is still there... i just updated to the latest github version

16:55 TimMc: ibdknox: Shouldn't have changed since like last week, at least not on this computer.

16:55 Raynes: TimMc: Nothing has changed.

16:55 &(+ 3 3)

16:55 lazybot: ⇒ 6

16:56 TimMc: hrmf

16:57 Raynes: ,(+ 3 3)

16:57 clojurebot: 6

16:57 Raynes: ~botsnack

16:57 clojurebot: Thanks! Can I have chocolate next time

16:57 Raynes: Sure.

16:58 TimMc: The last sign of life had been 14:57 < amalloy> ~anyone

16:58 devn: srid: Still working on your query...

16:58 srid: buggy bot. that's a syntax error!

16:58 TimMc: srid: Not for lazybot.

16:59 &(+ 1 2

16:59 lazybot: java.lang.RuntimeException: EOF while reading, starting at line 1

16:59 TimMc: o\__/o

16:59 Raynes: TimMc: We got rid of that.

16:59 TimMc: OK.

16:59 Why?

16:59 clojurebot: TimMc: because you can't handle the truth!

16:59 Raynes: It used fnparse which is a bit of an abandoned project and we needed to update to 1.3.

16:59 Or, I wanted to update to 1.3 in any case.

17:00 TimMc: Aha.

17:00 Raynes: But I absolutely want it back if someone wants to do it in some other way.

17:00 TimMc: Are there any cljs eval bots around?

17:00 Raynes: (while EOF (add-parens))

17:00 Raynes: http://github.com/flatland/lazybot <-- src/lazybot/plugins/clojure.clj if anybody wants to give it a shot.

17:01 lazybot can do Haskell, Clojure, and JRuby.

17:01 No cljs.

17:01 amalloy: TimMc: well, it used to handle (let [x (inc y] x)

17:01 srid: (eval (-> a b)) --- is it possible to resolve `a` and `b` before the the form is passed to `eval`?

17:01 amalloy: which your strategy is not so good on

17:01 Raynes: And the jruby isn't allowed at the moment because I haven't bothered adding JVM sandboxing (which I can do fairly easily with clojail).

17:01 But Haskell certainly works.

17:02 $he 2 + 2

17:02 lazybot: ⇒ 4

17:02 TimMc: srid: For-kludge-er won't take eval.

17:02 srid: hmm

17:04 TimMc: unless you're clever about it

17:04 Not golf-friendly-though.

17:05 s/y-/y /

17:07 devn: bahaha, srid: You are a jerk. I forgot about that REPL and my computer just started to get awfully loud.

17:10 cemerick: FYI: http://mostlylazy.wordpress.com/2011/11/03/coming-soon/

17:11 licenser: Raynes: :D long time no see

17:11 Raynes: Indeed.

17:11 How have you been?

17:12 licenser: good good :) got a new server, lots of fun and experience in setting stuff up, a actual work related clojure project which is darn awesome to have and my gf is spending a month with me :D

17:12 how about you?

17:12 TimMc: whelp

17:12 Raynes: I'm fantastic. :)

17:12 TimMc: devn: It turns out that (loop [] (future (loop [] (recur))) (recur)) is a terrible idea.

17:13 licenser: glad to hear ^^

17:13 devn: haha

17:13 TimMc: I'm on another computer now...

17:13 devn: licenser: yeah, where have you been?

17:13 licenser: I read your blog and noticed that you moved try-clojure to heroku, should I changed to try-clojure.org domain?

17:13 Raynes: Naw, I've got a redirect up.

17:13 licenser: devn: hiding under a pile of Hardware related work and some erlang coding

17:13 Raynes: It's all good.

17:14 licenser: :)

17:14 Raynes: The primary domain is tryclj.com now anyway.

17:14 licenser: kk

17:14 TimMc: My computer is now a space heater.

17:14 licenser: sweet TimMc :)

17:15 Raynes: TimMc: I take of my pants, fold my legs, and sit with my laptop in my lap to keep warm in the winter.

17:15 off*

17:15 TimMc: Raynes: And run a linear fork bomb?

17:15 Raynes: Right, yes.

17:15 licenser: heh

17:15 TimMc: 'cause that's what I just did.

17:15 And I have 8GB of RAM, so fuck me. Stupid Java process won't die for a while.

17:16 licenser: TimMc: neat, I tried that once to see if OSX fixed the "bug" in bash :P

17:16 for the record, they didn't

17:16 devn: licenser: cool, I just started working on the Manning Erlang and OTP book

17:16 licenser: yea that got me hooked, it is really good

17:16 if you ever are interested to look at some code, I've a darn interesting project in erlang

17:16 devn: the guy was like "that is not a beginner book, but it is a great book"

17:17 so i immediately purchased it. beginner books are a bummer.

17:17 90 pages of what an array is.

17:17 licenser: I would be delighted to. :)

17:17 brb

17:17 licenser: cool cool

17:20 ibdknox: technomancy: ping?

17:21 technomancy: ibdknox: what are the haps

17:22 ibdknox: technomancy: would you be interested in version of lein new that used a lib designed to spit out project structures?

17:22 technomancy: ibdknox: yeah, there's a "lein spawn" plugin that does that

17:23 callen: anybody going to the clojure meetup in SF tonight?

17:23 technomancy: I'd be interested in mainlining it or (something like it; I haven't looked at it much) for 2.0

17:23 oops, paredit slurp that or in

17:23 ibdknox: technomancy: excellent. There's a good chance Raynes or I might build such a lib.

17:24 technomancy: have you evaluated spawn?

17:24 ibdknox: if that one doesn't look good

17:24 was supposed to be on that sentence

17:24 Raynes: I'm looking at it now.

17:25 I think we'll have to put some work into taking the Leiningen stuff out.

17:25 I need this to work for both cake and leiningen.

17:25 But it looks good so far.

17:25 cgray: is there an equivalent to the int function in cljs?

17:26 ibdknox: cgray: (js/parseInt)

17:26 licenser: Raynes: out of curiosity how does the cake dev version handle jack-in?

17:26 Raynes: licenser: The same way leiningen does, for the most part.

17:28 licenser: what I mean is if I do clojure-jack-in how does it decide weather to use cake or lein?

17:35 callen: whether

17:36 Raynes: licenser: Ah, you have to set the command it uses.

17:36 (setq clojure-swank-command "cake jack-in %s")

17:36 That ought to do it.

17:37 * technomancy has the table staked out for the seajure meeting

17:38 technomancy: any seattle folk are welcome to swing by early =)

17:38 licenser: Raynes: sneaky :) thanks.

17:39 Raynes: That isn't documented yet because the next version of clojure-mode will define clojure-swank-command as a defcustom so that it can be edited using the Emacs customization interface. Also, cake jack-in isn't in a release yet, so I didn't want to confuse people.

17:40 replaca: callen: I'll be there. You?

17:40 licenser: Raynes: I see I see :)

17:40 callen: replaca: it was between clojure and django, I'm going to the clojure one instead. so yeah, I'll be there. I work nearby weatherbill.

17:41 licenser: also reading your blog I found it curiose that you dived into the topic of media servers as well :)

17:41 technomancy: is weatherbill hosting?

17:41 callen: da.

17:41 technomancy: cool

17:41 ThreeCups: Is there a way to get around reduce's need for it's fn argument to take 2 args? I'd like to pass in more than 2.

17:41 technomancy: one of their Seattle employees is a regular up here

17:42 callen: they seem to be prolific in general.

17:42 cgray: ThreeCups: just put them in a vector and destructure it in your fn

17:43 ThreeCups: cgray: Thanks, was hoping for a different solution, but that will work. I don't really like it because the optional arg is required.

17:44 That means I have to write my function like (defn [a b & c] ...) and c is required by the fn

17:44 cgray: ThreeCups: no, i meant something like (defn foo [[a b] c] ...)

17:45 and it should return a vector of two values

17:45 replaca: callen: cool. I work close too, so it's a great location.

17:45 ThreeCups: cgray: okay, that makes sense. let me give it a try...

17:46 replaca: callen: see you there

17:46 callen: replaca: indeed. My name's Chris btw.

17:46 replaca: callen: And I'm Tom

17:46 ThreeCups: cgray: I don't understand the the "and it should return a vector of two values"

17:47 I'll have a look at the reduce source and that will prolly answer my confustion

17:47 cgray: ThreeCups: reduce calls the fn repeatedly with the last thing you return and the next thing in the list...

17:50 technomancy: so, any ideas why I can access a postgres db just fine on the command line but not via jdbc? the DB is owned by a postgres user with the same name as my unix user, which means I shouldn't need a password, but c.j.jdbc freaks out claiming the server requires a password.

17:50 (side note: this is why people are nuts about nosql)

17:50 clojurebot: 'Sea, mhuise.

17:50 technomancy: ~botsmack

17:50 clojurebot: clojurebot evades successfully!

17:50 technomancy: ...

17:50 clojurebot: forget (side note: this |is| why people are nuts about nosql)

17:50 clojurebot: I forgot that (side note: this is why people are nuts about nosql)

17:51 * technomancy can't remember the last time he successfully botsmacked

17:51 hiredman: postgres somtimes decides to be whacky and do auth via identd

17:52 gfredericks: okay, I have now ceased getting unbound fn errors and am now getting an error about one of the generated fn classes not being found

17:52 the exception relates to a class ending in "$iter__94__98$fn__99", while when I examine the jar the relevant class has slightly different numbers

17:52 hiredman: sounds like you are mixing aot and classloader wonkyness

17:53 gfredericks: I bet so :/

17:53 hiredman: oh, no

17:53 technomancy: oh ffs

17:53 ident sameuser only works using unix domain sockets

17:53 hiredman: thats not it, you should clean out your classfiles

17:53 technomancy: that's it. mongodb here I come.

17:53 hiredman: technomancy: well, it makes sense, other wise how can you tell it is the same user?

17:55 technomancy: hiredman: sure, but the point is that this is a waste of time.

17:55 amalloy: ThreeCups: what would it mean for reduce to take three args? what args would it pass?

17:56 technomancy: setting up a postgres DB that you can actually access takes in excess of seventeen steps if you count all the times you have to create the DB, realize you've done something subtly wrong, dropping it, and recreating it.

17:56 hiredman: technomancy: you could just allow anyone to use the db without a password, just like most nosql dbs

17:58 gfredericks: hiredman: does "clean out your classfiles" imply anything more than `lein clean`? :/

17:58 seancorfield: i must admit, on the (two) occasions i've setup postgres, i've found it to be crazy fussy to install / configure / use and i can't understand why anyone raves over it :(

17:59 hiredman: gfredericks: rm -rf classes

17:59 ThreeCups: amalloy: it would take an accumulator, the next value to add to the accumulator, and any other args needed to calculate the addition of value to the accumulator

17:59 duck1123: There used to be a library that had a fn for shelling out that I can't seem to find anymore. Does anyone know of any good ones?

17:59 hiredman: and make sure the jar you end up using was generated after you did the rm -rf

17:59 duck1123: I've got pallet.stevedore, but that only seems to generate the scripts

18:00 technomancy: seancorfield: "GRANT ALL ON db.* TO $USER" is 90% of the reason mysql is widely used

18:00 hugod: duck1123: clojure.java.shell

18:01 amalloy: ThreeCups: but how would that work? either the "other args" are part of the next value (and you need only two args), or they're part of the accumulator (same thing), or they're the same every time. if they're the same every time, you can just make them part of the reducer function

18:01 duck1123: hugod: Well there it is. thanks

18:02 seancorfield: technomancy: and the fact that for dev work you don't need to create an o/s level user for mysql etc etc etc

18:02 gfredericks: hiredman: did everything over quite carefully. It looks like the jar for my project contains in itself a reference to the class, even though the class it contains has the slightly different numbers

18:03 (i.e., when I `grep <classname> <jarfile>`, grep says it matches)

18:04 I'm using a macro that emits a deftype...would this make sense if it was somehow running twice during compilation?

18:04 hiredman: possibly

18:05 * gfredericks looks around for anything suspicious

18:05 hiredman: the differing numebrs tends to mean something got compiled twice

18:05 also, if you are emitting a deftype inside a let or something

18:05 gfredericks: they all differ by one, which is odd, as it doesn't make sense if there's a global incremented variable for the unique IDs

18:07 the deftype is at the top level. The weirdest thing going on is that I'm doing (require ...) a couple times in the body of the only function of my deftype, just to make sure the ns's are loaded.

18:07 hiredman: ugh, yeah, no

18:07 don't do that

18:07 ThreeCups: amalloy: I think I understand what you're saying. I'm thinking about it a little differently. I'm updating a 2-d vector using reduce. I have a sequence of coordinate, value pairs e.g. ([[0 0] :value]...) and I have a fn that I use to update a matrix

18:07 (defn update-matrix-cell [matrix coords f & args] (apply update-in matrix coords f args))

18:07 gfredericks: okay, then I don't know how to make sure my class works

18:07 ThreeCups: I also have an intermediate fn between reduce and update-matrix-cell that takes 3 args

18:07 (defn update-matrix-cell-for-specific-data [matrix coords data] ... (update-matrix-cell ...))

18:08 It's this update-matrix-cell-for-specific-data that I'd like to call from reduce. I've "solved" this in the meantime by doing destructuring.

18:08 gfredericks: hiredman: without that I get unbound fn errors

18:08 hiredman: gfredericks: ok, add it, but use resolve

18:09 or, have the java side load the required namespaces

18:09 amalloy: ThreeCups: (reduce (fn [acc x] (update-matrix-cell acc (do-stuff-with-x))) cells) or something?

18:09 gfredericks: hiredman: the latter would be clunky, as I'd rather not edit the java (different project). My macro is emitting symbols for the require statements

18:09 e.g., (require '~(-> *ns* str symbol))

18:10 hiredman: use ns-name

18:10 and use resolve

18:10 gfredericks: so (require (resolve '~(ns-name *ns*)))?

18:10 hiredman: no

18:11 when you go to use something from the required ns, use resolve

18:11 (reuire x) ((deref (resolve 'x/y)) 1)

18:11 gfredericks: oh wow

18:11 the only thing I have after the require is ~@body

18:11 so I guess anytime I call the macro I need to resolve everything?

18:13 I had no idea interop from clojure was so hairy

18:14 am I doing something wrong? Is it really not possible to supply a class to a java proj via a jar without adding java code to bootstrap it?

18:16 srid: ,((first '(+ x x)) 2 3) ;; strange result

18:16 clojurebot: 3

18:16 srid: shouldn't that be 5?

18:16 amalloy: no

18:16 gfredericks: ,('+ 2 3)

18:16 clojurebot: 3

18:16 amalloy: &(= + '+)

18:16 lazybot: ⇒ false

18:16 amalloy: &(:+ 1 20) ; same as this

18:16 lazybot: ⇒ 20

18:16 srid: %('whatever 1 2)

18:17 membership lookup? returns 2nd arg as default.

18:17 gfredericks: have symbols always done that?

18:17 amalloy: &('+ '{* 1} 4)

18:17 lazybot: ⇒ 4

18:17 srid: ,((resolve (first '(+ x x))) 2 3) ;; works n ow

18:17 clojurebot: 5

18:18 amalloy: &('+ '{* 1 + 8} 4)

18:18 lazybot: ⇒ 8

18:18 amalloy: gfredericks: for as long as anyone can remember, anyway. probably for as long as keywords have done it

18:18 srid: 4clojure refuses resolve.

18:19 amalloy: &(resolve (symbol "eval"))

18:19 lazybot: java.lang.SecurityException: You tripped the alarm! resolve is bad!

18:20 amalloy: that's why - with resolve you can get eval, from which you can get anything you want

18:20 srid: problem 121 - close to lowest code golf ...

18:20 brehaut: amalloy: does it really ;)

18:20 gfredericks: ,(list (symbol "eval"))

18:20 clojurebot: (eval)

18:24 gfredericks: is require idempotent?

18:24 ThreeCups: amalloy: that will work, and I think it's what I've done but removing the "middle man". I want to think about updating my matrix with the fn

18:24 (defn update-matrix-cell [matrix coords f & args]

18:24 This seems to be a pretty clean/clear fn. And it makes sense that I'd have another function that update the matrix for a specific "data type" at a specific coordinate, hence the fn

18:24 (defn update-matrix-cell-for-specific-data [matrix coords data] ... (update-matrix-cell ...))

18:24 Now I have a matrix and a sequence of coordinate/data pairs and want to call my handy function to update the matrix for this type of data. But I can't because reduce takes a fn that takes 2 args.

18:24 I've got around this by creating an intermediate fn

18:24 (defn intermediate [matrix [coords data]] (update-matrix-cell-for-specific-data matrix coords data)

18:24 It'd be nice if I could hide this fn somewhere, i.e. make it anonymous or something (I'm too new to clojure so I don't know how to do this)

18:25 brehaut: ThreeCups: let + fn or letfn ?

18:26 ThreeCups: brehaut: will give it a try. I've used it once and forgot about it :)

18:26 technomancy: gfredericks: yeah

18:32 ThreeCups: brehaut: Thanks! worked like a charm

18:32 gfredericks: oh, I was wrong about my jar containing a reference to the non-existing class. apparently I used grep poorly.

18:36 oh man, I think it's a serialized object

18:37 are clojure datatypes not safely serializable in the java-sense? or maybe just lazy seqs?

18:44 I can imagine if java tries to serialize a lazy seq it couldn't do anything other than serialize the internal fn itself

19:02 hiredman: gfredericks: the other thing is java serializing requires the classes to be present at both ends, dones't play well with dynamic byte code generation

19:04 gfredericks: hiredman: are non-lazy datatypes safer? or do they have hidden references to fns?

19:05 hiredman: they are safer, you really should be able to serialize a lazy-seq

19:08 gfredericks: I think I finally got the example-of-a-use-case working, though I'm not sure if serialization will come up later. Will try it out.

19:08 hiredman: thanks for the help.

19:09 hiredman: np

19:42 scottj: "There are several upcoming books on Clojure from multiple publishers. I think there's been more books on Clojure in 2 yrs than Lisp in 20 ;)"

19:42 no way, no matter how you pick the two years (since programming clojure is already over two years old).

19:43 let over lambda, land of lisp, practical common lisp, lisp small pieces, ansi common lisp, on lisp, paip, plai, little schemer, seasoned schemer, reasoned schemer. and if you go 22 years or so you get horn and cltl2

19:43 callen: PC is the one I have.

19:43 I can't wait for v2.0

19:43 I want some Noir.

19:44 scottj: of course the tweet suffers from the same flaw as people who complain that the US isn't building as many bridges as China.

19:50 technomancy: don't forget the art of the metaobject protocol

19:51 scottj: oh wow I thought that was older so I didn't bother checking

19:52 technomancy: not really fair to count both CL and Scheme though

19:53 scottj: actually I bet if you just do 89-91 CL beats any three year pear of clojure

19:56 oopcl, amop, cltl2, paip, horn3

19:59 tolstoy: How long until "Clojure & Spring"?

20:00 * TimMc stabs

20:00 tolstoy: Heh. ;)

20:00 TimMc: $kill

20:00 lazybot: KILL IT WITH FIRE!

20:01 tolstoy: Movie: The Spring. A group of hackers go down to Antartica to uncover an old architecture, when...

20:03 ThreeCups: How would I get the x/y coordinate pairs from a 2-d matrix? E.g. (coord-pairs (->> (repeat 2 {}) vec (repeat 2) vec)) would return [[0 0] [0 1] [1 0] [1 1]]

20:05 gfredericks: ThreeCups: I'd get the dimensions and do something like ##(for [x (range 3) y (range 2)] [x y])

20:05 lazybot: ⇒ ([0 0] [0 1] [1 0] [1 1] [2 0] [2 1])

20:12 technomancy: dakrone: how do you feel about accepting a string for :basic-auth?

20:12 it would make for easier round-tripping via java.net.URI since that class exposes user/password only via .getUserInfo as a single colon-separated string.

20:12 (as well as continuing to accept a seq of course)

20:13 also: why do I always come up with these questions for dakrone _after_ 6pm mountain time?

20:14 hiredman: :/

20:14 mdeboard: So, question. I was just reading http://blog.factual.com/clojure-on-hadoop-a-new-hope and he has several variables preceded by `?`. Is this some convention or does it have a syntactic meaning I'm missing

20:15 or is it just something he likes doing

20:15 hiredman: it's a cascalog/datalog/logic programming thing/convention

20:16 nathanmarz: it distinguishes variables from regular variables

20:16 hiredman: doesn't have a meaning in clojure outside of those domains

20:16 nathanmarz: errr

20:16 from regular values

20:16 e.g., if you did this: (<- [?a ?b] (source ?a) (+ val ?a :> ?b))

20:16 then "val" is just a normal Clojure variable, and its value is substituted into the query

20:16 whereas ?a and ?b are part of the query

20:17 mdeboard: oh hey nathan

20:17 marz

20:17 I was just looking at Cascalog

20:17 I se

20:17 e

20:17 I have a need for such functionality at work.

20:18 I've got this colossal "cities.txt" file that is a csv of every city in the world, with its country and lat/long

20:18 1.5 mil lines or something

20:18 cool story bro

20:19 nathanmarz: cool

20:19 you could certainly query that with cascalog

20:19 gfredericks: the '.txt' makes me imagine opening it in notepad

20:20 * gfredericks actually has no idea if notepad could handle it or not

20:20 mdeboard: gfredericks: Worse. Iterating over every line, creating a Django ORM object out of the line, then saving it to the database.

20:20 * hiredman was just trying to edit a 300,000+ line org-mode file

20:21 mdeboard: gfredericks: It is unbelievably slow.

20:21 hiredman: (didn't go over well)

20:21 gfredericks: mdeboard: I'm not sure what you just said but I'm pretty sure it was offensive

20:21 mdeboard: gfredericks: I threw up.

20:21 hiredman: at least he didn't call you a cfmljure

20:22 gfredericks: :)

20:23 mdeboard: I'm frustrated just thinking about it.

20:26 It's stovepiping part of a bigger project, actually. I wish I hadn't brought itup.

20:27 TimMc: stovepiping!

20:27 mdeboard: indeed

20:27 TimMc: I first heard that phrase in a Charlie Stross book, re: gov't projects.

20:28 Or is that even the same term?

20:29 mdeboard: TimMc: I spent a decade+ in the USMC, common metaphor :P I'm sure it was explained in the book but literal stovepiping is when a spent cartridge is incompletely ejected from the chamber, and gets caught between the bolt and ejection port

20:29 So it's just sticking straight up, preventing the weapon from completing its firing cycle

20:29 it being the spent casing

20:29 TimMc: Why does it get that name?

20:29 mdeboard: It looks like a stovepipe

20:29 TimMc: That's like a 4th meaning...

20:30 mdeboard: http://images.google.com/imgres?q=stovepipe&hl=en&biw=1600&bih=746&gbv=2&tbm=isch&tbnid=O_5jgmm1b31ftM:&imgrefurl=http://4photos.net/en/image:142-47576-Glock_23_stovepipe_images&docid=BW6DcnkfZoGYgM&imgurl=http://4photos.net/photosv2/130428_glock_23_stovepipe.jpg&w=300&h=200&ei=QDGzTqLoNvG42QXsjMHMDQ&zoom=1

20:30 wow, nice link

20:30 you're right, I used"literally" and shouldn't have

20:30 Literally a stovepipe: http://www.daviddarling.info/images/stove_pipe.jpg

20:30 Metaphorical weapon-related stovepipe, whence the term originates: http://4photos.net/photosv2/130428_glock_23_stovepipe.jpg

20:30 TimMc: Now *that*'s a stovepipe.

20:31 Wikipedia has two definitions: https://secure.wikimedia.org/wikipedia/en/wiki/Stovepiping

20:31 mdeboard: So by stovepiping the project I mean something that is between me and project completion

20:32 wow

20:32 ANd knowing is half the battle

20:32 technomancy: (defn getenv [x] ({} x (System/getenv x)))

20:33 ^ because no System/setenv exists

20:33 * technomancy stabs

20:33 TimMc: mdeboard: And here I thought you meant you had some spaghetti... stovepipes...

20:33 piping data from one component to another, but haphazardly.

20:36 mdeboard: TimMc: Interesting, I've really never heard of that. Can tell I wasn't an intel bubba.

20:38 TimMc: Thanks, actually.

20:39 TimMc: I still don't really get the gov't/intel sense of the phrase.

20:39 I mean, at a gut level for what it means organizationally.

20:43 mdeboard: TimMc: AFAICT it uses the meaning of stovepipe i.e. "isolated vertical conduit" that vents material outside the building, to mean an isolated vertical conduit that vents "material" (information) outside the organization

20:43 Like when a colonel has the ear of a senator

20:43 and passes his information to influence policy

20:43 without distributing it through the proper channels to reach the same destination.

20:44 TimMc: I get that one.

20:44 technomancy: What's the context?

20:45 technomancy: TimMc: you want to change an environment variable without restarting the whole JVM

20:45 so you just slap it in the map in getenv

20:48 TimMc: {} is a placeholder for a ref of a map?

20:48 technomancy: it's just something you can edit inside the function at dev time

20:48 cark: is there a one liner that transforms :a to ([:a] [:a :a] [:a :a :a] ....) ?

20:49 vectors not required,

20:49 TimMc: technomancy: Oh, some defaults.

20:49 hiredman: ,(for [i (range 10)] (repeat i :a))

20:50 clojurebot: (() (:a) (:a :a) (:a :a :a) (:a :a :a :a) ...)

20:50 TimMc: ,((partial iterate conj []) :a)

20:50 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core$iterate>

20:50 cark: hiredman: ah thanks, i was looking at reductions

20:50 TimMc: urg

20:50 cark: but good enough !

20:50 ibdknox: ,(map #(repeat % :a) (range 1 10))

20:50 clojurebot: ((:a) (:a :a) (:a :a :a) (:a :a :a :a) (:a :a :a :a :a) ...)

20:52 amalloy: &(rest (iterate #(conj % :a) []))

20:52 TimMc: ,(take 3 (drop 1 (iterate #(conj % :a) []))) ; cark

20:52 clojurebot: ([:a] [:a :a] [:a :a :a])

20:52 lazybot: java.lang.OutOfMemoryError: Java heap space

20:52 ibdknox: lol

20:52 amalloy: haha sorry lazybot

20:52 (dec amalloy)

20:52 lazybot: You can't adjust your own karma.

20:53 gfredericks: (inc amalloy)

20:53 lazybot: ⇒ 19

20:53 gfredericks: serves you right

20:53 for trying to dec yourself

20:53 ibdknox: lol

20:54 cark: thanks all !

20:54 gfredericks: when I try to create a future in the body of an aleph channel-receiving function, I get a java.util.concurrent.RejectedExecutionException

20:54 TimMc: technomancy: http://stackoverflow.com/questions/318239/how-do-i-set-environment-variables-from-java/496849#496849

20:55 :-P

20:55 cark: Pyramid scheme of some sort.

20:55 technomancy: TimMc: my eyes!

20:55 TimMc: haha

20:56 gfredericks: It's not a real function if you haven't typed "Map<String, String>" at least four times.

20:56 technomancy: TimMc: that is a serious hack though, wow

20:56 i wonder how many lines of clojure that would be

20:57 ibdknox: that is all kinds of evil

20:57 hiredman: ,(let [[Map<String, String>] [1 2]] [Map<String, String>])

20:57 clojurebot: [1 2]

20:57 TimMc: ahaha

20:58 hiredman: clojurebot: symbols |are| kind of fun

20:58 TimMc: gfredericks: Map<LanguageCode, Map<String, Map<String, Set<Integer>>>>

20:58 clojurebot: In Ordnung

20:58 gfredericks: clojurebot: symbols?

20:58 clojurebot: symbols are kind of fun

20:58 cark: ah for completeness here is the reductions version :

20:58 ,(take 3 (reductions conj [] (repeat :a)))

20:58 clojurebot: ([] [:a] [:a :a])

20:58 cark: but i'll take hiredman's version which is the most readable

20:59 (for me)

20:59 TimMc: cark: but but but it doesn't share structure!

20:59 cark: ah indeed !

21:00 amalloy: technomancy: not as much, anyway

21:00 er, TimMc

21:01 gfredericks: to share the most structure wouldn't we want to use cons instead of conj?

21:01 TimMc: technomancy: Farther down the page is a crossplatform hack.

21:01 hiredman: depends

21:02 cark: curse you TimMc, now i have to think about structure sharing =P

21:02 hiredman: cons is really only for constructing seqs

21:02 conj is fine for sharing structure among vectors

21:02 cark: one can conj on a list

21:03 technomancy: http://p.hagelb.org/setenv.clj.html <= 7 lines, could be golfed further

21:03 gfredericks: ,(map type [(cons 7 ()) (conj 7 ())])

21:03 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IPersistentCollection>

21:04 gfredericks: ,(map type [(cons 7 ()) (conj () 7)])

21:04 clojurebot: (clojure.lang.Cons clojure.lang.PersistentList)

21:04 gfredericks: okay so I meant conjing onto a list I guess

21:04 technomancy: I'll stick with my crappy defn getenv workaround for now

21:07 TimMc: technomancy: I was just writing that! `lein new hurk`, (defn ohgod [...] ...)

21:09 jcromartie: for some reason, the bozo that wrote this code thought that a singleton object which operates as a state machine was somehow thread safe

21:09 and the words "thread safe single object for foo repository" are all over

21:10 TimMc: jcromartie: It is threadsafe because he used the @threadsafe Javadoc annotation.

21:10 jcromartie: not even

21:10 but dear god

21:10 I just realized this crap is all over

21:10 it's a wonder it works at all

21:11 amalloy: jcromartie: but there's only one! how could that be unsafe!!!!

21:11 TimMc: jcromartie: Ah, the mystery of life.

21:12 gfredericks: at work I've been using the Activiti BPMN engine, and in one of their webapps they have a 500 line custom implementation of a prefix trie. AND it's buggy. I rewrote it in clojure and it worked fine.

21:13 I thought of that because I'm pretty sure it's not threadsafe either, but of course my clojure replacement was.

21:13 jcromartie: :)

21:13 TimMc: OK, evangelism question. I want to start converting bits of a large multi-component Java project at work into Clojure. How can I do it incrementally?

21:13 Everything is managed with Maven.

21:14 jcromartie: this is in 14 classes

21:14 they are all race conditions

21:14 they are all used unsynchronized

21:14 by multiple users on the web site

21:14 and they all say "Thread Safe"

21:14 gfredericks: jcromartie: if something doesn't work they just click the button again?

21:14 TimMc: Maybe it is a brand name.

21:14 jcromartie: and even among those classes there are OTHER race conditions

21:15 like where they copied temporary files to a file using new Guid() in .NET

21:15 which creates an *empty* GUID

21:15 every time

21:15 TimMc: ahaha

21:15 jcromartie: the same file, 00000000-0000-0000-0000-000000000000

21:15 is used for every concurrent user

21:15 I mean dear god

21:16 I knew concurrency was not always easy

21:16 TimMc: "Well, when I tested it, it worked!"

21:16 jcromartie: but this...

21:16 this is inexcusable

21:16 gfredericks: jcromartie: it's okay if they're all the same as long as they're globally unique

21:16 cark: indubitably one unique guid you got there

21:17 jcromartie: thankfully our user activity is measured in hits per minute

21:18 gfredericks: IUID: Initially Unique Identifier

21:18 TimMc: I figured.

21:18 jcromartie: Why does that constructor even exist? Attractive nuisance.

21:19 jcromartie: TimMc: it's a .net struct

21:19 meaning it defaults all of the fields to a default (0) values

21:20 and, of course, since the geniuses copied and pasted all of this crap, it's the same race condition duplicated separately 14 times

21:20 used in slightly different ways

21:20 TimMc: hahaha

21:20 jcromartie: I mean

21:20 can we sue?

21:20 TimMc: lazybot: Can we sue???

21:20 lazybot: TimMc: Yes, 100% for sure.

21:20 gfredericks: jcromartie: for a better-than-average job? :)

21:22 TimMc: ,(= java.lang.String (.getClass ""))

21:22 clojurebot: true

21:22 TimMc: technomancy: Why not (= c java.util.Collections$UnmodifiableMap)

21:23 technomancy: TimMc: sure, why not?

21:23 TimMc: since you kind of asked for golfing

21:23 Also, prettier.

21:25 amalloy: (some #{j.u.C$UM} all-the-classes)

21:25 TimMc: Why does it even bother iterating?

21:27 technomancy: probably because it's java =P

21:27 TimMc: (let [c java.util.Collections$UnmodifiableMap ... ) works

21:29 Seriously, WTF.

21:31 I wonder if the author didn't know you could directly reference stuff like that.

21:32 jlf: technomancy: what's the recommended package to get clojure-jack-in working in a vanilla emacs 24?

21:32 technomancy: jlf: clojure-mode and lein plugin install swank-clojure 1.3.3 should do it

21:32 jlf: clojure-mode either from marmalade or github

21:32 jlf: thanks

21:35 * jlf is at http://www.meetup.com/The-Bay-Area-Clojure-User-Group/events/19783281/

21:40 technomancy: ah cool; say hi to everyone for me

21:40 * technomancy is at http://seajure.github.com

21:41 darevay: hi 4clojurers. For problem 86 (http://www.4clojure.com/problem/86) I have a solution (http://www.4clojure.com/problem/86) that causes ClassNotFoundException:clojure.core. Works fine locally. What have I done?

21:41 gfredericks: how does 1.3 handle vars in (future)?

21:41 darevay: ... oops that solution link should be https://gist.github.com/1338452

21:46 TimMc: darevay: Yeah, WORKSFORME locally.

21:47 amalloy: darevay: something seems to be wrong with the set literal. i don't know how that can be, really

21:48 ie, if i replace your #{} with [] and use (some #{n} ns), it works. obviously that shouldn't matter

21:51 darevay: amalloy: thanks. weird.

22:00 ... and now I see how I was working way too hard to get the digits of a number. geesh :)

22:07 gfredericks: oh man. an hour of debugging and it turns out ztellman implemented his own map type. o_o

22:17 is there not an interface or protocol for conj?

22:19 cark: ,(conj {} [:a 1])

22:19 clojurebot: {:a 1}

22:20 amalloy: gfredericks: IPersistentCollection.cons

22:23 gfredericks: amalloy: ah ha. Indeed that method is left out. thanks.

22:45 mdeboard: export JAVA_OPTS=-Xmx768m

22:45 oop

22:55 brehaut: ibdknox: ping?

23:02 leo2007: can M-. in slime jump to definition of `def'?

23:21 tali713: leo2007: i can't, here.

23:21 leo2007: tali713: thanks for the confirmatino.

23:22 confirmation*

23:28 technomancy: leo2007: it should actually

23:29 leo2007: a bug?

23:29 technomancy: could be

23:45 seancorfield: fixed that bug in clojure-jack-in that was causing issues with warn-on-reflection

23:45 released a new clojure-mode version with the fix

23:47 aperiodic: is there a way to exit from a repl inside a repl?

23:47 without also exiting from the enclosing repl, that is

23:55 technomancy: sending an EOF should do it

Logging service provided by n01se.net