#clojure log - Jul 09 2011

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

0:09 bhenry: who is in charge of the planet clojure reader feed?

0:14 hugod: amalloy_: adding a :dev-resources-path to project.clj for the tools.jar file seems to work (as described in the readme under sun/orcale jdk)

1:49 amalloy: dnolen: i see that you're helping spread the gospel of performant clojure again :)

2:31 zodiak: hey everyone, so, quiet in here.. but.. I have to ask; what's the web frameworks for clojure ? is there a sort of rails/django/play type of mvc framework ?

2:31 talios: webnoir looks to be the new hotness

2:32 zodiak: talios: danke.. off to google I go :)

2:32 talios: zodiak: http://www.webnoir.org

2:32 zodiak: oh. even better. dankeschoen

2:32 talios: builds ontop of compojure, which itself is a webframework, webnoir is more higher level

2:33 amalloy: zodiak: noir is the new hotness, but it's pretty amazing how easy it is to work with the lower-level tools like ring, compojure, and hiccup

2:33 zodiak: perhaps a bad question but, I am coming from a smalltalk/ruby/scheme/perl background.. does clojure more closely follow scheme with minimal syntax or common lisp with 4000+ methods ? :)

2:34 talios: amalloy: heh, noir is just ring/compojure/hiccup by the looks of it

2:34 zodiak: amalloy: looking at it now.. webnoir I mean.. seems to be fairly grokable :)

2:34 amalloy: zodiak: some of both

2:34 zodiak: amalloy: more names to google. thank you (honestly :)

2:35 amalloy: as long as it's not as "bad" as CL .. that's a good thing :D

2:35 amalloy: clojure's "syntax" is pretty minimal, but it has more built-ins than scheme (not really the same thing as syntax)

2:35 talios: zodiak: noir etc. arn't fullstack tho, so theres no ActiveRecord like thing built in.

2:35 amalloy: talios: no? i thought that's what noir was supposed to do. i haven't looked into it

2:35 zodiak: talios aah. I was going to ask at some point about "orm" (I know you can't really have the O part but, you get the point)

2:36 I take it the channel is "newb friendly" ?

2:36 talios: amalloy: not that I've seen. but if you adding clojureql shouldn't be hard

2:37 amalloy: zodiak: we only murder one in ten new users. you seem to have survived so far, so you're probably safe

2:37 * zodiak tips hat

2:37 zodiak: good show ;)

2:37 talios: zodiak: http://www.clojureql.org - it's not an ORM, but a nice liibrary/framework for querying/working with dbs

2:38 zodiak: talios: reading the examples. the syntax looks horribly clean :) awesome.

2:38 talios: amalloy: yes but me maim three out of five people who ask annoying questions :)

2:40 zodiak: last annoying newb question (promise) is clojure's performance "good" (I know, that's a very subjective question but, it's faster than python/ruby I assume since it's a jvm language)

2:46 Scriptor: does doing new File() in Java do any actual IO, or does only happen when you call some method on it?

2:47 couldn't find anything about joining paths in clojure, so just looking at the java way of doing it

2:47 amalloy: Scriptor: no io

2:48 Scriptor: yay

2:49 talios: zodiak: Id say faster but that kinda depends on what you're doing isn't it :)

2:49 zodiak: talios: oh. totally. I know it's subjective, as long as it's not the slowest kid in the class, it's all good I guess :D

2:51 talios: if there's methods you really need to optimize you can give type hinting to your methods which make things more porformant, I think thats improved a lot already in 1.3 as well

2:55 seancorfield_: sorry for the constant part/join - the network here is *^%^$

3:09 amalloy: zodiak: clojure in general is pretty fast. things which can be quite slow if you do them the "easy way" are interop (calling non-clojure java code) and arithmetic.

3:10 but if you find out that's your bottleneck (and you care), you can add annotations to the source to make that faster without having to restructure anything. bug dnolen about it, he loves to show off how fast clojure can be

3:15 hiredman: I'm going crazy looking for a screenshot I took of a tweet were a guy said something like "people like hiredman are not helping clojure catch on" (since someone was asking about newbie friendliness) and which all my logging, etc, I can't find the stupid thing

3:18 amalloy: people like hiredman are not helping clojure catch on

3:18 maybe use that as a substitute?

3:19 hiredman: http://www.thelastcitadel.com/_media/clojure.png?cache=cache <-- I did find some early work on a clojurebot logo

3:21 I know for a fact I had this thing, where did it go, it's not like I ever delete anything

3:28 amalloy: hiredman: hah, that's hilarious

3:33 ibdknox: you around?

3:33 ibdknox: amalloy: sup?

3:34 amalloy: i'm finding it pretty hard to modify the starter bot, because everything depends on this global *game-state*. specifically, i'd like to update the state every time i move an ant, so that they don't think a space is empty anymore if another ant is on his way there

3:35 i guess i can create a local copy of it, then create a new (binding) preparatory to every call into the starter kit

3:36 ibdknox: I did it by adding in an ant tracker

3:36 because beyond just knowing if a space is taken I wanted to be able to uniquely ID an ant so I can give it a role

3:36 that's not included in the starter thing because they explicitly state they don't want it to be lol

3:36 amalloy: sure

3:37 but do you have an objection to having most of the starter-kit functions accept an (optional?) explicit state argument, rather than depend on a global?

3:37 incidentally, you don't need to uniquely ID ants in order to give them roles

3:38 ibdknox: no?

3:38 how's that?

3:38 amalloy: you can have a map of {location => role} pairs, which you match against the ants when you read them, and update when you move them

3:39 i imagine your tracker works similarly, except you store {location=>id}

3:39 and have an additional {id=>role} map

3:39 ibdknox: yep

3:39 amalloy: that might be better, so that you can have a role like "hang out with ant 43", but it seems more complicated

3:40 ibdknox: it's stupid simple, but that also means it's stupid ;)

3:41 btw

3:41 the only reason I did it the way I did was because they wanted the packs to be similar

3:41 I originally wrote it such that the bot was passed a map of the state

3:41 and you just worked with that directly

3:41 I think that might be the better solution overall

3:42 the bot being the function you pass to start-game

3:42 amalloy: right

3:42 ibdknox: thoughts?

3:42 I can make that change on the grounds that it's more idiomatic

3:43 amalloy: well, i'd write it the way you first did

3:43 but it boils down to adding a (state) argument to pretty much every function in ants.clj

3:43 ibdknox: it would actually get rid of most of the functions entirely

3:43 amalloy: so perhaps in the interests of more-easily modeling state it's better to bind it

3:44 ibdknox: well, maybe. i think a lot of them are good to have around as sort of an API to the map, so you don't have to know what it contains if you don't want

3:44 ibdknox: fair enough

3:45 water makes it slightly more complicated too

3:45 since it's not given every time

3:45 though, not any real complexity there

3:46 completely unrelated, my 7 line bot is doing stupidly well

3:46 lol

3:46 amalloy: ibdknox: i improved the performance by switching (first) to (rand-nth) :P

3:46 ibdknox: haha

3:46 here's what the one I submitted is doing

3:47 amalloy: ibdknox: but the server still doesn't run clojure bots correctly, does it? i'm curious how you submitted it in that case

3:47 ibdknox: https://gist.github.com/1073423

3:47 I put it all in a single file

3:47 amalloy: idea stealer!

3:47 ibdknox: it was annoying

3:47 but it works :-p

3:47 haha

3:48 implemented it first ;)

3:49 amalloy: oh, something I found out and need to change in the starter thing: you can move on top of food.

3:49 err

3:49 can't*

3:50 amalloy: i don't see that mattering. does food spawn right next to you, and then only hatch after you've moved?

3:54 ibdknox: well if you're next to it and you're trying to move to it, it will count as an invalid move

3:54 enough of those and you end up disqualified

3:54 amalloy: ibdknox: but you shouldn't be next to it, is my point, since it should hatch when you get there

3:54 unless it behaves as i suggedted above

3:54 ibdknox: it hatches the next turn

3:56 hiredman: it would be interesting to do it cps style for co-operative multitasking

3:58 amalloy: oh, yikes. the the :ants key is a seq of locations

3:59 that makes it pretty tough to change the state to no longer include an ant

4:03 ibdknox: hm, it's a seq? I must've screwed something up.. it should be a set

4:04 amalloy: ibdknox: oh, sorry then

4:04 i didn't read closely; i'm sure you're right

4:07 ibdknox: if you're interested i wrote up https://gist.github.com/ea397d8052c71fefbb4b as an example of keeping two ants from moving into the same square at once

4:09 ibdknox: amalloy: cool! I just made a change to make passable? take other ants into account, since everywhere I kept having to do (unoccupied? (passable? loc))

4:10 amalloy: (def okay-move? (comp unoccupied? passable?)) :P

4:10 ibdknox: haha

4:11 amalloy: ibdknox: do you know how to get debug information about a crash? every five or ten games my bot gets marked as "crashed" at some point

4:13 ibdknox: this works for me:

4:13 (defn run []

4:13 (try

4:13 (start-game my-bot)

4:13 (catch Exception e

4:13 (.printStackTrace e))))

4:13 it seems if you explicitly print the trace it ends up in the output

4:14 amalloy: ibdknox: in what output?

4:14 ibdknox: when you run ./test_bot or ./play_one_game it lists all the turn info

4:14 it shows up there

4:14 as it runs

4:14 amalloy: oh. i guess their engine is swallowing stderr

4:15 * ibdknox nods

4:15 amalloy: but not stdout. weird choice, imo, but what do i know

4:15 ibdknox: something to do with the way the sandbox works?

4:15 I have no idea

4:16 you might have to run it with the same flags as test_bot has too... I can't remember

4:17 the whole thing could use some help to be honest lol

4:17 amalloy: --strict --capture_errors

4:17 ibdknox: yeah

4:17 strict will list out invalid moves and such

6:37 trochala: Hello, I am reading the Joy of Clojure book, and it suggests installing cljr from github.com/fogus/cljr.

6:38 This repo doesn't exist but seems to have moved to https://github.com/liebke/cljr.

6:39 I can see that the last commit is one year ago. I wanted to ask if the project is outdated and if I should use some other repl package

6:40 schasi: trochala: I am also new, but I think installing it from lein is a good idea

6:40 Even though I'd like to know what the proes here have to say about it :D

7:02 rbuchmann: Hey, quick question: What git mode, if any, do you prefer for emacs and why?

7:07 I had a look at magit, but I'm not sure I like it

7:54 lnostdal-laptop: emacs and swank-clojure-1.6+ users; does evaluating (future 42) work in your repls?

7:55 bsteuber: you mean leiningen-1.6+

7:55 lnostdal-laptop: ah, yeah

7:55 i mix the numbers

7:55 bsteuber: me too :)

7:56 lnostdal-laptop: to be exact, i'm using swank-clojure-1.4.0-SNAPSHOT (from git) .. and leiningen-1.6.1 from git

7:56 ..and futures doesn't work..

7:57 "Task java.util.concurrent.FutureTask@3a70dd47 rejected from java.util.concurrent.ThreadPoolExecutor@5e3c782[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 2"

7:58 bsteuber: same for me still

7:58 strange technomancy couldn't reproduce it

7:58 lnostdal-laptop: ok, yeah, i even updated clojure-mode to make sure

7:58 ..though i guess that should be unrelated

7:58 ..what version of emacs, bsteuber ?

7:58 bsteuber: 24

7:59 but that should really not matter

7:59 lnostdal-laptop: .. same .. but, yeah, indeed

7:59 i'm using jvm7 tho

7:59 bsteuber: hmm

8:00 lnostdal-laptop: (System/getProperty "java.version") => "1.7.0"

8:00 bsteuber: yeah it's really a mystery to me

8:00 lnostdal-laptop: maybe he's forgotten to push some patches .. that does happen :}

8:01 bsteuber: just sticking to lein 1.5.2 and getting things done for now

8:02 lnostdal-laptop: so ...anyone else seeing the same thing besides bsteuber and me?

8:05 and another question; what coding style does people use for global variables now in 1.3.x seeing as globals aren't dynamic by default anymore?

10:04 b6n: Can someone tell me how I can transform a data structure like [[:foo 1] [:bar 2]] into {:foo 1 :bar 2} ?

10:05 dnolen_: ,(into {} [[:foo 1] [:bar 2]])

10:05 clojurebot: {:foo 1, :bar 2}

10:05 dnolen_: b6n: ^

10:06 b6n: oh it's so easy?! thanks a lot

10:14 vdrab: Hi all. what is the idiomatic way to do buffered reads from standard input in clojure?

10:15 duck-streams? clojure.java.io?

10:16 java BufferedReader? java InputStream?

10:23 fliebel: vdrab: i'd say (clojure.java.io/reader *in*) should do.

10:24 &(class *in*)

10:24 sexpbot: ⟹ clojure.lang.LineNumberingPushbackReader

10:24 vdrab: fliebel: thanks!

10:25 fliebel: vdrab: Maybe skip the reader part, and just wrap *in* in a buffered reader from java.io

10:25 vdrab: is this also considered the most performant way to read streams? (elegance and all aside)

10:27 fliebel: I wouldn't know. Maybe you can get stdin from javaland without the pushback stuff.

10:27 &System.in

10:27 sexpbot: java.lang.ClassNotFoundException: System.in

10:28 vdrab: &System/in

10:28 sexpbot: ⟹ #<BufferedInputStream java.io.BufferedInputStream@1f5a6f9>

10:28 fliebel: well, there you go :)

10:28 vdrab: thanks

10:29 and wrap this in a line-seq?

10:32 "(println (line-seq (clojure.java.io/reader *in*)))" gives me around 11mb/sec throughput on my little macbook

10:36 can you think of any obvious ways to improve upon this?

10:38 Scorchin: so has anyone got any guesses on what the july 20th announcement is?

10:41 Scriptor: nope, I'm still too bummed about not being in the city then

10:42 dnolen_: Scorchin: I'm betting compiler related.

10:42 Scorchin: dnolen_: anything specific?

10:43 clojure in clojure would be nice

10:44 can then make a clojure in JS runner

10:47 dnolen_: Scorchin: I'm thinking it'll be something along those lines. When I gave my preso on Logic programming at the NYC Clojure Meetup a while back, he mentioned he had new ideas for the compiler. Also to allow libraries to provide typechecking the compiler really needs to provide some kind of hook which doesn't exist right now.

10:48 Scriptor: hmm, I didn't overhear anything special from him at the last meetup, so that may be it

13:40 chouser: dnolen_: I didn't think you'd have to guess

13:41 dnolen_: chouser: heh, I don't have any inside knowledge :)

13:54 ataggart: dnolen_: What were the companion books to The Reasoned Schemer you mentioned? I'm not able to google it up.

13:55 dnolen: same question ^

14:39 dnolen_: ataggart: Bratko's Prolog book, Sterling & Shapiro Prolog book, Byrd's thesis http://pqdtopen.proquest.com/#abstract?dispub=3380156

14:40 ataggart: thx

15:47 arohner: I have an arrow that looks like (-> foo (bar) (.trim))

15:47 where .trim is being called on a string. How do I add a type hint there to avoid reflection?

15:53 I guess I can do the fn trick

15:53 dnolen_: ,(do (set! *warn-on-reflection* true) (-> "foo" identity (.trim)))

15:53 clojurebot: java.lang.IllegalStateException: Can't change/establish root binding of: *warn-on-reflection* with set

15:54 dnolen_: (-> "foo" ^String (identity) (.trim))

15:54 ^ works

15:54 arohner: aha!

15:54 dnolen: thanks

15:57 dRbiG: can anyone give me some 'classic' situation/problem when macros come really really handy?

15:58 AWizzArd: dRbiG: when developing a DSL

15:59 arohner: dRbiG: with-open

15:59 ,(doc with-open)

15:59 clojurebot: "([bindings & body]); bindings => [name init ...] Evaluates body in a try expression with names bound to the values of the inits, and a finally clause that calls (.close name) on each name in reverse order."

15:59 AWizzArd: For nearly every lib you will probably want to have one macro that offers a little DSL.

15:59 dnolen_: dRbiG: day to day boilerplate is a big use case.

16:02 Chousuke: macros are a potential solution whenever you feel like you're writing repetitive code

16:02 dRbiG: right.\

16:02 the with-open example would be a block in ruby

16:03 chouser: though closures do a pretty impressive job there too

16:03 Chousuke: Yes, the first approach should of course be a design that doesn't force you to write repetitive stuff, but whenever that's not possible (or feasible) macros help

16:04 paraseba: dRbiG: ruby block would be similar to passing a clojure function to with-open. Macros give you the extra syntactic sugar, so you don't need to wrap everything in (fn ...)

16:04 dRbiG: so lets consider: i want o bind a set of x-foo variables to results of (.foo bar) - i guess i can do it nicely with a macro?

16:04 Chousuke: sure

16:04 bsod1: clojure repl funcitons like dir, doc, javadoc, pprint etc. are not included in `lein swank`, right? with `lein repl` I can use it but in SLIMV repl, I can't..

16:05 arohner: bsod1: they're there, but you might have to 'use' them first to get them into your user namespace

16:05 bsod1: arohner: thanks, that's what I was wondering..

16:05 arohner: (use '[clojure.pprint :only (pprint)])

16:06 etc

16:06 look in clojure.repl, and clojure-contrib.repl-utils

16:16 dnolen_: bsod1: it also useful when you're building a fairly involved embedded paradigm, the results from macro transformation in core.logic are pretty intense.

16:16 oops, dRbiG ^

16:20 dRbiG: https://gist.github.com/1073927

16:22 dRbiG: defne - ? some pattern maching defn?

16:22 dnolen_: dRbiG: it's basically Prolog.

16:23 but yes, that pattern matching via unification.

16:24 dRbiG: interesting. pattern matching and currying is always useful

16:25 dnolen_: dRbiG: these macros are all about controlling names, binding, scope, etc. stuff that's hard to w/o macros.

16:33 amalloy: dRbiG: as a matter of interest, you might like to see how it's possible to implement (let ...) as a macro layered over (fn ...)

16:36 dRbiG: i think i've seen that somewhere already

16:38 amalloy: well, https://gist.github.com/1073943 if you want

16:42 arohner: is http://dev.clojure.org/jira/browse/CONTRIB the right place for an issue in clojure/java.jdbc?

16:44 amalloy: arohner: i don't think so. lemme check

16:45 arohner: http://dev.clojure.org/jira/browse/JDBC

16:45 arohner: similarly, I don't see a "new" style project for c.c.zip-filter and c.c.zip-filter.xml. Are they supposed to have one?

16:46 dRbiG: right, now i have a really stupid question: how do i get length of *command-line-args*? :S

16:46 amalloy: &(doc count)

16:46 sexpbot: ⟹ "([coll]); Returns the number of items in the collection. (count nil) returns 0. Also works on strings, arrays, and Java Collections and Maps"

16:47 dRbiG: thanks. i find the lack of common agreement on verbs a major inconvenience ;)

16:47 hmm, actually now i realise it's verbs vs. nouns

16:49 amalloy: dRbiG: indeed. java has .length and .size - verbs with noun-names :P

16:49 arohner: dRbiG: ideally, in a lisp (or any FP language), all function calls are verbs

16:50 dRbiG: my 'code'base is mostly ruby now, so length is indeed my first idea

16:51 arohner: chouser: what's the plan with zip-filter.xml and "new" contrib projects? I have a bug in zip-filter.xml; there needs to be a small tweak in tag= to make it work with your new data.xml

16:52 chouser: in tag=, need to swap ((zip/node %) :tag) for (:tag (zip/node %))

16:52 dRbiG: though it makes sense not to think about length/size as a noun-property of things that can be infinite

16:53 arohner: dRbiG: right, sometimes it's not a property, which is why it's a verb

16:53 wilfredh: so, I read that Clojure's let behaves like Scheme's let*, so is there a Clojure equivalent of Scheme's let? Would it be useful?

16:54 arohner: dRbiG: I also like count because length implies a 1D view of things that isn't entirely appropriate for e.g. sets

16:54 dRbiG: arohner: good point there

16:55 zakwilson: I have never wanted let from CL/Scheme in Clojure, and usually prefer let* in those languages.

16:59 amalloy: wilfredh: the equivalent is easy with destructuring, but there's not much need for it, and you don't get the (mild) performance benefits

17:00 &(let [a 1, b (inc a)] (let [[a b] [b (inc a)] [a b]))

17:00 sexpbot: java.lang.IllegalArgumentException: let requires an even number of forms in binding vector

17:00 amalloy: &(let [a 1, b (inc a)] (let [[a b] [b (inc a)]] [a b]))

17:00 sexpbot: ⟹ [2 2]

17:00 amalloy: the first let creates some bindings, and the second uses destructuring to assign in parallel

17:01 keithwyss: Hey everybody. I just noticed the other day that on the clojure.org/api pages for the xml and lazy-xml libraries there are a few pubic functions that aren't listed until you view the source. The emit methods are public, but not listed. Also lazy-xml/attributes.

17:01 Is this something that should be changed, or is using those functions discouraged for some reason?

17:06 sean_corfield: mornin' :)

17:07 i'm looking at some clojure code (that i didn't write) and it has (swap! some-atom (fn [_] val)) - isn't that equivalent to (reset! some-atom val) ?

17:07 would there be any reason to use swap! here rather than reset! ?

17:07 amalloy: sean_corfield: maybe it's an effort to make the reader cry

17:09 dRbiG: and another question, i've got a function that takes two arguments - can i expand a thing like *command-line-args* so i won't have to do (first ...) (second ...) on it?

17:09 paraseba: sean_corfield: I've seen the same thing several times, and always ask me why. I don't have an answer yet

17:10 arohner: dRbiG: you could let destructure it

17:10 dRbiG: i want the shortest way to do it

17:10 paraseba: sean_corfield: or the other form: (swap! x (constantly ....))

17:11 dnolen_: ,(let [*args *[1 2 3] [a1 a2 a3] *args*] [a1 a2 a3])

17:11 clojurebot: java.lang.IllegalArgumentException: let requires an even number of forms in binding vector

17:11 arohner: dRbiG: (defn foo [[first_arg second_arg] :as cmd-line-args] ...)

17:11 dnolen_: ,(let [*args* [1 2 3] [a1 a2 a3] *args*] [a1 a2 a3])

17:11 clojurebot: [1 2 3]

17:12 dRbiG: right, so :as seems to be the magic here

17:12 arohner: dRbiG: http://clojure.org/special_forms

17:12 look at let

17:13 dRbiG: i admit i haven't read all the docs so sorry in advance for questions that are already answered there - i'll try to look first though :)

17:14 paraseba: sean_corfield: I think I read somewhere, probably in JoC that you should try to use swap!, without major explanations. And, for instance, fogus unk library uses the (swap! x (constantly form

17:14 arohner: reset! is the right thing to use in that case. it's explicitly what it's designed for

17:15 amalloy: yes, you should use swap! because your functions shouldn't be (constantly ...). if they are, you should use reset!, not least because it makes you question your approach

17:16 paraseba: amalloy: I see...

17:18 amalloy: if you change a mutable value in a way that ignores its current value, you're not managing state very well. there are exceptions to that rule, which is why we have reset!

17:20 paraseba: yes, initialization for instance, when you already know for sure the current value

18:08 chouser: arohner: that change makes sense to me

18:08 But I don't know anything about plans. I've been told not to commit to old contrib anymore, but I haven't heard anything about zip-filter being included in the new contrib.

18:09 arohner: hrm. It should remain "alive"

18:09 I

18:09 I'm currently mapping over all of wikipedia's XML dump with it

18:10 chouser: It seems to me someone who has the authority to create new-contrib projects should say which will be included (eventually, even) and which will not. Those that will not should be "released" from the

18:10 from the Clojure project so authors can take ownership of them themselves.

18:11 amalloy: hey chouser, since we're on the topic, did you get my github message about prxml?

18:11 arohner: right

18:11 chouser: I think that technically the copyright would allow authors to do that now, but it seems a bit rude.

18:11 ibdknox: What exactly is the motivation for removing the contrib libraries?

18:11 chouser: amalloy: I did. Did you see my response?

18:11 amalloy: apparently not

18:11 my inbox is regrettably still empty

18:13 ibdknox: they're too monolithic. to get one function for parsing xml, you need to depend on a jar with a bazillion unrelated .clj files

18:13 (that is, the motivation is that there is "a contrib library", not "contrib libraries")

18:13 ibdknox: ah

18:13 makes sense

18:14 amalloy: unrelated, they seem to have finally merged my changes into the aichallenge, I think we can have more than one file now ;)

18:14 amalloy: oh cool

18:15 huh. i seem to have chosen *not* to follow/fork either your repo or theirs, ibdknox. strange decision

18:15 ibdknox: lol

18:18 dRbiG: another question probably answered somewhere in the manual: how do i define a global value? i don't like the idea of passing stuff all the way down

18:18 amalloy: ibdknox: http://aichallengebeta.hypertriangle.com/starter_packages.php doesn't list it yet, so i gather there's some lag between the git repo and actual reality

18:18 ibdknox: amalloy: I'll keep an eye on it and let you know when it works :)

18:19 dRbiG: just define it at the top of your file? (def my-const 302)

18:19 amalloy: dRbiG: (a) use def or defn; (b) you'd be amazed how much you can do with just lets and lambdas (that is, anything). see www.4clojure.com as an example of a problem-solving site that doesn't allow any defs

18:20 sean_corfield: amalloy paraseba thanx for the input on swap! / reset!

18:25 dRbiG: def doesn't do it ("java.lang.Exception: Unable to resolve symbol:") - btw i actually want a constant, not a variable :)

18:26 dnolen_: dRbiG: 1.3.0-beta1 supports (def ^:const foo bar)

18:26 ibdknox: dRbiG: what was your line?

18:28 amalloy: dRbiG: everything's (basically) a constant already, with the immutable data structures

18:28 dRbiG: ibdknox: you mean the exception line?

18:28 * sean_corfield is fed up with this network :(

18:28 dnolen_: oops I mean (def ^:constant foo bar)

18:28 ibdknox: dRbiG: your def line that you said doesn't work?

18:29 dRbiG: (def root ".") for example

18:29 i guess

18:29 amalloy: dRbiG: well that will work for sure

18:30 dRbiG: the problem is in the other part

18:30 ibdknox: ?

18:30 dRbiG: i'm trying to use it in def - proxy - let

18:30 amalloy: ibdknox: the value he's assigning to the def'd var is an invalid expr

18:31 ibdknox: ah, I see

18:34 paraseba: sean_corfield: do you have any thoughts on how we should test c.j.jdbc? would you use mocking or a real (maybe embedded) database?

18:38 dRbiG: right, all is needed is a forward declaration :)

18:39 mdeboard`: I'm teaching myself Clojure, have a strong Python background but very little formal CS education, so this question might be stupid. When using the word "lazy" in Clojure, e.g. "...`for` returns a lazy `seq` whereas `doseq` is for generating side effects..." (Joy of Clojure) is this the same concept as generator functions/expressions in Python? Or even (forgive me, I know this is far afield) Django QuerySets?

18:39 dRbiG: i'd say it

18:39 is

18:40 mdeboard`: I feel like it is at first blush but I don't want to have a misconception already

18:41 pdk: you could look at it that way

18:41 mdeboard`: Ah, "Most of the sequence library functions are lazy, i.e. functions that return seqs do so incrementally, as they are consumed, and thus consume any seq arguments incrementally as well." http://clojure.org/sequences

18:42 pdk: (for [i (range 5)] (- 1)) would give you a lazy sequence that contains (0 -1 -2 -3 -4)

18:42 mdeboard`: That's about the same as Python generators (I understand there are other differences)

18:42 dnolen_: mdeboard`: generators in Python are not very functional if I'm not mistaken tho right? they are stateful no?

18:42 pdk: doseq always returns nil so it's intended just for producing side effects like printing and i/o on each step of the loop

18:42 amalloy: pdk: if you use (- i) instead of (- 1), anyway :P

18:42 pdk: well

18:43 that's true

18:43 criminy!

18:43 so say if i wanted to print out each value in a sequence on a line

18:43 (doseq [i mysequence] (print i))

18:44 mdeboard`: dnolen_: Yes to the fact they're stateful

18:44 dnolen_: mdeboard`: that makes a fairly big difference.

18:44 mdeboard`: but they ar ea part of Python's functional paradigm

18:45 pdk: you could picture something like a function closed over a ref as an analogy for python generators

18:45 mdeboard`: dnolen_: I see what you mean. I'm not used to thinking about state (at least in some explicit way)

18:47 amalloy: the same underlying mechanism fuels clojure's lazy-seqs and python's generators, but clojure exposes it with a much more functional api

18:49 dnolen_: amalloy: is that true? yield is more like continuations I thought.

18:50 ibdknox: Iterators in C# and VB work similarly, though they also keep state

18:52 mdeboard`: One other thing I'm getting hung up on while reading Joy of Clojure (and other docs) is the notion of "side effects." What I *think* that means is that a function does one thing -- yields a value -- but does not in the course of its operation do anything else. Can someone give me a practical/real world & as simple an example as possible? I've seen references that IO ops are an example of a side effect, but afraid I a

18:52 m not making a connection.

18:52 amalloy: dnolen_: there's not really a big difference. you can implement "yield" as "return a value/thunk pair", with the python runtime building the thunk for you. that's pretty much the same as how lazy-seq works, no?

18:54 ibdknox: mdeboard`: pure functions take a value in and return a value out, nothing else happens. The notion of side effects is when a function changes something outside of itself.

18:55 dnolen_: mdeboard`: Are you asking how it's possible to do something useful w/o side-effects? :)

18:55 mdeboard`: dnolen_: No, not at all.

18:55 dnolen_: ,(print "foo")

18:55 clojurebot: foo

18:55 mdeboard`: dnolen_: I'm asking for a practical example of side effects because I am having trouble coming up with a context

18:55 dnolen_: mdeboard`: print doesn't return a useful value, it's IO

18:56 mdeboard`: ibdknox: Yeah, I get the general idea I guess, looking for a practical example.

18:56 dnolen_: Hm, so, ... hang on.

18:57 dnolen_: e.g. http://p.mattdeboard.net/clos.html, line 4, the println? I put it in there just to see what was going on in internals. Is that an exampel of a side effect?

18:58 dnolen_: mdeboard`: yup.

18:59 ibdknox: mdeboard`: here's a practical example: I have a function to create users for my website. My first implementation simply takes in a name and password and returns back a map with an ID added and the password hashed. This implementation is currently free of side effects. I provide input and it gives me an output.

18:59 mdeboard`: Maybe it's tough for me to contextualize because it's strongly discouraged to have side effects in Python functions. Or, at least, I always try to avoid it since it makes code gross, unwieldy and hard to read/maintain.

19:00 ibdknox: mdeboard`: that's not very useful though, because I haven't stored it somewhere. In my real implementation I add a line to my function that then stores that map in a database.

19:00 mdeboard`: Ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh!

19:00 ibdknox: Now I see

19:00 ibdknox: mdeboard`: now I have a side effect. If I were to create the same user 20 times, I would have the same user in my DB 20 times. Whereas with the pure function I could do it a million times and it wouldn't matter. :)

19:00 dnolen_: mdeboard`: changing the contents of shared dictionary inside of a function - mutation - is also a side-effect.

19:01 mdeboard`: Interesting.

19:01 dnolen_: mdeboard`: your ability to reason about your program just went out the window.

19:03 add some concurrency and you have a real mess.

19:03 mdeboard`: dnolen_: I don't understand that either, though I think that's just because I'm "too close" to Python. It's like being an abused wife. Too close to the situation to recognize how effed up it is.

19:04 dnolen_: mdeboard`: the reason people hate mutable globals is because they decrease your ability to reason about your program. Who knows who changed what where?

19:04 ibdknox: to be fair, side effects aren't bad, per se

19:04 just they have to be monitored intelligently

19:04 and used carefully

19:04 dnolen_: mdeboard`: but even local state changes are hard to keep in your head.

19:05 mdeboard`: dnolen_: re; local state changes, agree completely. Though I am having trouble reasoning through clojure recursion and looping.

19:05 dnolen_: mdeboard`: so Clojure datastructures are immutable, you can't never change anything without it flowing in a functional manner through your code. That is not w/o resorting to the various tools for managing state change.

19:05 mdeboard`: recursion is hard.

19:06 mdeboard`: but once you get it, it's pretty sweet.

19:09 mdeboard`: I mean I kind of get it, I know it's "process the first item from an iterable, then with the result of that process, process (first (rest iterable))" until, say (= (count iterable) 0), but actually putting those steps into practice hurts my brain. I'm trying to rewrite in Clojure this "make change" app I originally wrote in Python for school, and it's eating holes in my brain.

19:10 ANyway, I'm done pissing and moaning, I'm enjoying Clojure. Thanks for all the thoughtful answers.

19:10 amalloy: mdeboard`: chapter 3.2 of On Lisp has a discussion of this that i think is neat

19:10 pdf freely available at http://lib.store.yahoo.net/lib/paulgraham/onlisp.pdf

19:13 the whole book really is fantastic; when you have some time, have a read. the last five chapters or so are still well beyond me

19:15 ibdknox: amalloy: hah! That's awesome, I didn't know it was freely available.. it's damn near impossible to find the book

19:16 dnolen_: hmm is there any such thing as mutually recursive generators in Python?

19:16 mdeboard`: amalloy: Thanks. I'm working my way through Joy of Clojure right now

19:16 amalloy: ibdknox: http://www.paulgraham.com/lisp.html and http://www.paulgraham.com/books.html

19:16 mdeboard`: another excellent book

19:17 mdeboard`: dnolen_: If there is, using them would be extremely inefficient from what I understand.

19:17 amalloy: dnolen_: wouldn't any generator with two different yield statements be mutally-recursive?

19:18 ie, you could write it in clojure as two lazy-seqs that refer to each other

19:19 ibdknox: amalloy: does python allow multiple yeilds? I know C# does

19:19 amalloy: ibdknox: i know jack-all about python

19:20 mdeboard`: ibdknox, amalloy: Yes, with branching logic

19:20 but not try/except

19:21 amalloy: mdeboard`: well. i'm imagining something more like

19:21 yield 1; yield 2; # pretending that semicolons are valid separators

19:21 mdeboard`: Oh, no

19:22 amalloy: mdeboard`: http://linuxgazette.net/100/pramode.html ?

19:22 ibdknox: yeah, C# allows that

19:22 dnolen_: amalloy: yeah this is what I'm talking about generator has to happen inside the same fn

19:22 mdeboard`: amalloy: mind: blown

19:23 I thought yield froze the function and returned to parent context, like "return"

19:23 amalloy: mdeboard`: once you have the facilities for a yield to exist anywhere in a function, adding support for more than one doesn't seem like much work

19:24 dnolen_: mdeboard`: amalloy: I just tried to write a mutually recursive generator in Python, didn't work for me. But perhaps there is way, I don't see any literature anywhere on it.

19:24 mdeboard`: amalloy: I'm not well-versed enough in the "how does that work" area to come to that conclusion :\

19:25 dnolen_: mdeboard`: in case, IHMO lazy-sequences are strictly more powerful general than generators in Python :)

19:26 mdeboard`: lazy-seqs, recur, and trampoline in tangent recover the loss of TCO in Clojure, not as elegant as TCO to be sure, but at least you can implement the literature in Clojure.

19:31 mdeboard`: This isn't mutual recursion, right? Putting on my dunce cap here.

19:31 http://p.mattdeboard.net/foo.py.html

19:32 dnolen_: mdeboard`: not really, bar doesn't call itself.

19:32 mdeboard`: I'm terrible at recursion.

19:33 amalloy: dnolen, mdeboard`: https://gist.github.com/1074054

19:33 dnolen_: mdeboard`: but that may be a good clue as to how it can be done.

19:33 amalloy: demonstration that having multiple yields is equivalent to mutual recursion

19:34 mdeboard`: amalloy: https://gist.github.com/1074055

19:34 dnolen_: amalloy: hardly, first and second could be higher order, impossible in Python.

19:35 amalloy: dnolen_: i don't understand

19:35 dnolen_: first could take a "second", second could take a "first"

19:36 lazy-seqs are not some weird special case the way generators are.

19:36 amalloy: so? python has lambdas and closures

19:37 mdeboard`: "weird special cases"?

19:37 amalloy: i mean, generators are built into the language, yes, in a way i wish they weren't

19:37 dnolen_: amalloy: which can not be transfer yield to each other.

19:37 amalloy: you're talking about continuations now?

19:38 dnolen_: amalloy: no I'm talking about the fact that lazy-seq support a kind of open mutual recursion, yield does not.

19:41 mdeboard`: wait uh

19:45 dnolen_away: What do you mean doesn't support mutual recursion?

19:46 stand by, paste inc

19:58 amalloy: mdeboard`: trying to win an award for longest standby?

19:58 mdeboard`: dnolen_away, amalloy: Mutual recursion? http://p.mattdeboard.net/foo.py.html

19:58 lol

19:58 nice timing!

19:59 er, ignore baz()

19:59 oop

19:59 http://p.mattdeboard.net/foo.py.html

19:59 left out the whole "recur" part

20:00 amalloy: ugh, languages with statement/expression dichotomy make me sad

20:01 if foo yield bar; else yield baz;

20:01 vs (yield (if foo bar baz))

20:02 mdeboard`: Yeah I prefer Python's branch logic syntax less than switch/case syntax.

20:02 amalloy: But point being, isn't that mutual recursion between even & odd?

20:03 amalloy: i think so, but i never needed convincing

20:03 i mean, clearly it's mutual recursion

20:03 mdeboard`: I NEED TO BE RIGHT ON THIS MAN

20:03 But seriously, I know, but the guy who did conveniently disappeared.

20:03 amalloy: but is it mutually-recursive higher-order generators? that's for dnolen to decide, since nobody else is sure what he means

20:10 mdeboard`: If he meant that mutually recursive generators are first-class citizen, then yeah they are (obv). Anyway just a mental exercise on my part

22:04 bdesham: any idea why I get "java.lang.Exception: No dispatch macro for: )" on the last line of <https://gist.github.com/1074160>?

22:06 scottj: replace the # with %

22:06 the last #

22:07 bdesham: oh gosh

22:07 scottj: # is a special character that does something different (dispatches) based on it's next character. like be a set #{} or an anon func #()

22:07 bdesham: that was simple ;-)

22:08 scottj: so anytime you get that message the offending char will follow a #

22:08 bdesham: good to know. thanks!

22:11 ihodes: what kind of tutorials/essays/whatever are needed in the beginner/whatever clojure community right about now? i still need to write my "ins and outs of clojure, pt II"... but aside from that...?

22:12 bdesham: ihodes: I haven't checked recently, but one thing I found overly difficult when getting started was just how to set up source files

22:13 like, if someone gives you a function to try out... where do you put it? if you put it into a .clj file, how do you run it? how do you get a repl to access those functions? ...stuff like that

22:15 ihodes: bdesham: hmmm, good idea. getting started is getting easier, but conceptually no one has really explained it (or have they? where at?)

22:16 mdeboard`: I just started Clojure yesterday

22:16 and want to enthusiastically second bdesham's suggestion

22:17 bdesham: ;-)

22:17 mdeboard`: what's lein? Is it required? I'm using it because I guess that's the only way to get history via up/down arrow keys

22:17 bdesham: mdeboard`: if you have any specific questions, fire away...

22:17 mdeboard`: and tab completion, I think?

22:17 bdesham: oh

22:17 mdeboard`: lein repl > vanilla repl

22:17 afaict

22:17 bdesham: you can use other things for that, like jline, but leiningen is probably the easiest way

22:17 right

22:18 mdeboard`: How are Clojure projects organized? Hell, even something explicitly saying, "The file extension for Clojure files is .clj" would be awesome

22:18 It's a 3-second Google request but still.

22:18 How do I load a .clj file into repl contxt?

22:19 bdesham: leiningen is primarily a build system, in that it'll handle the messy work of initializing a repl (as you've seen), fetching your project's dependencies, testing, and eventually putting everything into a single .jar file

22:19 (err... not sure if you were actually asking, or just suggesting things to ihodes ;-))

22:19 mdeboard`: I'm asking :P

22:19 and suggesting

22:20 I'm p smart and self-educating but still, I know in a month I'm going to look back on my clojure directry structure and facepalm

22:20 bdesham: right

22:20 personally I wish I'd known about leiningen earlier

22:21 mdeboard`: I only knew about it because i use emacs and swank's maintainer wrote leiningen

22:21 bdesham: I started with "Programming Clojure", which is really great, but kind of glosses over these mundane beginning details as far as I can recall

22:21 mdeboard`: so there was some cross-pollination

22:21 Yeah, tutorials tend to skip over things

22:21 really low-level considerations

22:22 bdesham: I'd like to write a tutorial like that, but I'm not sure I have a good enough understanding of how the internals work

22:23 ihodes: mdeboard`: great! tell me more, if you can think of it ;) and ask questions, if you've got any

22:23 mdeboard`: i'd look on the github page for leiningen re: getting started. technomancy has some nice info there as well

22:24 mdeboard`: Yeah I did, followed all that. I'm good on the REPL end (though I could use some auto-indentation and colorization :) )

22:24 ihodes: mdeboard`: including an example project. and getting going with clojure deps etc

22:24 mdeboard`: yeah that would be so nice...maybe I'll get around to it one day ;)

22:24 bdesham: what's the best way to call (time ...) without displaying the output of the call?

22:25 at the repl

22:25 I guess I could just look at the definition of time and have it return nil

22:25 mdeboard`: Here's a question. What does this syntax mean:

22:26 (defn foo [[op & args]]

22:26 ihodes: bdesham: it returns the value of the expression you're timing, and prints the time out

22:26 mdeboard`: the double-brackets

22:26 ihodes: bdesham: so no worries there, i don't think

22:26 mdeboard`: double brackets == destructuring

22:26 mdeboard`: ??

22:27 destructuring is...a concept I Just need to read about?

22:27 bdesham: mdeboard`: yep ;-)

22:27 ihodes: mdeboard`: e.g. (let [[x y] [1 :a]] {x y}) => {1 :a}

22:27 mdeboard`: Alright. I'm reading through Joy of Clojure

22:27 ihodes: mdeboard`: make sense?

22:27 bdesham: it's important, and a useful thing to learn

22:27 ihodes: right, I just want (time) to not return that value

22:27 ihodes: mdeboard`: i think it's in the JoC--been a while since i've read it through. it's definitely a useful think to learn. you can destructure maps, too. which is great.

22:27 bdesham: I'm testing an algorithm by making it do a lot of computations, but I don't actually want to see the output

22:28 I looked at the source for "time" and just replaced the last form with nil, that works fine

22:28 ihodes: bdesham: what's your use scenario? what are you trying to avoid? you could e.g. just do (do (time (first [1])) nil)

22:28 bdesham: or that!

22:29 mdeboard`: oh, destructuring is like uh

22:29 bdesham: ihodes: oh, good idea with the (first ...)

22:29 mdeboard`: is not unfamiliar

22:29 from py

22:29 ihodes: bdesham: the first is just the example algorithm i'm timing ;)

22:29 bdesham: I'm doing something like (take 1000000 <my function>) and all the values overwhelm my terminal

22:29 ihodes: bdesham: so (do (time ALGORITHM HERE) nil) as do just returns the last form

22:30 i'd use `do` i think

22:30 mdeboard`: good -- do you understand sort've my example above? don't know if it was clear enough

22:30 mdeboard`: Yeah

22:30 ihodes: sort of*

22:30 mdeboard`: That's what I used to grok the concept

22:30 bdesham: d'oh... I was thinking first would evaluate the expression and not return the whole thing, but that wouldn't work for lazy sequences ;)

22:31 ihodes: mdeboard`: good. you can do similar things with maps, though it's a little tricker. google "destructuring maps clojure" to get some good info, i'd say. or read JoC ;)

22:31 mdeboard`: that's like uh

22:32 (lambda x,y: {x:y})(1, 'a')

22:34 ihodes: mdeboard`: in a way, i suppose. though that's just a function application there, but the effect is similar. you'll get the hang of it the more you see and use it--feel free to ask any Qs here too

22:45 mdeboard`: wow joy of clojure fisting my third eye

22:46 ihodes: mdeboard`: haha how so?

22:46 mdeboard`: explanation of what state is, difference between mutable & immutable state, and the advantages of immutable state gave me that, "Ohholyshit!" moment of comprehension

22:47 mostly about the nature of OOP

22:47 ihodes: mdeboard`: there you go :) it's such a great read. what langs are you coming from?

22:47 mdeboard`: Python mostly, but some js as well.

22:48 Toyed with lots of others but nothing I'd ever claim any kind of knowledge about

22:49 ihodes: very nice. i like python. welcome to Clojure though! i'm off--being kicked out of my coffee shop. happy coding

22:49 mdeboard`: tt

23:00 Yamazaki-kun: 340-2899999999999999999999999999999999999999999999999999999999999999999999999 opppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

23:00 mdeboard`: arigato gozaimas

23:01 Yamazaki-kun: sorry; my cat apparently really need to say that.

23:02 mdeboard`: Yamazaki-kun: thought you were having issue with floating point

23:02 340.289999999999999999999999999999999999999999999999

23:09 jimi_hendrix: hello, what is the prefered editor for writing clojure?

23:10 mdeboard`: jimi_hendrix: What editor are you used to?

23:10 or, what editor do you normally use?

23:11 jimi_hendrix: mdeboard`, depends. typically i use vim, but i also use eclipse for jvm stuff. i know that emacs is the popular editor in the lisp community

23:11 hiredman: emacs is very popular for clojure as well

23:11 mdeboard`: Yeah I use emacs for everything, personally

23:12 python, js/node, clojure

23:12 tufflax: vim is ok for clojure

23:13 mdeboard`: jimi_hendrix: emacs is popular for lisps because it's written in a lisp, so is well-suited to handling lisp syntax out of the box.

23:13 jimi_hendrix: right

23:13 it also has slime/swank

23:13 tufflax: jimi_hendrix you may wanna look at this or something http://www.deepbluelambda.org/programming/clojure/programming-clojure-with-vim

23:14 i use vimclojure myself and im pretty happy with it

23:14 mdeboard`: jimi_hendrix: Eh slime/swank are a bridge too far for me right now. I'm sure it's handy but I just use vanilla clojure-mode and lein repl. I'm sure vim is fine too

23:14 as long as it has auto-indent & parens matching I can't imagine it mattering too much in the beginning

23:16 i spent a couple hours mucking about with slime/swank yesterday, finally just threw up my hands and am using vanilla clojure-mode. Don't really miss anything.

23:16 Scriptor: as a vim user, I like having a separate window for slime right below the main editor in emacs

23:16 one of the reasons why I started learning it

23:17 mdeboard`: sigh I should probably get slime up-and-running

23:17 tufflax: Scriptor hm what do you mean exactly... main editor?

23:17 Scriptor: tufflax: the window that contains whichever file I'm working on

23:18 just in case anyone is confused, I'm talking about emacs windows...or whatever they called

23:18 jimi_hendrix: Scriptor, i have messed around with slime and that is a very nice feature

23:18 mdeboard`: buffers

23:18 tufflax: ok... but what is emacs? but you are a vim user?

23:18 mdeboard`: http://common-lisp.net/project/slime/images/more-slime.png

23:18 tufflax: thats*

23:19 mdeboard`: tufflax: I think he just means, like, "I am not an emacs zealot and use mostly vim, but I like having slime emacs separate buffers etc etc"

23:19 Scriptor: tufflax: mpost of the time I use vim, but I've been tinkering with clojure using emacs (don't use vim with clojure otherwise)

23:20 tufflax: I've not used emacs a lot but one can get a decent repl and all that in vim too

23:20 Scriptor: yea, but it was just simpler to set up slime/swank with emacs :)

23:20 although I do have vimclojure

23:20 jimi_hendrix: tufflax, i am reading the link you gave me right now. i do very much prefer vim to emacs 99% of the time

23:21 hiredman: when I wrote clojure in vim I prefered to just have a seperate repl running over using vimclojure, but I never use vim anymore

23:24 tufflax: Although I'm new to both vim and emacs, I imagined the basic editing being much nicer in vim, so I went with that

23:24 hiredman: meh

23:24 Scriptor: the super-simplified way of putting it is that vim is the better text editor, emacs the better dev environment

23:24 * Scriptor ducks

23:25 hiredman: I used vim for years, had to switch to emacs for work, so much better

23:25 tufflax: oh yeah? but doesn't your wrists hurt? :p

23:26 hiredman: I think the joke is the pinky starts to hurt

23:27 tufflax: but seriously, why is it so much better?

23:27 hiredman: I have capslock mapped to control, and have for many months now but still haven't gotten into the habbit of using it instead of control

23:27 tufflax: have you ever written vimscript?

23:27 tufflax: just a little

23:27 hiredman: elisp is horrible but it beats the pants off of vimscript

23:27 tufflax: hehe'

23:28 mdeboard`: tufflax: It's so much better iff. you want a fully customizable dev environment

23:28 tufflax: :)

23:28 hiredman: emacs has org-mode which is amazing, all you can write all kinds of crazy extensions

23:28 and

23:28 mdeboard`: and no insert-mode

23:29 hiredman: fullscreen gui emacs on my mac is just so damn pretty

23:29 tufflax: i made a totally new keyboard layout where i bound my caps lock to alt-gr, and have every symbol on the keyboard on alt-gr + letters, its really good with vim

23:29 hiredman: (emacs 24 + the cocoa fullscreen patch)

23:30 mdeboard`: scpaste :)

23:32 hiredman: to be fare vimscript is #11 on the github rankings which is kind of crazy

23:32 elisp is #13

23:32 fair

23:32 I can't believe anyone would put themselves through writing that much vimscript

23:34 jimi_hendrix: vimscript is crazy though

23:34 scottj: also perhaps more elisp projects are included in emacs itself or emacswiki than vimscript projects in vim and whatever

23:34 mdeboard`: Plus, I mean, irc in my editor? Yes pls

23:34 jimi_hendrix: mdeboard`, i tried that. it wasnt that great

23:34 mdeboard`: doin it wrong

23:34 :P

23:35 Scriptor: mdeboard`: emacs is my favorite windows irc client

23:35 jimi_hendrix: idk, i need my xchat

23:35 even though i hate it

23:35 mdeboard`: ...

23:35 jimi_hendrix: its like an abusive relationship

23:36 mdeboard`: people need all these features for IRC, I don't get it

23:36 Scriptor: I love seeing 4 irc channels at the same time

23:36 mdeboard`: tab completion of names, event notifications, auto ID to services is all I really need

23:36 Scriptor: with xchat I'd have to keep tabbing around

23:36 jimi_hendrix: mdeboard`, i barely use any

23:36 hiredman: I get notifications from irssi

23:37 jimi_hendrix: Scriptor, thats true, but many other clients support windows/panels

23:37 hiredman: I have a program that reads the irssi log and sends it to SQS and then I pull it down from SQS and growl it

23:37 costs about $1.20 a month

23:37 mdeboard`: rcirc is a great IRC/IM client. Plus fully scriptable :)

23:38 scottj: hiredman: why now pull it from whatever host you're running irssi on?

23:38 Scriptor: "and doesn't light up like a christmas tree"

23:38 heh

23:38 hiredman: scottj: I could, but SQS is webscale :)

23:39 actually my first version used hornetq running on the host irssi is running on

23:39 scottj: hiredman: hehe :) I do a similar thing with one line of bash

23:39 clojurebot: hiredmans euler.clj is so embarassing

23:39 hiredman: clojurebot: thanks

23:39 clojurebot: thanks for your suggestion, but as usual it is irrelevant

23:39 Scriptor: harsh

23:40 tufflax: haha

23:51 mdeboard`: mmkay just got slime/swank installed for emacs. Wow. Enormous, enormous boost.

Logging service provided by n01se.net