#clojure log - Jan 26 2010

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

0:35 scottj: Is there a shorter way to write (apply str (apply concat '((\1 \0) "," (\0 \0 \0))))?

0:36 hiredman: ugh

0:37 ,flatten

0:37 clojurebot: java.lang.Exception: Unable to resolve symbol: flatten in this context

0:37 hiredman: ,(use 'clojure.contrib.seq-utils)

0:37 clojurebot: nil

0:37 hiredman: ,(reduce str (flatten '((\1 \0) \, (\0 \0 \0))))

0:37 clojurebot: "10,000"

0:39 hiredman: concat, I hate the function, as I hate hell, mutable state, and shellfish

0:41 oh lord, what if flatten uses concat, :(

0:42 scottj: it seems like there should be a way to say do apply with this seq of functions

1:39 Raynes: Is there a map for functions with side effects?

1:39 Something along the lines of (map println ..)

1:40 I could use doseq, but I was wondering if there is a better way.

1:40 hiredman: side-effects + keeping the return value?

1:41 Raynes: Indeed. Like println.

1:41 hiredman: uh

1:41 the result of println is nil

1:41 always, why would you keep that?

1:41 Raynes: I guess I misunderstood you.

1:41 hiredman: for stuff that is completely side-effects doseq is best

1:41 Raynes: In Haskell, we have mapM_ to map a side-effecty function to a list.

1:41 All I needed to know.

1:41 Thank you.

1:42 hiredman: if you want to keep a return value, (comp vec map) is pretty good

1:43 Raynes: I didn't intend to keep the value of println. I simply intended to map println to a list of values.

1:43 :)

1:43 (Just to clarify)

1:45 arbscht: fwiw, there is also dorun. but doseq is nicer imo

1:48 hiredman: for purely side-effect stuff, without a doubt doseq is nicer

1:48 chouser: should have been named dofor

1:48 hm. or maybe not

1:53 qed: chouser: i like dofor, but i think it would encourage familiar for-like usage

1:53 which is probably not the best idea

1:55 screen -r

1:55 Raynes: qed: Heh heh. I have a habit of tying "cd channelname".

1:56 qed: :)

1:56 i will sometimes throw an ls

1:56 screen -r is a new problem

1:56 Raynes: Likewise.

1:57 replaca: scottj: if you're still here - if the goal is to interpose ","s in numbers, cl-format can do that for you

1:57 * hiredman uses screen -ARD

1:57 qed: i often use screen -aASU

1:58 screen -aASU irc irssi

1:58 hiredman: SU are new to me

1:59 oh

1:59 no I know S

1:59 qed: -S sessionname

1:59 When creating a new session, this option can be used to specify a meaningful name for the session. This name

1:59 identifies the session for "screen -list" and "screen -r" actions. It substitutes the default [tty.host]

1:59 hiredman: wait, I know U too

1:59 qed: suffix.

1:59 -U Run screen in UTF-8 mode. This option tells screen that your terminal sends and understands UTF-8 encoded

1:59 whoa.

1:59 hiredman: infact I have screen aliased to 'screen -U'

1:59 and forgot about it I guess

1:59 qed: yeah i aliased 'sn' to screen -aASU

2:00 sr to 'screen -r'

2:00 hiredman: ��� screen

2:00 qed: same

2:00 at work it is the reason im like 40% faster than everyone else

2:01 i just have open screen sessions everywhere and resume them at will

2:01 hiredman: heh

2:02 qed: whenever i log into a box it sames "do you want a screen session?" if i hit Y it nests one for me

2:02 hiredman: wow

2:02 qed: and names according to host

2:03 gregh: has anybody tried tmux (a BSD screen workalike)?

2:03 I tried it for a while but it's hard to undo 10+ years of screen muscle memory

2:03 qed: never tried it

2:03 hiredman: gregh: it's on my radar (since there has been talking of including it in the base FreeBSd system) but I tried it yet

2:04 gregh: it's got some different ideas about sessions and moving them between clients, but I didn't really explore that much

2:04 hiredman: apparently you can get configs that set it up screen like

2:04 gregh: I fired it up with the screen compatibility key bindings and it was close but not quite right

2:04 qed: the majority of boxes i touch are SuSE, RH, AIX, or Ubunru

2:05 Ubuntu

2:05 so i stick with screen

2:05 * hiredman is all freebsd

2:05 qed: hiredman: ever AIX?

2:06 hiredman: hmmm, no

2:06 qed: good. it sucks.

2:06 hiredman: very small amounts of hp-ux

2:06 also sucks

2:06 qed: AIX is based on System V

2:06 need I say more

2:07 chouser: anyone ever use Tru64 a.k.a. Digital Unix?

2:08 qed: no

2:08 ive used Inferno-OS

2:08 that's as exotic as I've gotten

2:08 chouser: that's probably more esoteric than Tru64

2:08 replaca: all this screen talk: http://xkcd.com/686/

2:08 qed: chouser: have you played with inferno?

2:09 inferno..sigh..Limbo could have been Java

2:09 chouser: I was really interested in limbo, once upon a time, but couldn't get my hands on any way to try it out.

2:09 qed: http://en.wikipedia.org/wiki/Limbo_(programming_language)

2:09 chouser: you're the first person I've *ever* met to have an interest in Limbo

2:10 well, outside of that community anyhow

2:10 chouser: I don't remember how I heard about it, or what alternatives I was aware of at that point.

2:10 qed: chouser: the ceremony makes it really tedious

2:10 hiredman: obviously someone needs to target the dis vm with a lisp

2:11 qed: hiredman: google summer of code 2010

2:11 let's do this

2:12 hiredman: haha

2:12 qed: that's how i learned about p9 and inferno actually

2:12 GSoC 2007

2:12 clojurebot: with style and grace

2:12 hiredman: clojurebot: indeed

2:12 clojurebot: Gabh mo leithsc��al?

2:12 qed: clojurebot: love

2:12 clojurebot: I don't understand.

2:12 chouser: oh, I must have heard about limbo circa 1996

2:12 qed: exactly.

2:13 chouser: i'd wager i'm a fair bit younger

2:13 24

2:13 RaceCondition: how much does Clojure differ from Erlang?

2:13 qed: RaceCondition: a lot...

2:13 chouser: qed: not quite a decade, then. :-)

2:13 qed: chouser: :)

2:14 RaceCondition: qed: it's also incredibly similar, so I'd just like to get a better picture of how these two solve the same problems

2:14 Erlang apparently doens't allow changing anything and Clojure does... like refs and atoms... so I assume that dosync/transactions thing makes up for that?

2:14 qed: RaceCondition: their concurrency models are way different, but chouser will probably correct me

2:15 hiredman: clojure is targeted at same process multi-core concurrency, erlang is for distributed concurrency

2:15 qed: (or hiredman)

2:15 ;)

2:15 hiredman: I haven't actually written any erlang

2:15 wiat

2:15 I did

2:15 qed: haha hiredman

2:15 hiredman: I did a hello world tutorial years ago

2:16 qed: "wait...wait...there is directory here which says erlang..."

2:16 "okay...i've written erlang"

2:16 RaceCondition: me neither, but I know you can only assign stuff once and in order to change something, you basically make a tail-recursive call with new state built in that swaps out the old function

2:16 hiredman: yeah

2:16 clojurebot: oo sucks?

2:16 clojurebot: http://www.sics.se/~joe/bluetail/vol1/v1_oo.html

2:16 qed: no tail recursion in clojure

2:16 hiredman: armstrong seems like a cool guy

2:17 qed: hiredman: have you read coders at work?

2:17 hiredman: of course!

2:17 qed: that's one of my favorite interviews in there

2:17 RaceCondition: hiredman: btw I just saw a nice presentation about Clojure and funprog/concurrentprog and I have to admit I was surprised by the slight bashing of OO since OO is not just about objects changing state -- its about polymorphism mostly

2:17 qed: (armstrong's)

2:18 RaceCondition: Haskell has nice OO and you can't argue Haskell isn't pure functional

2:18 qed: RaceCondition: it's about time

2:18 "time"

2:18 that's where the bashing of OO comes from

2:19 RaceCondition: qed: so STATEFUL OO should be bashed, not OO in general, because polymorphism, which is what distinguishes OO from procedural, is orthogonal

2:19 ...to statefulness

2:19 hiredman: RaceCondition: sure, but polymorphism is not only in OO, and OO general brings all this imperative junk

2:19 qed: the general OO philosophy includes stateful OO

2:19 it's how most OO languages operate

2:20 hiredman: RaceCondition: have you read the rationale?

2:20 qed: RaceCondition: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

2:20 RaceCondition: read the rationale or watch that video

2:21 RaceCondition: qed: I just watched one of that guys presentations

2:21 qed: "that guy" is Rich Hickey

2:21 RaceCondition: I know

2:21 qed: lol

2:21 chouser: I think it's the "orientation" rather than the "object" that is the problem.

2:21 qed: just making sure

2:21 hiredman: the rationale has set of points on polymorphism

2:22 RaceCondition: and he did cover state and time management in that other demo as well and I completely understand the rationale behind that

2:22 qed: chouser: what do you mean by orientation

2:22 hiredman: ~rationale

2:22 clojurebot: rationale is http://clojure.org/rationale

2:23 hiredman: it's basically rhickey's N theses

2:23 qed: what really made me stop in my tracks

2:23 was the river quote

2:23 "No man can cross the same river twice."

2:24 chouser: OO is Object Orientation. Clojure has objects but isn't oriented around them.

2:24 hiredman: http://clojure.org/state has some stuff about why rhickey didn't use erlang type actors for clojure

2:25 chouser: pretty much every good and useful feature of OO is available in some form in Clojure, usually a form that is simpler and more cleanly decoupled than standard OO

2:26 qed: the abstract ideas about how a cloud, if you watch it, can become three clouds, or disappear

2:26 that stuff really resonated with me

2:26 chouser: sounds like nice subject to include in a book. Maybe in Chapter two...

2:26 dnolen: is ~(symbol (str sym)) the only way to make anaphoric macros work? (I feel like I've learned this like 20x times)

2:27 * qed wishes he could get paid to learn clojure

2:27 chouser: dnolen: ~'foo

2:27 dnolen: chouser: I get a complaint from compiler if I use that (not the macro, but when I use it later)

2:28 chouser: oh yeah, because it gets qualified

2:28 how to avoid that again?

2:28 hiredman: then you aren't doing it right :P

2:28 dnolen: hiredman: i'm not sure what other where there is it do it with anaphora sir.

2:29 chouser: (defmacro foo [] `(list ~'bar)) (let [bar 5] (foo)) ; returns (5)

2:29 qed: i still dont get macros

2:29 but i havent tried too hard admittedly

2:30 unfo-: qed, i can recommend Programming Clojure - it has a nice chapter on macros

2:30 chouser: as long as you're using a language that has them, you'll hardly ever have to write them.

2:30 dnolen: chouser: huh I swear that is working for me I tried that.

2:30 that isn't working i mean

2:30 qed: unfo-: i got sort of sidetracked on programming clojure at about 125p in

2:30 hiredman: I see macros on lists of why clojure is great a lot

2:31 unfo-: qed, p. 211 :)

2:31 qed, read from there on for the macro chapter

2:31 qed: unfo-: will check it out, thanks

2:32 hiredman: I mean, they are neat, but there are so many other features I use more

2:32 dnolen: macros: you almost never use them but when you really need one, oooh boy.

2:32 qed: i dont totally get multimethods yet either

2:32 which seem even more useful

2:32 hiredman: multimethods, java interop, immutable values, sequences

2:32 ~multimethods

2:32 clojurebot: multimethods seperate the 20% from the 80%

2:33 qed: hiredman: really, mmethods are 80%?

2:33 RaceCondition: btw that {} and [] thing is a read-macro thing?

2:33 dnolen: chouser: or anyone really, see anything suspicious here? http://paste.lisp.org/display/93916

2:35 when I use ~'sym the usage of the macro throws: unable to resolve sym in this context

2:35 hiredman: qed: 20% who get it, and 80% that don't, I think is what is implied

2:35 dnolen: you should look at the macro expansion

2:36 that exception means there is no binding for sym in the expansion

2:36 scottj: replaca: yeah, that was the goal, after writing myself I just ended up wrapping (. (DecimalFormat/getNumberInstance) format 1000.00)

2:36 dnolen: bah ~(symbol (str sym)) is what I want, ~'sym just puts sym there :)

2:36 hiredman: ���

2:36 isn't that what ~(symbol (str sym)) does?

2:37 dnolen: no

2:37 hiredman: you want 'sym not sym

2:37 like the unevaluated symbol sym

2:37 '~'sym

2:37 scottj: Learning Clojure wikibook says . is never a valid symbol. What does that mean? :. seems to be, and obviously . itself isn't because symbols start with :

2:37 hiredman: scottj: no

2:38 scottj: s/valid symbol/valid keyword

2:38 s/because symbols/because keywords

2:38 dnolen: hiredman nope, that produces 'sym in the expansion

2:38 hiredman: right

2:38 which is what you want

2:38 dnolen: no

2:39 hiredman: yes!

2:39 you want the unevaluated symbol sym

2:39 dnolen: I'll paste the difference to illustrate

2:39 hiredman: that is what '~'sym gets you

2:40 I understand the difference

2:40 or not

2:40 dnolen: the macro expansion looks different

2:40 hiredman: lets see it

2:41 dnolen: '~'sym: http://paste.lisp.org/display/93917

2:42 hiredman: lets see with the (symbol ...)

2:42 dnolen: ~(symbol (str sym)): http://paste.lisp.org/display/93918

2:42 clojurebot: "if you never learnt Lisp, then you never learned to program" -- some rant on some blog somewhere

2:43 hiredman: you know, I don't think you want a capture

2:43 you want the sym that is the argument macro right?

2:43 er

2:43 the macro argument

2:43 dnolen: hiredman: yeah

2:43 hiredman: that is not capturing that is unquote

2:43 ~sym

2:43 clojurebot: Titim gan ��ir�� ort.

2:44 qed: all: thanks for the great talk -- have a good night

2:45 dnolen: haha: the danger of not writing making in too long a time. you forget even the most basic rules. sheesh

2:45 not writing macros in too long a time

2:45 hiredman: thx

2:45 hiredman: sure

2:54 G0SUB: any clojure list admins here?

2:54 hiredman: rhickey may be the only one who is an admin

2:55 G0SUB: hmm

2:55 hiredman: maybe chouser

2:55 G0SUB: I want to change my email address... but since I am using Google Apps, I can't find any way to do so.

2:56 So I thought may be they can...

2:56 hiredman: btw, is there any way to use the released version of c.c (1.1.0) with lein?

2:57 hiredman: you should be able to add it to the dependencies

2:57 qed: [clojure "1.1.0"]

2:57 G0SUB: qed: clojure.contrib

2:57 qed: oh sorry

2:57 ive been using 1.0

2:57 i dont know

2:58 hiredman: G0SUB: same

2:58 the contrib builds are up in the build.clojure.org maven repo

2:58 G0SUB: hiredman: I get this -- Unable to resolve artifact: Missing:

2:58 hiredman: hmmm

2:59 I think the seperate "release" repo is new, so you might need to add it

2:59 G0SUB: hiredman: is there any way to add repos?

2:59 hiredman: yes

2:59 it's in the readme, I don't recall off hand

3:00 * G0SUB checks

3:00 hiredman: I do remember it takes a map of names (Strings) to urls (Strings)

3:02 G0SUB: hiredman: can't find it/

3:15 hiredman: :repositories

3:35 RaceCondition: I have to admit I really enjoy those two of Hickey's presentations on InfoQ

3:35 really enlightening and refreshing

3:35 (I hope I won't become a Clojure worshipper after them)

3:37 G0SUB: hiredman: yep. thanks.

3:50 cgrand: G0SUB: pushed a new enlive.jar to clojars

3:50 G0SUB: cgrand: cool. many thanks.

3:50 cgrand: the version id is the same?

3:52 cgrand: yup

3:55 G0SUB: cgrand: works. great.

4:03 esj: cgrand: quick question - in your kata solution for devlinsf yesterday you called (sift ...) explicitly to recur, why not use recur ? Is it just because for a small solution you don't need to worry about the stack ?

4:06 cgrand: esj: let me check but I believe it was in a lazy-seq

4:06 esj: it was

4:07 so that takes care of it for you

4:07 yeah, I'm being stupid

4:07 thanks

4:07 the road to understanding, long it is.

4:08 cgrand: you can' t call recur through a lzy-seq because the lazy-seq macro wraps its body into a fn

4:10 Raynes: Lazy-seqs make me feel all warm and fuzzy inside.

4:11 esj: thanks

4:19 Raynes: I wrote some Python earlier. One function and I still want to hang myself. :|

4:20 gregh: that's odd

4:29 hiredman: ~python

4:29 clojurebot: python is ugly

4:30 Raynes: I concur.

4:32 G0SUB: lol

4:37 spariev_: clojurebot is sure opinionated

4:38 esj: lol

4:38 ~ruby

4:38 clojurebot: Chunky bacon!

4:38 esj: not to taunt or anything

4:39 spariev_: ~java

4:39 clojurebot: ���

4:39 spariev_: lol

4:39 * Raynes lols

4:39 esj: ~clojure

4:39 clojurebot: clojure is far closer to perfection then python

4:40 hiredman: :O

4:40 Raynes: ~hiredman

4:40 clojurebot: hiredman is lazy

4:40 hiredman: ~clojure

4:40 clojurebot: clojure is the bestest programming language available.

4:41 hiredman: ~clojure

4:41 clojurebot: clojure is the brand

4:43 G0SUB: ~java

4:43 clojurebot: ���

4:44 Raynes: ~factor

4:44 clojurebot: Huh?

4:44 Raynes: :\

4:46 cypher23: ~scala

4:46 hiredman: clojurebot: please tell us about scala

4:46 clojurebot: Unfortunately the standard idiom of consuming an infinite/unbounded resource as a stream can be problematic unless you're really careful -- seen in #scala

4:47 hiredman: ~scala {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}

4:47 clojurebot: Any = 1

4:47 hiredman: ~scala work because clojurebot tries to run scala

4:47 er

4:47 doesn't

4:48 cypher23: ah, ok

5:13 esj: cgrand: ok, here's another silly question. If (drop-while ...) returns a lazy sequence, why wrap yours in a (seq ...) ? I notice that it nukes destructuring (to the point of killing the code) if you remove it, but can't understand why. What lorry sized hole is this in my understanding ?

5:14 is is to force the lazy seq to realise ?

5:15 Chousuke: seq returns nil if the lazy seq is empty

5:16 esj: ,(lazy-seq nil)

5:16 clojurebot: ()

5:16 esj: ,(seq nil)

5:16 clojurebot: nil

5:16 esj: funky

5:16 cgrand: esj: it has nothing to do with the "-let" (destructuring) part of the when-let but with the "when" part

5:16 ,(seq (lazy-seq nil))

5:16 clojurebot: nil

5:16 esj: gotcha

5:16 glad I asked, thanks.

5:27 lypanov: well. took a while. but my insanity is over.

5:27 clojure via gwt is the stupidest idea i had in a long time

5:27 esj: :)

5:28 i love those

5:28 lypanov: porting clojure itself to js is the only way

5:28 long showers++

5:29 esj: (inc long-showers), no ?

5:29 ;)

5:29 lypanov: no clue, i haven't yet written a single line of clojure :P

5:30 esj: then your insanity is far from over !

5:32 lypanov: the moment i can slime connect to a clojure instance running in chrome in order to fix a random bug in my webpages layout code

5:33 thats when the insanity is over :)

5:53 ivan_chernetsky: Hi. I've just seen that clojure-contrib moved on to using maven exclusively, so I am curious what's behind this decision? As far as I know using clojure-ant-tasks it is gainable to have a small ant build file. I worry of it because use of maven's complicating the life of distro (at least source-based) package mantainers .

6:03 jlr: is your concern then packaging clojure-contrib projects for e.g. debian or gentoo?

6:10 angerman: cool

6:19 ivan_chernetsky: jlr: Gentoo.

6:20 alexott: angerman: there is also #clojure.de channel ;-)

6:21 angerman: I'm not so certain I want to get localized.

6:21 alexott: angerman: just fyi

6:21 angerman: alexott: thanks

6:55 Hali_303: hi!

7:19 AWizzArd: Is subseq lazy?

7:23 cgrand: do you know why PersistentTreeSet does not implement java.util.SortedSet? That would allow to get .subSets of them.

7:59 Leonidas: ~[6~/win 2

7:59 clojurebot: excusez-moi

8:41 jcromartie: so this is kind of odd...

8:41 ,(clojure.set/difference (set "abc") "abc")

8:42 clojurebot: #{}

8:42 jcromartie: ,(clojure.set/difference (set "abc") "abcd")

8:42 clojurebot: #{\a \b \c}

8:42 jcromartie: ,(clojure.set/difference (set "abc") (set "abcd"))

8:42 clojurebot: #{}

8:42 chouser: clojure.set operations are for the most part undefined unless you pass in sets

8:43 jcromartie: ok but what about the last one?

8:43 chouser: ,(doc clojure.set/difference)

8:44 clojurebot: "([s1] [s1 s2] [s1 s2 & sets]); Return a set that is the first set without elements of the remaining sets"

8:44 esj: its not symmetric

8:44 jcromartie: I see

8:44 chouser: so that's a non-commutative "subtract", not a commutative xor

8:44 esj: would be easy enough to synthesise with a union of the two differences

8:45 (union (diff a b) (diff b a) i'd think

8:50 jcromartie: yeah

8:54 cgrand: AWizzArd: most methods in j.u.SortedSet return Sets while methods in Sorted return seqs, this make that interface harder to implement -- but no real reason

8:56 AWizzArd: cgrand: probably the functions in clojure.set will be helpful enough. I just thought it would be nice to have a (subset ...).

8:56 subseq can sometimes be helpful enough though

8:59 cemerick: using require with :as is of course far cleaner and polite to those that need to read your code, but wow, using :use when you're just trying to hack something out feels so much more productive.

9:03 cgrand: AWizzArd: sure, ask rhickey if you can open a ticket

9:06 AWizzArd: cgrand: yes

9:47 jcromartie: would it be reasonable to patch duck-streams to use a temp file?

9:48 specifically when spitting to a File

9:50 I guess that's kind of specific and doesn't fit with the way it handles writers

9:51 stuartsierra: that would not be ok

9:52 can't guarantee that the process has permission to write anywhere except the file it was told to write to

9:54 jcromartie: gotcha

9:54 well I'm very pleased with my safe atomic spit function :)

9:54 after losing a file

9:55 and after finding a half-written file

9:55 chouser: maybe an option that allows the caller to specify a tempfile name and/or directory?

9:55 jcromartie: and atomic-spit just has a nice ring to it

9:56 stuartsierra: maybe, but that should be a separate function, e.g. write-rename

9:56 jcromartie: http://gist.github.com/286894

9:57 I just hit some of these safety issues pretty quickly while testing my code

9:57 i.e. simulating lots of writes and then bringing down the server

10:11 * stuartsierra is rewriting str-utils2

10:11 AWizzArd: stuartsierra: why?

10:11 saml: is there a library for command line option parsing?

10:12 stuartsierra: AWizzArd: see http://groups.google.com/group/clojure-dev/browse_thread/thread/7ab69b1d43012917#

10:12 saml: command-line

10:13 stuartsierra: Thinking about making str-utils2/replace a macro that dispatches on types at compile time.

10:14 chouser: whoa

10:14 really?

10:14 stuartsierra: Well, multimethods are slow, and 99% of the time you're going to call 'replace' with literal arguments

10:14 AWizzArd: hmm

10:15 chouser: saml: clojure.contrib.command-line is there, though not terribly advanced.

10:15 saml: chouser: yup. it seems like it binds positional arguments to symbols

10:15 stuartsierra: It could fall back on a multimethod if the types are unknown at compile time.

10:15 saml: that's all i need for now :P

10:16 chouser: stuartsierra: by "unknown" you mean "symbols"?

10:16 stuartsierra: chouser: or expressions

10:16 chouser: ah, sure.

10:17 hm, and if you make it :inline instead of always a macro, it could still be used with comp for our point-free friends, map, etc.

10:18 stuartsierra: Hmm...

10:18 I'd have to figure out exactly how :inline works.

10:19 saml: *command-line-args* this is global variable for command line arguments?

10:19 chouser: stuartsierra: won't take you long. :-)

10:19 stuartsierra: heh

10:19 chouser: saml: yes

10:19 saml: oh to get that i need to launch through command line. not in emacs

10:20 silly me

10:26 java -cp clojure.jar clojure.main /path/to/myscript.clj arg1 arg2 arg3 how can I get things before arg1 arg2 arg3 ?

10:26 stuartsierra: Actually, a macro could do compile-time checking for anything.

10:27 Any multimethod that dispatches on type can theoretically be resolved at compile time.

10:34 chouser: stuartsierra: you mean if the args are hinted?

10:34 stuartsierra: yes

10:34 or literals

10:38 the tricky part is how to abstract that into a macro

10:39 * stuartsierra just pushed str-utils3

10:40 saml: to read text file, do I use java interop?

10:42 grammati: ,(doc slurp)

10:42 clojurebot: "([f] [f enc]); Reads the file named by f using the encoding enc into a string and returns it."

10:44 saml: grammati: thanks

10:45 how do I know current working directory of the repl?

10:45 chouser: saml: but yes, anything slightly complicated and you'll probably have to fall back on interop calls.

10:46 (System/getProperty "user.dir")

10:47 the jvm doesn't let you chdir

10:47 LauJensen: (defn pf [s & args] (println (format s args)))

10:47 Is there some & related trickery I can do to make this work w/o using a macro

10:48 chouser: apply

10:52 LauJensen: how?

10:52 clojurebot: with style and grace

10:56 neotyk: clojurebot: are you the smartest in your family?

10:56 clojurebot: Titim gan ��ir�� ort.

11:27 jcromartie: so those of you using Java IDEs... what is your preference: NetBeans or Eclipse?

11:28 LauJensen: Emacs

11:28 (sorry, couldnt help myself!! :P)

11:31 jcromartie: ...

11:31 I use Emacs too.

11:32 spariev_: I tried IDEA and netbeans Clojure plugins, but Emacs is better

11:33 I'm still the IDEA fan for java/ruby thought

11:34 jcromartie: NetBeans looks nice on SO X

11:34 OS X

11:35 it almost feels like a human being designed it

11:36 jasapp: heh

11:37 jcromartie: my concern is in having others collaborate on a clojure project that might not be quite ready for Emacs

11:38 zero emacs experience makes for fun times

11:39 spariev_: I believe netbean's enclojure is the most polished Clojure IDE plugin as for now

11:39 esj: don't let anybody tell you that emacs stands for esc-meta-alt-ctl-shift, entirely untrue and misleading ;)

11:39 jcromartie: hah hah

11:39 spariev_: heh

11:39 caljunior: emacs schmemacs. :-) I'm having an issue using incanter with TextMate.

11:40 jasapp: I love emacs now, don't get me wrong.

11:40 but learning to use it was one of the most frustrating things I've ever done

11:40 after 7 or 8 years of being a vim guy

11:40 caljunior: when I try to load incanter in the repl with: (use '(incanter core))

11:41 I get this exception: java.lang.IllegalStateException: copy already refers to: #'clojure.contrib.duck-streams/copy in namespace: user (NO_SOURCE_FILE:0)

11:43 lypanov: jasapp: i use viper

11:43 caljunior: is this the prebuilt incanter version (incanter-app-*.jar clashing with clojure which is actually required for running code from TextMate?

11:43 lypanov: jcromartie: netbeans. eclipse is ... yeah.

11:43 but i'd rather suggest idea if you have the option.

11:44 caljunior: I realise this is a less than interesting issue.

11:44 stuartsierra: hey, where's my paste?

11:45 Compile-time type-checking multimethods: http://paste.lisp.org/+20HG

11:46 cgrand: stuartsierra: lispbot seems aphonic since yesterday

11:46 jasapp: lypanov: I tried using viper, but that just made things worse for me

11:46 caljunior: got the answer directly from david liebke: should require not use. thanks David.

11:46 jasapp: I think it was trying to use emacs, viper, and slime

11:46 all while trying to learn to use emacs

11:47 AWizzArd: ,(instance? String "x")

11:47 clojurebot: true

11:47 AWizzArd: ,(time (dotimes [i 1000000] (instance? String "x")))

11:47 clojurebot: "Elapsed time: 159.273 msecs"

11:48 lypanov: jasapp: yeah. its painful. i'm just taking breaks whenever i feel like my skull might crack

11:48 AWizzArd: Interesting. This dotimes above gives on my system: (class: my/ns$eval__15603$fn__15604, method: invoke signature: ()Ljava/lang/Object;) Unable to pop operand off an empty stack

11:49 joegg: cgrand: aphonic is a great word. vocab++

11:53 esj: ,(distinct '(1 2 2))

11:53 clojurebot: (1 2)

11:53 esj: ,(distinct? '(1 2 2))

11:53 clojurebot: true

11:53 esj: ?

11:54 stuartsierra: ,(apply distinct? '(1 2 2))

11:54 clojurebot: false

11:54 AWizzArd: maybe compile time constants

11:54 esj: aaah apply

11:54 thanks

11:58 would it be useful to be able to attach some textual explanation to :pre and :post assertion exceptions ?

11:58 joegg: I want to write a simplex solver to help with my clojure-learning, and I'm having trouble coming with how to represent the system of equations using clojure data structures. Something like a list of maps of variables onto coefficients would probably work, but then I'm worried about the fact these structures are immutable, and I just don't see how I would interact with the thing. Can anyone point me to some knowledge?

11:59 esj: joegg: have you tried Incanter ?

11:59 it backs into a bunch of numerical libraries

12:00 has things like linear regressions etc, so you'll find representations such as you're looking for

12:00 joegg: esj: That's a good suggestion, and I might look to for inspiration, but (and I know this is crazy), I don't want to pull in *any* libraries. The whole exercise is to do it myself, it's a kata.

12:01 I will see how they represent these structures, though. Excellent suggestion.

12:01 Thanks!

12:01 esj: groovy.

12:02 * technomancy is always hesitant to use the word "groovy" as an adjective since it could be mistaken for a noun

12:03 joegg: technomancy: Bruce Campbell never mistakes it for a noun. :)

12:04 * esj reaches for soap to wash out mouth. Oops.

12:04 technomancy: joegg: perhaps if it were followed by the sound of a shotgun being loaded the ambiguity would fade.

12:04 esj: ~groovy

12:04 clojurebot: I don't understand.

12:04 esj: just checking clojurebot...

12:06 Mec: How come you cant chat in here as a guest?

12:06 esj: spammers

12:06 joegg: ,(do (load shotgun)) (println "Groovy."))

12:06 clojurebot: java.lang.Exception: Unable to resolve symbol: shotgun in this context

12:06 joegg: Something is wrong.

12:11 * jcromartie works on his shotgun lib

12:13 the-kenny: dan

12:13 oops

12:15 esj: is is possible to customise the sort function applied by (sorted-map ...) ?

12:16 or is that all kinds a crazy ?

12:16 chouser: sorted-map-by

12:16 esj: !

12:17 thanks a ton, that's awesome.

12:17 chouser: be careful -- if you say two keys are equal, it'll only store one of them.

12:17 esj: thanks, that could be unexpected.

12:18 chouser: ,(sorted-map-by (constantly 0) :a 1, :b 2, :c 3)

12:18 clojurebot: {:a 3}

12:27 Mec: I'm going to lose my mind trying to get an IDE to work

12:31 contrib is encluded in my enclojure project but it keeps telling me no contrib classes exist

12:32 stuartsierra: Mec: start with the command line, then work up to an IDE

12:44 saml: can I extend a java class in clojure?

12:45 oh java_interop has section about Implementing Interfaces and Extending Classes

13:09 noidi: is there a way to refer to the current namespace?

13:09 chouser: *ns*

13:09 noidi: I have a function called foobar/set! and it worked fine, but now I want to refer to it from another function in the same namespace, and *ns*/set! doesn't seem to work

13:09 and just plain set! doesn't work because it's a special form

13:11 I get "No such namespace: *ns*" when evaluating the file in slime with C-c C-k

13:11 chouser: oh. yeah, I don't think you can get away with a var named 'set!'

13:11 noidi: I can as long as I don't need it within the namespace :)

13:11 but thanks, I'll rename it to set-data!

13:11 clojurebot: clojure-alpha was renamed clojure-master, and this broke most of the projects on Clojars

13:12 chouser: if it were just a macro of fn, you could get away with it, but special forms will cause you trouble

13:13 Chousuke: noidi: *ns* is a variable

13:13 noidi: you'd have to do the.namespace/set!

13:14 alexyk: how do folks structure something like .clojurerc, to be loaded into each repl?

13:15 i.e. how do you auto-load it?

13:15 noidi: depends on how you launch your repl :)

13:15 alexyk: better not to depend on it :)

13:16 noidi: there's the -i command line flag for clojure.main, you could add that to the script than launches the repl

13:17 alexyk: ah ok

13:17 noidi: java -cp ... clojure.main -i clojurerc.clj

13:17 BrandonW: all right! class path talk!

13:17 that is just what i came in here to ask :)

13:18 Chousuke: :P

13:18 alexyk: class of 2010

13:18 Chousuke: note that the classpath was omitted.

13:18 alexyk: the working class

13:18 Chousuke: in other news, by qnap HDD was making some nasty click noises earlier :(

13:19 it seems to have calmed down now though.

13:19 alexyk: Chousuke: Time Machine!

13:19 or gibak

13:19 somnium: alexyk: if you put a user.clj on the classpath it will get autoloaded

13:19 Chousuke: alexyk: it's RAID1; and a relatively new installation anyway. there's nothing to back up

13:19 alexyk: somnium: oh! now that's autoloading indeed

13:20 BrandonW: okay, so i am going through the programming clojure book and i am currently trying to generate a java class file via clojure's :gen-class

13:20 alexyk: Chousuke: it hurts even to read of clicking noises! :)

13:20 Chousuke: alexyk: it just sucks. the hdds are about six months old

13:20 alexyk: I have a six year old HDD that's still going strong.

13:20 BrandonW: the start of my tasklist.clj file is (ns reader.tasklist, so it is the reader package, class tasklist

13:20 Chousuke: what's wrong with modern ones :(

13:20 alexyk: Chousuke: we need to add a few terabytes here and there, too. Did you get some cheap SATA?

13:21 BrandonW: that file is in com/reader/tasklist.clj

13:21 i start the clj repl in com directory (with no additional args)

13:21 type (compile 'reader.tasklist)

13:21 Chousuke: alexyk: I bought 2*1.5TB from a friend. he still has the receipts though so if the drives fail now I can get new ones through warranty

13:21 alexyk: So I'd rather they fail NOW than after two years when they're full of data and out of warranty...

13:21 BrandonW: and it says No such file or directory (tasklist:clj:1)

13:22 alexyk: Chousuke: hope just one is clicking! there's all those urban legends that RAID'ed disks fail together etc.

13:22 BrandonW: unfortunately i am coming to clojure from c# :( i had some experience with java in college, but it was academic computer science, so i didn't get much experience with jars and class path. i looked up a bit on google but i feel like i am missing something very fundamental...

13:22 Chousuke: alexyk: it should be jut one. right now, neither is making any noise, though.

13:23 alexyk: but it was a really nasty tick-tock noise it made earlier...

13:23 lypanov: i sometimes here that for a drivethats been going without issues for 1.5 years

13:23 dunno why

13:24 Chousuke: hmm :/

13:24 now I ran aptitude and no ticking noises. hm

13:25 alexyk: ok to BrandonW's question: should the dirs with the actual files be on the classpath?

13:25 jasapp: Chousuke: maybe a little shaking would help

13:25 alexyk: I actually call my namespaces whatever with the dot and don't consider it as a path part or anything

13:25 BrandonW: from teh quick research i did on class paths, i *think* the directory you start java/clj from is added automatically

13:25 Chousuke: jasapp: I'll try that if the clicking resumes...

13:26 alexyk: BrandonW: did you try adding the actual directory containing the tasklist.clj file to the path?

13:26 tools like lein repl or maven clojure:repl do that for you

13:26 jasapp: Chousuke: I meant to induce more ticking

13:26 BrandonW: and from what i've read of java classpath usage, it is supposed to be in reverse domain form (e.g. org.clojure.xxx) and it usually maps to directory structure

13:26 Chousuke: hm.

13:26 now it made a couple ticks again. :(

13:26 Mec: Is there a namespace tutorial anywhere? refer use require import ns *head explode*

13:26 BrandonW: and i could do that via clj -cp ./reader

13:27 right?

13:27 lypanov: BrandonW: fwiw, i don't use classpaths. lein repl takes care of all that for me. i'd suggest trying leiningen therefore if what you really want to do is learn clojure not java classpath nasties :)

13:27 BrandonW: well

13:27 i would like to eventually use it at work if i can

13:27 alexyk: BrandonW: I always load things by their full path, (load-file "meat/subdir/file.clj")

13:28 BrandonW: in which case i will probably have to deal with class paths anyways :P

13:28 alexyk: meat is a symlink into the maven guts, e.g. meat -> com/domain/somedir

13:28 BrandonW: when compiling though, you don't give it a full path, you gave it a package/class i think, right?

13:29 alexyk: BrandonW: I don't really compile, you load and it's compiled for you.

13:29 noidi: Mec, what do you find confusing?

13:29 technomancy: Mec: use and import is all you need to get started

13:29 alexyk: the senior comrades will correct me, but you don't really need to compile clojure

13:29 technomancy: "use" for clojure code, "import" for java classes

13:29 Mec: how do I only take a few functions from a lib without using the whole thing?

13:29 BrandonW: i'm working on the programming clojure book, on the chapter where you generate java class files in teh filesystem

13:30 alexyk: ah, ok

13:30 technomancy: Mec: it's best to have something like (:use [clojure.contrib.duck-streams :only [slurp* writer]])

13:30 BrandonW: so i could load the file, but i would still need a qualified package/class name (i think) to compile it with the compile function

13:30 alexyk: I wish that chapter would move to the end of the book

13:30 BrandonW: yeah

13:30 alexyk: to non-Java people it's confusing

13:30 Mec: ah hah, i was missing a set of braces

13:30 BrandonW: i don't know that i would ever generate java class files in clojure, so i wasn't putting much thought into it

13:30 if class path issues like this normally don't crop up in clojure, then i'm okay with skipping it :)

13:30 technomancy: Mec: (in your ns form at the top; it's different if you're using it outside ns)

13:30 alexyk: totally unnecessary to throw all that Java crap into the middle of the pretty gugrgling stream of FP

13:30 lypanov: heh

13:31 DeusExPikachu: anything like etypecase (from CL) in clojure?

13:31 alexyk: DeusExPikachu: sounds like the name of a protein

13:32 * alexyk confesses he's waiting for a big load from database to finish

13:33 DeusExPikachu: alexyk: heh

13:38 alexyk: DeusExPikachu: cool nick btw :)

13:39 DeusExPikachu: alexyk: I've had it for the longest time, since 2000 I believe, came from the video game Deus Ex and you know what else

13:52 alexyk_: I notice my repl slow down significantly after some usage. I launch a 64-bit server JVM with compressed references and -Xmx30g, than see it reach 28g usage, then shrink back to 10g, and go 5 times slower on the same database load from mongo. I use transients to assemble the load back. Is there any knob to adjust?

13:52 StartsWithK: how do i compare two symbols? (declare x) (defn is-x? [s] (or (= 'x s) (= `x s)) works if i (use) namespace with 'x and 'is-x?, but if i do something as (require '[foo :as f]) (f/is-x? 'f/x) it returns false

13:53 somnium: ,(= 'foo 'bar/foo)

13:53 clojurebot: false

13:54 Mec: (= (name x) (name y))

13:54 somnium: ,(= 'foo (name 'bar/foo))

13:54 clojurebot: false

13:54 somnium: doh

13:54 Mec: ,(= (name 'foo) (name 'bar/foo))

13:54 clojurebot: true

13:54 hiredman: but those two symbols are not equivilent

13:54 alexyk_: that's deep

13:55 hiredman: .(= 'foo 'bar/foo)

13:55 ,(= 'foo 'bar/foo)

13:55 clojurebot: false

13:55 alexyk_: somnium: did you notice mongo slowdown after usage in the same repl?

13:56 somnium: alexyk_: Its lightning fast for all my loads, which have topped out around a million entries or so

13:57 StartsWithK: it works ok if i don't use aliased name, is there a way to force 'f/x to expand to 'foo/x?

13:59 somnium: alexyk: except when I accidentally print the database without setting print length, thats when I usually go refill my coffee or kill emacs

13:59 chouser: `f/x

13:59 alexyk: somnium: if I do that. it would print the whole twitter :)

14:00 would need three tons of coffee

14:00 btw how do I set that print limit again?

14:00 somnium: set! *print-length* 42

14:01 the-kenny: somnium: You forgot the parens!

14:01 alexyk: somnium: I feel like a plumber with a blob of sh*t somewhere. It definitely gets clogged, but whether it's the server, teh JVM, the mongo or the repl, who knows

14:01 the-kenny: somnium: Did your session ran out of parens?

14:01 jasapp: alexyk: how many tweets are you up to now?

14:01 alexyk: the-kenny: can you imagine parens? :)

14:02 jasapp: I use a research set of 100 million. I have overall a few billions I think.

14:02 StartsWithK: chouser, how do i call ` my self, as in '(f/x 1) i would like to `f/x first argument only?

14:02 jasapp: any exciting trends you've noticed?

14:03 alexyk: jasapp: a lot of small things. I need to notice something exciting by the KDD deadline!

14:03 jasapp: I played around with twitter for a week until the poor spelling and bad grammar got too depressing.

14:04 kdd?

14:04 alexyk: I was effing with transients for a few days before I started to get my data quickly into repl.

14:04 somnium: I misplaced my father's parens for a moment

14:04 alexyk: kdd.org

14:05 jasapp: since Oprah started using twitter in bed, you have no excuse not to

14:05 jasapp: haha

14:05 BrandonW: finally!

14:05 i figured out my problem :)

14:06 i got mildly obsessed with figuring the stupid thing out so i had to keep bashing my head against the metaphorical class path wall :(

14:06 somnium: alexyk: you should team up with these guys >> http://noosphere.princeton.edu/

14:06 BrandonW: my problem was i needed to have a classes sub-directory in the directory i started the repl from

14:06 and that *also* needed to be in the class path

14:07 so basically, i had to start clj like: clj -cp classes (after already making the classes subdirectory, which didn't exist before)

14:08 hiredman: so, exactly what it says to do on the page about compilation on clojure.org?

14:08 fractalis: /join #emacs


14:08 Sorry, ignore that.

14:09 jasapp: emacs? who uses emacs? ;)

14:09 fractalis: lol

14:10 hiredman: clojurebot: emacs?

14:10 clojurebot: emacs is an out-moded belief system

14:11 technomancy: classics never go out of style

14:11 * technomancy waits for the ed fans to jump out of the woodwork

14:11 alexyk: technomancy: ran ed on iphone. Did you run emacs on it?

14:11 BrandonW: ah hiredman that would have helped had you linked me to it earlier

14:12 all i had was the book and (doc compile)

14:12 technomancy: alexyk: that's against the TOS!

14:12 alexyk: try to mess up your term and not be able to find the current line. ed saves the day!

14:12 BrandonW: which gave me enough to figure it out, but took a while as a non-java programmer

14:12 alexyk: technomancy: that was before Steve Jobs told me to stop it

14:12 technomancy: I hope he asked nicely.

14:13 alexyk: BrandonW: same here. I just cook the classpath in zsh now. leiningen puts things into lib/ with lein deps, then I say: JARS=( lib/*.jar ); LIB=${(j.:.)JARS}; CLASSPATH="$LIB${CLASSPATH:+:$CLASSPATH}"

14:14 and that's it :)

14:14 BrandonW: the classes part of the classpath are what screwed me up, i saw classes on the sample shell script of code that came with the book, but i didn't know that i actually had to create the classes directory

14:14 i thought it would automatically generate it for me or something :O

14:14 i don't mind it so much now that i understand how it works

14:15 while i was looking around various bits of docs i saw a reference to .clojurerc which i think will be very nice in setting up projects

14:16 i will check out lein though

14:16 alexyk: technomancy: in fact I repented and went back into the warm ATT fold, to sync my stuff with OmniFocus and Things.

14:16 BrandonW: i've seen that mentioned in various places

14:16 alexyk: and, we have the leiningen field marshal here, prof. dr. technomancy

14:16 and it's really cool, except it effs up repl still

14:17 technomancy: yup... that's due to not being able to get a hold of the original I/O streams from inside a call to clojure.main/repl.

14:17 StartsWithK: why if i do (require '[foo :as f]) (find-ns 'f) it return false, but (find-ns 'foo) return true

14:17 BrandonW: actually while i'm here, i'm curious: how many people jazz up the standard repl and use that, and how many people use an in-place repl a la swank or vimclojure or the netbeans plugin?

14:17 technomancy: next release is going to print out a warning when you do "lein repl" and suggest use of swank or nailgun instead

14:18 unless someone comes up with a clever fix post haste

14:18 BrandonW: also, now that you have mentioend lein a couple of times and i am checking it out, how does lancet (the build tool you build in programing clojure) compare to it?

14:18 is lancet useful at all, or is it more of a proof of concept?

14:18 technomancy: BrandonW: lancet is useful as a library, not as a build tool.

14:18 leiningen uses it to call ant tasks

14:18 BrandonW: ah right

14:20 well thanks very much for the classpath help and the pointer to lein :) have a great day

14:23 StartsWithK: uf.. (defn real-ns [s] (let [sn (symbol (namespace s))] (ns-name (or (find-ns sn) (get (ns-aliases *ns*) sn))))), is there a bether way to do this?

14:27 alexyk: ,(set! *print-limit* 42)

14:27 clojurebot: java.lang.Exception: Unable to resolve symbol: *print-limit* in this context

14:27 alexyk: something else?

14:27 somnium: length?

14:27 clojurebot: count

14:27 alexyk: ah

14:27 clojurebot: don't talk unless talked too, as a good Victorian servant

14:27 clojurebot: a is t

14:27 somnium: I put all the sets into a (user!) fn in my user.clj so I can forget these things

14:28 chouser: StartsWithK: s is a symbol?

14:28 StartsWithK: yes

14:28 chouser: which may have a namespace?

14:29 alexyk: ,(set! *print-length* 42)

14:29 clojurebot: java.lang.IllegalStateException: Can't change/establish root binding of: *print-length* with set

14:29 StartsWithK: yes, but a namespace can be in aliased form

14:29 alexyk: I was wondering if we can hack GAE, but nope

14:29 StartsWithK: like 'f/x or 'foo/x in my example

14:30 i am looking in "make easier to switch between -> and ->>" patch by cgrand, as it looks like we are doing the same thing

14:31 he has a line "if (and (#{'-> '->> `-> `->>} form) (not (contains? &env form)))"

14:31 but that too will not work if i alias the core

14:31 chouser: (symbol (namespace (read-string (str "::" s))))

14:32 alexyk: somnium: thx mucho! the very next print I tried after setting the limit would have printed 100 million things. This user! is a must.

14:32 chouser: I think what you really want is clojure.lang.Compiler/namespaceFor, but it's private

14:32 dnolen: is there anything in contrib for converting a string into an inputstream?

14:32 StartsWithK: will that pach then have the sam problem as me?

14:32 chouser: ,(with-in-str "hello" (.read *in*))

14:32 clojurebot: 104

14:33 StartsWithK: it's easy to miss in core as you usualy don't alias it by another name

14:33 chouser: StartsWithK: I don't see how an alias for core would cause a problem for cgrand's patch

14:34 StartsWithK: `-> and '-> will not match 'core/-> if clojure.core is aliased to 'core

14:35 alexyk: how do I list the names defined so far in ns again?

14:35 StartsWithK: alexyk, (ns-interns *ns*)

14:36 alexyk: StartsWithK: thx!

14:36 chouser: StartsWithK: ah, I see. if you alias and then try to use the aliased name. hrm.

14:37 alexyk: now, how can I filter the result of ns-interns by whether it's a function or a value?

14:38 ...which is not a function? :)

14:38 vagif: hello, i'm reading the source code of contrib.sql.internal

14:38 http://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/sql/internal.clj

14:38 and i cannot find where the function resultset-seq is defined

14:39 chouser: ,(map key (filter #(-> % val deref fn?) (ns-publics 'clojure.core)))

14:39 clojurebot: java.lang.RuntimeException: java.lang.IllegalStateException: Var clojure.core/*3 is unbound.

14:40 chouser: vagif: it's actually built in -- clojure.core/resultset-seq

14:41 StartsWithK: alexyk, they are all Vars, if you want to check is valu of the var a function, try (map (fn [[k v]] [k (fn? (var-get v))]) (ns-interns *ns*))

14:42 vagif: chouser: thx

14:43 somnium: ,(-> 'clojure-is fn?)

14:43 clojurebot: false

14:43 somnium: ,(-> 'clojure-is ifn?)

14:43 clojurebot: true

14:43 somnium: :/

14:44 cgrand: StartsWithK: (and (#{#'-> #'->>} (resolve form)) (not (contains? &env form))) ; should be better

14:44 alexyk: StartsWithK: thx! I did this to see fns: (->> (map (fn [[k v]] [k (fn? (var-get v))]) (ns-interns *ns*)) (filter second) (map first))

14:44 ,(->> (map (fn [[k v]] [k (fn? (var-get v))]) (ns-interns *ns*)) (filter second) (map first))

14:44 clojurebot: ()

14:45 cgrand: (except that resolve is defined after ->)

14:46 chouser: ,(resolve '(foo bar))

14:46 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

14:47 chouser: rhickey is mia today. wonder what he's up to.

14:48 StartsWithK: cgrand, that works in my case too

14:49 cgrand: chouser: right, (and (symbol? form) (#{#'-> #'->>} (resolve form)) (not (contains? &env form)))

14:50 StartsWithK: alexyk, just watch for unbound vars, check each 'v with (.isBound v) or you my get a exception when you try var-get

14:51 alexyk: ok

14:51 StartsWithK: try something like (declare c)

14:52 lisppaste8, help

15:08 AWizzArd: ~seen rhickey

15:08 clojurebot: rhickey was last seen quiting IRC, 1835 minutes ago

15:13 chouser: oh, he apparently gave a talk at DRW today, whatever that is.

15:16 dnolen: yes

15:17 oops, ignore that.

15:17 alexyk: ,1835/60

15:17 clojurebot: 367/12

15:17 alexyk: ,(/ 1835 60)

15:17 clojurebot: 367/12

15:18 alexyk: ,(quot 1835 60)

15:18 clojurebot: 30

15:19 AWizzArd: chouser: good

15:19 I just watch him on Channel 9

15:19 chouser: I can't figure out what DRW is

15:20 AWizzArd: Soon we���ll know :)

15:20 alexyk: I'm getting objects from a database, then insert into a transient. How can I parallelize it?

15:20 jasapp: I thought of DSW, immediately, for some reason.

15:20 chouser: AWizzArd: link?

15:20 alexyk: I'd like to have one thread loading things and converting, and another to insert them into the transient when ready

15:20 AWizzArd: http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Rich-Hickey-and-Brian-Beckman-Inside-Clojure/

15:21 alexyk: "I went deep, man. Deep."

15:21 chouser: AWizzArd: ah, thanks. yeah, I've seen that.

15:22 and twitter posts saying #DRW don't help

15:23 alexyk: somnium: so there's a clear slowdown, even for the version with the cursor.

15:23 somnium: would putting a transient map in an agent and sending it things to conj! from multiple threads be reasonable?

15:24 alexyk: how many cores are you working with?

15:24 chouser: oh! DRW, Cloure funder: http://www.drw.com/

15:24 alexyk: somnium: since mongo is not parallel yet, I can have only one cursor anyways, right? 8 cores.

15:24 StartsWithK: well drw = doctor who :)

15:25 alexyk: What really bothers me is that on a virgin JVM, I do my fetch-graph version in 15 minutes; now it will go to 3 hours.

15:25 At some point memory usage was 28g out of 31g, now is back to 12g, and fetch is going very slow

15:25 nothing else really happened

15:25 somnium: alexyk: but you could make 7 mongods

15:25 I think

15:26 alexyk: somnium: true. Would I then divide work by issuing partitioned queries?

15:26 AWizzArd: alexyk: is that a g as in "gigabytes"?

15:26 alexyk: AWizzArd: yep

15:27 AWizzArd: is that the amount of RAM your system has?

15:27 alexyk: AWizzArd: it's a 64g box

15:27 really need a 256g for this

15:28 somnium: alexyk: maybe ask in #mongodb if that would let you get multiple cursors

15:29 alexyk: somnium: yeah...

15:29 somnium: you could do it with one read thread and a conj! agent but I suspect the overhead would neutralize the benefit

15:29 alexyk: somnium: so any clue what may clog congomongo meanwhile? I do assoc! now instead of conj!, not to waste space twice, btw.

15:30 somnium: alexyk: hard to say whats happening

15:31 alexyk: an identical fetch slows down 10 times, kind of... I wonder whether we can profile mongo-java-driver and congomongo separately

15:31 somnium: alexyk: all the other users (who have commented to me) have said its plenty fast enough, but theyre not juggling terabytes

15:32 alexyk: somnium: it's not terabytes yet! a few puny gigabytes

15:32 somnium: alexyk: have you tried writing the bottlenecks in java? (the loads)

15:33 alexyk: the problem is the slowdown on a JVM which is well back under its Xmx, so it's something fishy. Java didn't occur to me... hmm. I'd rather unleash the agents. :)

15:34 I did google for "ocaml mongo", but there isn't one yet :)

15:35 somnium: the strangest thing is, as it does it slow fetch, it's decreasing the RAM! Now down to 10g from 12g.

15:36 Can it be that congomongo/mongo-java is allocating a lot and then same things are gc'ed?

15:36 hiredman: alexyk: you seem to have theories, how collecting some evidence

15:37 alexyk: somnium: the funny part is, that each graph is mass-insert!'ed in 10 minutes each

15:37 somnium: alexyk: I have to plead utter cluelessness when it comes to jvm internals

15:37 hiredman: enable some debugging options

15:37 alexyk: hiredman: which ones?

15:37 hiredman: you could start with the one to print out GC information

15:38 you could also grab a copy of yourkit and profile your app

15:38 or visualvm, or whatever

15:40 somnium: alexyk: you could try just calling the java driver from clojure, the driver returns <String><Object> Hashmaps, then write a loop that hammers those into your map, (assuming you know the types in the maps, you may avoid some coercion overhead)

15:41 alexyk: the wrapper just unravels maps/lists into keyword->object persistent maps/vector trees

15:43 but I think you may as well try dropping to java if you want to get a baseline for performance

15:43 alexyk: somnium: do you mean to do it in java? I already work the cursor per your gist, still it uses .toClojure

15:43 the thing is that the final map of maps must be clojure

15:43 AWizzArd: you put in type hints I guess

15:43 alexyk: hiredman: thx, I'll check those out

15:43 somnium: .toClojure does recursive .instanceOf calls to un-nest

15:43 AWizzArd: warn-on-reflection set to true

15:44 somnium: if you know the structure you can avoid the recursion

15:48 alexyk: somnium: ah!

15:50 AWizzArd: what's warn-on-reflection set to true? :) Type hints are not there either, since I'm not sure where to start sticking them in, and everywhere doesn't seem pretty

15:50 hiredman: ~performance

15:50 clojurebot: http://clojure.org/java_interop#toc46

15:52 AWizzArd: alexyk: whenever you have a (.something ...) then it is not clear for which class the JVM should call .something.

15:52 You should type hint that to avoid reflection.

15:52 alexyk: aha!

15:53 good good

15:54 AWizzArd: if your .toClojure sits in a tight loop and is not type hinted it may run two orders of magnitude slower

15:57 alexyk: AWizzArd: indeed...

15:57 AWizzArd: ja

16:02 alexyk: hey somnium: so I'm using that http://gist.github.com/278490. Should I type hint that cursor is DBCursor, and possibly replace .toClojure by something hand-made?

16:11 somnium: alexyk: you can type hint the target as #^ClojureDBObject too

16:12 alexyk: ok

16:15 somnium: say my collection is of the form, {"user":"John","days":{"1":2,"2":7}}. What would .toClojure be replaced with, roughly?

16:17 somnium: alexyk: have you read the source of ClojureDBObject?

16:18 alexyk: somnium: am going to now :)

16:24 somnium: you could have the default be "string" -> object, and then have #{"a" "b" "c"} -> map, and so on, sort of pattern matching on the keys in the root map

16:25 hiredman: or profile and type hint

16:25 somnium: using strings instead of keywords will avoid a little overhead too, the wrapper is aimed at convenience at the cost of a little (usually tolerable) overhead

16:25 ^^

16:25 hiredman: instead of guessing and flailing your arms about

16:26 somnium: yeah, we have no idea where the bottleneck actually is afaik

16:28 saml: hey, how would you replace all \W with white space?

16:28 use Java Matcher and Pattern ?

16:31 alexyk: somnium: so the reflections to avoid are, in toClojureVal, are two checks for instanceof Map/List?

16:32 avarus: hi

16:32 hiredman: are you even setting *warn-on-reflection*?

16:32 are you just guessing where you might be using reflection?

16:32 somnium: alexyk: its the stack-recursion more that the type checking

16:33 alexyk: hiredman: step by step, I'm reviewing now

16:34 saml: (use contrib.str-utils) yay and re-split

16:34 hiredman: what does that mean?

16:34 have you set *warn-on-reflection* and reviewing what it told you?

16:34 have you?

16:35 saml: java -cp clojure.jar clojure.main hello.clj --execute="(main *command-line-args*)" can I do this?

16:35 hiredman: saml: please read the --help

16:35 alexyk: hiredman: I'm speeding-up the alg first; added a type hint for Java method already; then will see what the warning shows

16:35 saml: hiredman: oh thanks

16:35 hiredman: alexyk: stop!

16:36 just stop

16:36 alexyk: ok :)

16:36 hiredman: set warn-on-reflection first

16:36 adding a million type hints that you might not need is not "working on the algorithm"

16:37 jasapp: it is entertaining to watch, though

16:37 somnium: hiredman: I think theres only two places he could type hint in the loop

16:37 alexyk: hiredman: true, I mean working with somnium to avoid a generic recursive-reflective call with a hand-made

16:38 somnium: I thought just one? #^ClojureDBObject cursor

16:38 hiredman: alexyk: have you set warn-on-reflection?

16:38 saml: it seems to be impossible to call a function defined in some.clj file

16:38 * saml manually edits some.clj to test from console

16:39 alexyk: hiredman: once the current load finishes, I will!

16:39 hiredman: saml: you are going to have to provide more context than that

16:39 alexyk: warn-on-reflection is a compile time setting

16:39 somnium: the cursor would be #^DBObject, set *warn-on-reflection* true, compile the loop, and it should tell you where the reflection happens

16:40 or smthing, DBCursor

16:40 saml: hiredman: my file ends with ;(main *command-line-args*) I explictely commented it out so that it won't call main function when I require it or load it on repl

16:40 but i also want it to be executable from command line

16:41 http://stackoverflow.com/questions/973106/what-is-the-clojure-equivalent-of-the-python-idiom-if-name-main hah!

16:41 alexyk: ok, so far I just did (load-file "my-fetch.clj"); will it compile as well or need I do explicit things after warn-on-reflection?

16:41 hiredman: saml: this is in the context of your earlier question?

16:42 alexyk: that will compile

16:42 saml: hiredman: yes. that link answered me

16:43 hiredman: alexyk: keep in mind that it will load and compile my-fetch.clj, but not anything it depends on that is already loaded

16:43 alexyk: hiredman: yep, that's ok. Lovely! oodles of info.

16:47 so if a typehint is wrong, Clojure silently ignores it, and reflection is warned about?

16:54 in a form, (-> cursor .next .toClojure), how can I typehint that .toClojure is called on a #^ClojureDBObject?

16:54 cursor is already hinted as #^DBCursor outside

17:01 i.e., the question is on how to syntactically stick a type hint in the middle of ->, or would I have to declare an intermediate var

17:02 StartsWithK: do you get a reflection warnning wothout one?

17:03 (-> "string" #^String (.toUpperCase)) will preserve :tag on final form

17:04 chouser: if .next is declared to return a ClojureDBObject, you don't need to hint .toClojure

17:05 alexyk: StartsWithK: yeah, warning on .toClojure... .next returns a java DBObject, on which we need to tack on .toClojure from ClojureDBObject

17:06 chouser: Try (-> cursor #^ClojureDBObject (.next) .toClojure)

17:07 alexyk: chouser: ok

17:07 so in the chain (-> #^TypeHint1 form1 #^TH2 form2) the hints are applied properly to their right-hand forms?

17:08 chouser: alexyk: judging by the source of ->, as long as the form is a list, yes.

17:09 alexyk: cool. hiredman: thanks for advice, java is running fast after some bitch-slapping! or it may be the fresh JVM.

17:09 StartsWithK: that kind of looks like a bug, .toUpperCase when wrapped in a list should pick up meta from .toUpperCase symbol

17:11 jasapp: alexyk: are you timing these, or just feeling better about the speed?

17:11 alexyk: jasapp: I'm timing runs and I have per-million progress throughout all of the code

17:12 crucial for me to see progress bar or I want to kill things

17:12 jasapp: cool, so you can actually quantify how much faster it's going?

17:12 alexyk: jasapp: well I just run under (time ...)

17:13 chouser: I assume Clojure's deftype is just like C's typedef, only backwards...

17:13 alexyk: the beauty of clojure, indeed, is how easy is to time things

17:13 jasapp: what kind of speed ups are you getting?

17:14 alexyk: jasapp: you see it's hard to tell. On a fresh JVM I get 50 million records in 15 minutes; on a used one, an hour or 3 hours. Who's responsible, I dunno. It's all somnium's fault, if someone asks.

17:15 but, seriously, somnium did a great job. Learning to work congomongo learned me some clojure for real good!

17:16 somnium: alexyk: its barely 300 lines, you could have written it

17:16 alexyk: somnium: 300 lines of clojure, that is :)

17:20 somnium: Im curious about protocols, is a protocol with sig (foo [x]) supposed to be faster than (fn [x] (cond (.isInstance SomeType x) ...)) in the general case?

17:21 chouser: somnium: yes, I think so

17:22 the latter is essentially what core fns do now (generally implemented in clojure.lang.RT) like 'seq'

17:24 hiredman: protocols are supposed to be more polymophic

17:24 avarus: mhmh...

17:25 hiredman: the clojure rationale page specificly calls out switch statements (like cond) as being too brittle

17:25 avarus: -e "(compile 'foo.bar)" would compile file "bar.clj" in directory "foo" right?

17:25 jlongster: Hey guys, I'm trying to figure out how to list all the files in a directory with clojure. Here's what I've got so far:

17:25 (doto (new java.io.File (str ROOT "/blog/")) (listFiles))

17:25 But it can't find the listFiles method. How should I do it?

17:25 StartsWithK: jlongster, (file-seq (java.io.File. "base-dir"))

17:26 hiredman: jlongster: you need to but a . infront of methods

17:26 .listFiles

17:26 avarus: make sure you read the docs on compiling clojure.org/compilation

17:26 devlinsf: Did swank-clojure change recently?

17:28 jlongster: StartsWithK: hiredman: thanks

17:28 avarus: hiredman: ah ok, so the ns thingy and defn -main is needed, thx :)

17:29 hiredman: -main is not needed to compile

17:29 it is needed if you want to have a static main method as an entry point

17:29 avarus: ok

17:30 I have no idea, I just want to set up something I can work with to learn the language

17:31 hiredman: why us compile at all?

17:31 why use compile at all?

17:31 there is really no point unless you need it, and you will know if you do

17:32 clojure always compiles code anyway, compile is just for if you need to keep the class files around

17:32 avarus: ya, I know, java -jar clojure.jar bla.clj sets me up :)

17:33 Chousuke: avarus: the easiest way to learn clojure is just to run emacs and slime and execute whatever code you want in the interactive REPL buffer :P

17:33 avarus: setting up emacs can take some time though, but it's worth it if you ask me :P

17:33 avarus: sure bit I hate emacs

17:33 dnolen: avarus: probably the "easiest" thing to do is setup lein, then you can just do "lein repl"

17:33 lein comes with jline so interacting with the REPL isn't too tedious

17:34 jlongster: Is there something that splits an absolute path into a directory name, filename, and extension, or should I use regular expressions?

17:34 avarus: executing java isn't too hard either :)

17:35 hiredman: the repl can use jline and rlwrap without needing lein

17:35 lein forces you to have project

17:35 some times you just want to run some code

17:35 avarus: vim?

17:36 avarus: na, gedit :P

17:36 hiredman: :|

17:36 anyway

17:36 avarus: I press some key and I see the output

17:36 that's good enough

17:36 hiredman: really, gedit does that?

17:36 dnolen: hiredman: only partly true

17:36 avarus: and I was experimenting with building the jar

17:36 hiredman: ya

17:36 dnolen: "lein new whatever; lein repl"

17:36 sorry

17:36 hiredman: dnolen: so now you have a whatever directory

17:36 avarus: hiredman: it's a plugin called external tools :)

17:36 dnolen: but you can always go there for repl fun

17:37 "lein new fun; cd fun; lein repl"

17:37 StartsWithK: avarus, did you try cream? (vim configured as normal editor, vimclojure should work with it too)

17:37 hiredman: java clojure.main

17:37 dnolen: easy to remember to.

17:37 hiredman: much easier

17:37 works anywhere

17:37 clojurebot: dirt simple

17:37 clojurebot: No entiendo

17:37 the-kenny: dnolen: You forgot "lein deps"

17:37 hiredman: clojurebot: dirt simple clojure

17:37 clojurebot: clojure is like life: you make trade-offs

17:38 hiredman: clojurebot: are you kidding me?

17:38 clojurebot: Pardon?

17:38 the-kenny: Or does lein that now by itself?

17:38 dnolen: you don't need that the-kenny: just tried it, seems to work okay

17:38 the-kenny: dnolen: Oh cool

17:38 avarus: StartsWithK: no, but I read about it some time ago

17:38 dnolen: actually

17:38 "lein repl" works no project necessary SWEET

17:39 avarus: it's ok that way...I was only confused about the compiling stuff :)

17:39 I thought that was needed

17:39 you told me it's not, I tested it, and it works :)

17:39 hiredman: clojurebot: dirt simple clojure

17:39 clojurebot: http://www.thelastcitadel.com/dirt-simple-clojure

17:40 avarus: :)

17:40 the-kenny: Uh, the font is way too small here

17:40 avarus: lol

17:41 the-kenny: I like step VI

17:41 hiredman: I don't see how the font could possibly be too small

17:42 avarus: it's too big :P

17:42 Chousuke: hiredman: then it is too small, obviously!

17:42 avarus: :>

17:42 hiredman: your monitor is obviously too small

17:43 Chousuke: yes it is. also it makes a whining noise

17:43 the-kenny: hiredman: hm. Maybe I hit Cmd-- some time ago and my browser remembers this setting during visits

17:43 * Chousuke is contemplating buying a 24" one to replace it

17:43 hiredman: at the office here two people already have 28"

17:43 Chousuke: seriously though, that font is huge :P

17:44 hiredman: it's not that big

17:44 Chousuke: well, I currently have 13.3" & 17" CRT

17:44 hiredman: it's like 12pt

17:45 the-kenny: hiredman: hm.. if it's 12pt, I must accidently typed Cmd-- some time ago

17:45 hiredman: maybe 16

17:45 dnolen: looks huge to me to

17:45 more like > 24

17:47 hiredman: *shrug*

17:47 what browser/os?

17:48 looks fine in firefox on windows and freebsd

17:48 also chrome

17:48 and msie8

17:49 do you all have macs or something?

17:49 avarus: I don't

17:50 somnium: its huu-uuu-uuge on chrome/linux too :)

17:52 hiredman: well, y'all should fix your browsers

17:52 ahamay: which library would you use to write a parser in clojure?

17:53 hiredman: clojurebot: parse?

17:53 clojurebot: Pardon?

17:53 hiredman: clojurebot: parsing?

17:53 clojurebot: I don't understand.

17:53 hiredman: clojurebot: how much do you know?

17:53 clojurebot: I know 535 things

17:53 hiredman: hmm

17:54 ahamay: :)

17:55 the-kenny: clojurebot: skynet

17:55 clojurebot: I will become skynet. Mark my words.

17:55 hiredman: parser?

17:55 clojurebot: parser is http://github.com/joshua-choi/fnparse/tree/master

17:55 hiredman: clojurebot: jerk

17:55 clojurebot: It's greek to me.

17:56 ahamay: fnparse seemed a bit cryptic to me - but maybe I just need to get used

17:56 hiredman: there is at least one other parser library, fnparse is the only one I have used

17:57 fnparse does tend to shift out from under you

17:57 release to release it can vary significantly

17:57 ahamay: ic

17:57 guess you mean http://kotka.de/projects/clojure/parser.html

17:57 but the download's broken there

17:59 ok thx, guess I'll stick to fnparse for the start

17:59 the-kenny: Uhh I'd love a parser like parsec for clojure

18:01 ahamay: yeah, that's what I was hoping for, too

18:02 I even checked on JParsec - but to me that seemed closer to JavaCC than Parsec :(

18:02 hiredman: clojurebot uses fnparse

18:02 (badly)

18:04 ahamay: after looking at the fnparse tutorial, it seems to do the job okay

18:04 I just got scared by looking at the JSON example immediately :)

18:10 somnium: any monad enthusiasts on?

18:11 DeusExPikachu: what's the right way to go about this, I want to create objects for the purpose of creating identities and I want to create a tree datastructure populated with these objects using sequences and other objects, I want to be able to traverse the tree and dispatch based on the class. Now I don't think there is a way to define classes in clojure that I'm aware of, is this the time to use 'derive, thoughts?

18:12 avarus: good night

18:16 ahamay: somnium: I'm a bit into monads and this category theory stuff

18:16 though I'm not an expert

18:18 DeusExPikachu: won't multimethods be all you need? Or did I get something wrong?

18:19 DeusExPikachu: in case it helps with the explanation, I'm trying to write a very expressive PEG parser generator where the PEG is expressed in this hybrid form of clojure code and these objects that are identities for certain operators

18:19 ahamay: the idea is to use multimethods and dispatch on class, but I dont' know how to define a class

18:20 ahamay: you don't need classes

18:20 DeusExPikachu: I really can't dispatch on anything else but a class cause a class in my case will be the most unique

18:20 everything else can potentially be unintended if something else matches in the clojure code

18:21 ahamay: did you read up about ad-hoc hierarchies and stuff?

18:21 DeusExPikachu: I've been reading it but still don't quite understand the usage

18:22 ahamay: or how about having a :type field with a keyword in it?

18:22 hiredman: DeusExPikachu: I still don't see why you would dispatch on a class

18:22 use a keyword

18:22 ahamay: {:type my-type-a :data 42}

18:22 DeusExPikachu: keywords can potentially clash

18:23 I'd have to make it part of the contract that the user not create any code that evaluates to a map with the keyword type

18:23 hiredman: you can namespace qualify keywords

18:23 DeusExPikachu: hmmm, true

18:24 hmm I think that solves it for now

18:24 is that the general way to prevent clashes?

18:25 hiredman: I don't think preventing clashes completely is a good idea

18:25 somnium: ahamay: I have multimethod with sig [x y] dispatching on x, and all methods return [(f x) updated-y], and callers always merge updated-y onto y, kind of passing an environment up and down the stack

18:25 hiredman: some users may want to clash for some reason

18:26 somnium: using macros and map-destructuring to chop at the boiler-plate, but wondering if its a good spot for a monad (which I still dont really get)

18:26 DeusExPikachu: well from a developer standpoint, I don't want clashes interfering with the interface

18:26 ahamay: that indeed sounds like monad usage, yes

18:27 though actually I haven't yet looked at the clojure module for it

18:27 I was doing Haskell before

18:27 DeusExPikachu: excuse me, I mean interfering with my lib's interface

18:27 hiredman: DeusExPikachu: but somewhere downline the line someone using the software may want a clash for some reason, best to leave them an out somehow

18:28 sure, prevent accidental clashes

18:28 which namespacing does

18:28 DeusExPikachu: ok, so I guess its idiomatic enough then, thanks

18:28 hiredman: but let people clash if they really really want, even if breaks stuff

18:28 ahamay: I think http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html helped me a lot for understanding

18:28 DeusExPikachu: well they can clash it if they want to create a fully qualified keyword now then

18:28 somnium: ahamay: thanks, will read

18:28 hiredman: DeusExPikachu: exactly

18:29 DeusExPikachu: so I think it fulfills what you are talking about in my case too

18:32 ahamay: somnium: I just found http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/ - did you already look at these?

18:34 somnium: ahamay: yes, I think I got the principles, but havent tried using them in practice yet. maybe this is a good opportunity

18:35 right now I have a def-envfn macro and a call-envfn macro, and suspect Im reinventing something poorly

18:36 hiredman: maybe an evaluator

18:37 somnium: hiredman: the mechanism, not the application

18:37 hiredman: it is indeed an evaluator

18:38 * Raynes should have learned more about how email works before deciding to write an email client. JavaMail causes headaches.

18:40 technomancy: Raynes: JavaMail is actually very true to the spec. it's the spec that's causing those headaches; it's insane.

18:40 ahamay: if nothing else, understanding monads gave me a good feeling :)

18:42 hiredman: yeah

18:42 email is old and crufty

18:45 technomancy: "you have to remember, this was invented twenty years ago, before people were smart."

18:45 according to dysinger =)

18:46 hiredman: s/smart/experienced/

19:04 the-kenny: Is congomongo still the "best" client for mongodb?

19:19 Raynes: technomancy: Do you have experience with receiving email in JavaMail via Clojure, by any chance?

19:21 technomancy: Raynes: not directly via IMAP or SMTP, just parsing it from disk.

19:22 Raynes: technomancy: http://gist.github.com/287405 I'm confuzzled as to why it wont let me return mseq because I've closed the folder. I process the emails while the folder is open (mostly toStringing java objects) to stuff I can use.

19:22 I can't figure it out.

19:23 But I can do whatever with mseq as long as it's before I close the folder. It's confusing, because I don't actually store any Message objects or anything in mseq.

19:23 technomancy: Raynes: actually you're processing them after the folder is closed

19:23 clojurebot: map?

19:23 clojurebot: map is lazy

19:23 technomancy: Raynes: ^^

19:23 Raynes: Oh shit.

19:23 technomancy: hehe

19:23 Raynes: Hehe.

19:23 * Raynes forgot map was lazy.

19:23 Raynes: :>

19:24 You've saved the day.

19:24 technomancy: last time I made that mistake clojurebot was all: map is *LAAAAAZY* and made me feel more like a doofus. kids these days have it so easy. =)

19:25 Raynes: :)

19:26 DeusExPikachu: technomancy: do you frequent google groups swank-clojure? I posted a bug a day ago, was wondering if you looked into it yet

19:26 Raynes: technomancy: What is the preferred way to force evaluation in this particular situation?

19:26 technomancy: DeusExPikachu: I'm just swamped... behind on all my projects. =\

19:27 Raynes: wrap map in a doall

19:27 DeusExPikachu: technomancy: ok, just curious

19:27 Raynes: Alright. Thanks. :)

19:27 technomancy: DeusExPikachu: I will probably get to swank-clojure after I make the next leiningen release

19:28 Raynes: Yay! It works.

19:33 technomancy: How does lein test work? It appears that it only looks for a tests.clj file, and if it isn't there, it fails.

19:35 the-kenny: Uhm.. any congomongo-developer here? Why does (databases) return a java ArrayList instead of some clojure-seq?

19:36 technomancy: Raynes: if you give it a list of test nses as CLI args it will use those, otherwise it uses every namespace in the tests/ dir

19:37 Raynes: I tried making a testsomething.clj file with ns testsomething, but it didn't see it.

19:38 I'm new to unit testing, so I've probably done something wrong.

19:38 I'll figure it out later. :>

19:38 technomancy: Raynes: doing "lein new" on git master will spit out something with the correct structure

19:40 the-kenny: hm.. I have to go to bed. I'll file a bug.

19:40 Raynes: technomancy: Not sure what you mean.

19:40 the-kenny: Night

20:53 dnolen: so do people agree that eval is the only way to accomplish "introspection" when writing macros? that is it's most straightforward to reflect on the current environment

20:53 ?

20:54 chouser: avoid eval

20:55 'resolve' isn't quite as bad, though still not always what you want.

20:55 now you can look at &env as well

20:55 dnolen: chouser: oh yeah, care to explain how &env works? I guess it's what I need

20:56 in the past I used eval or resolve because I didn't really know any other to look up the value of previusly defined symbols.

21:00 hiredman: erm

21:02 chouser: a macro that depends on the *value* of a var or locall is suspect

21:03 dnolen: chouser: I'm reading a file's contents to produce the code for a function

21:05 I'd like to avoid what I'm doing but I don't "see" how.

21:05 thus the ^ question

21:06 basically I'm introspecting on the contents of an HTML file to produce an Enlive template. I want the code to be pretty terse

21:06 (templ name *path*)

21:16 chouser: hm. Well, examining data to produce code and then eval'ing it isn't necessarily wrong, but I don't see what that has to do macros.

21:17 dnolen: chouser: well in order to produce the proper syntax of an Enlive template I need a macro.

21:17 basically I'm looking up all the CSS ids, and automatically generating the template to match them so they can be replaced by pass a map to the template.

21:18 pass -> passing

21:42 mquander: what's the clojure equivalent of letrec?

21:43 that is, a let that allows me to bind one variable and then bind another based on the value of the first, hopefully without unnecessary nesting

21:43 oh, i think it's "let".

21:51 qed: why is it suddenly surprising to some bloggers that leiningen is the community's build tool of choice

21:51 ive been operating under that assumption for 3 months

21:54 why would you use maven or ant?

21:55 how have java developers put up with them for so long?

21:55 dnolen: qed: perhaps because you want something smarter/robust? I like lein because it's simple.

21:55 personally I think lein has some issues but I imagine they'll be worked out over the coming months.

21:55 qed: i had no java experience prior to clojure -- but it just baffles me that people used to actually write these gargantuan xml pieces of crap

21:56 no thanks.

21:57 lein definitely has some issues

21:57 but the issue it doesn't have is making the build process a complete fucking bummer

21:57 excuse my french

21:59 i guess i was just surprised people didn't see lein being the standard months ago

22:00 to me it was always the clear winner in build tools

22:02 tbqh being a newbie to clojure and java at the same time, i dont know if i ever would have created a single tangible runnable application in clojure if it weren't for lein -- maven, ant, etc. just looked like complete crap to me, a waste of time to learn

22:03 like "here, sift through this mountain of garbage to piece together a tiny working piece of distributable code"

22:03 mquander: newbie q: is there a lazy-mapcat somewhere that i can use as shorthand for (lazy-cat (map #(lazy-seq (my-real-mapping-fn %)) xs))?

22:03 qed: </rant>

22:04 mquander: er, i know i could actually just use concat there not lazy-cat

22:04 hiredman: ,(doc mapcat)

22:04 clojurebot: "([f & colls]); Returns the result of applying concat to the result of applying map to f and colls. Thus function f should return a collection."

22:04 qed: there's a mapcat iirc

22:04 mquander: i just don't like having to wedge the lazy-seq into my mapping lambda

22:04 oh, yeah, i guess i can use that to shorten it on front

22:04 that's pretty good then

22:05 hiredman: you know map is lazy right?

22:05 having lazy-seq there makes no sense

22:05 mquander: map is lazy? heck no i did not know that

22:05 qed: :)

22:05 mquander: that is awesome

22:05 hiredman: ,(doc map)

22:05 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

22:06 * qed hugs hiredman

22:06 mquander: geez problem annihilated then

22:06 * qed hugs mquander

22:06 hiredman: ���

22:06 qed: :|

22:07 the clojure spirit sometimes wraps me up, swallows me whole, and spits me out

22:07 it's like christmas, except real

22:07 hiredman: mquander: I don't think lazy-seq does what you think it does, so until you read up on it, I would pretend you hadn't heard of it

22:08 most of the functions that operate on sequences use lazy-seq internally, so you should not worry about it at all

22:08 mquander: ok, i see. i didn't realize that.

22:08 qed: what did lazy-seq used to be?

22:08 lazy-cat was it?

22:08 hiredman: lazy-seq does not magically make a seq lazy, the seq has to be constructed using lazy-seq

22:08 qed: lazy-cons

22:09 qed: ah yes, thanks

22:10 hiredman: but that changed long ago

22:10 qed: where long ago == 4 months

22:11 mquander: if map is lazy, then why does this happen?

22:11 brweber2: ,(println "hey folks")

22:11 clojurebot: hey folks

22:11 mquander: (defn expensive-operation [n] (print "foo") n)

22:11 (first (map expensive-operation [1 2 3])) ;; prints "foo" 3 times

22:12 qed: ,(source println)

22:12 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

22:12 hiredman: mquander: oh, complain to rhickey about it

22:13 qed: ,(doc prn)

22:13 clojurebot: "([& more]); Same as pr followed by (newline). Observes *flush-on-newline*"

22:13 hiredman: mquander: http://www.assembla.com/wiki/show/clojure/Chunked_Seqs

22:14 alexyk: how do you convert a :10 to number 10?

22:15 hiredman: http://blog.fogus.me/2010/01/22/de-chunkifying-sequences-in-clojure/

22:16 mquander: i see. thanks hiredman

22:16 dnolen: ,(Integer/parseInt (name :10))

22:16 clojurebot: 10

22:16 dnolen: alexyk: ^

22:16 qed: alexyk: well done sir

22:17 i couldnt find that

22:17 alexyk: qed: dnolen did it!

22:17 qed: oh oops

22:17 dnolen: you're a champ. i love you.

22:17 (alexyk is okay, too)

22:18 alexyk: qed: cheers!

22:18 * qed raises his cup

22:18 qed: to clojure!

22:18 alexyk: Glenfiddich all around!

22:18 qed: so im not the only clojurist with a penchant for scotch

22:19 alexyk: where are you from?

22:19 alexyk: New England. Formerly Russia...

22:20 qed: ah -- well, next time im out east i owe you a drink

22:21 alexyk: :)

22:22 we can go visit cemerick too

22:22 qed: !!!

22:22 alexyk: in his MA hamlet

22:22 * qed wants ahamlet

22:22 qed: not the vietnam-type hamlet

22:22 alexyk: hamlet is a processed piglet

22:22 qed: or the shakespearean hamlet

22:22 alexyk: or when-let

22:23 (hamlet [ham (...

22:23 qed: i can get behind ham

22:23 alexyk: (hamlet (to-be ...) (or (not( to-be ...

22:23 qed: not literally

22:25 (def to-be true)

22:25 alexyk: that's optimism!

22:26 qed: haha

22:26 mquander: (def the-question (or to-be (not to-be)))

22:26 mwilliams_: ~seen technomancy

22:26 clojurebot: technomancy was last seen quiting IRC, 72 minutes ago

22:26 mquander: a sufficiently smart compiler would just optimize hamlet's question out imo

22:26 qed: alexyk: im trying to start up an Erdos-esque travel schedule

22:27 can I come visit you with a suitcase and amphetamines in-tow?

22:28 alexyk: qed: you have to sell off all possessions then and live out a backpack. I got two small kids though which only eat healthy stuff; but the Appalachian trail passes right next to our house, and shadowy bearded types spend the nights in small tents in the snow...

22:29 qed: the trouble with computer science is you need a computer to test it

22:29 i wish i could get rid of this damned thing

22:29 alexyk: qed: that's the paradox of a computer scientist. To teach the stupidest and dumbest machine to do what a 5-year old kid knows.

22:30 qed: i should write a book about doing CS for a year without a computer

22:30 alexyk: qed: well you can have iPhone with IRC and ask people to compute for you

22:30 qed: nah that'd be cheating

22:30 clojurebot: is_rhickey_a_minor_god is yes

22:31 alexyk: or you can leave sexps to be eval'ed on scraps of paper

22:31 qed: i have so many books and junk downloaded -- i just need to print it all and disconnect

22:31 alexyk: qed: printing is old, stuff it into kindle

22:31 mquander: leaving paper in public place, waiting for someone to write response on it = very lazy evaluation

22:31 alexyk: or Apple tablet coming tmrw

22:32 qed: mquander: lol,

22:32 alexyk: mquander: right, and responses might be in any FP language, like Erlang or OCaml

22:32 qed: the apple tablet is going to be a disappointment and i know it

22:32 alexyk: qed: I wouldn't be so sure

22:32 qed: if it isn't eink, i dont care about it :(

22:32 i doubt they have a dual purpose screen

22:32 if they do ill buy one on the spot

22:32 alexyk: qed: well, in fact I prefer to read off my iPhone instead of a Kindle DX

22:33 qed: alexyk: yes, but you're absolutely mad

22:33 so who would trust your opinion?

22:34 alexyk: eink works for hours on end to read, then I do the DX

22:34 qed: well, I'll take it as a compliment for now :)

22:34 qed: :)

22:34 have you read Logicomix?

22:34 (highly recommended)

22:34 alexyk: never heard of it

22:34 qed: the first and only graphic novel ive ever read

22:35 http://www.logicomix.com/en/

22:35 mquander: i want device with touchscreen, hardware keyboard that folds up underneath it but can extend to a normal laptop form factor

22:35 qed: i want a device that doesnt run iphone OS

22:35 mquander: that too :X

22:35 qed: because it clearly sucks

22:36 can you imagine a 10" screen covered in apps?

22:36 what a waste of machine

22:37 unless i can compile and run emacs23, Terminal.app, and chrome -- ill pass

22:37 mquander: i just want something light and small that i can both program on and draw diagrams on

22:38 qed: mquander: i think we're thinking alike here

22:38 i played with the iphone liberally -- adding ssh to it, installing stuff on it, like GHC and such

22:39 but it was never that mythical machine that this tablet could potentially be

22:39 the rumors suggest it runs iphone OS

22:39 which makes it completely sad

22:39 mquander: only source i saw for that one was some textbook CEO on cable news

22:39 qed: yes the mcgraw hill asshole

22:40 hopefully he is wrong about the iphone OS

22:40 mquander: as if that guy can tell an OS from his rear end

22:40 qed: the mcgraw hill guy, regardless of what OS the tablet runs, needs a new rug

22:40 that thing was atrocious

22:40 mquander: anyway, if it runs mac OS, i would expect them to cook up some custom UI on top of it, sort of like smartphones and like that windows media center thing

22:41 so probably textbook guy would be clueless as to what was under the hood

22:41 qed: yeah, that's to be expected, id be very happy with that

22:41 but if it's just iphone OS, 10 inches big

22:41 that's going to be a very sad state of affairs

22:41 (until it's jailbroken)

22:41 mquander: that would be really lame, until jailbroken.

22:41 i feel guilty about buying apple products when they contribute to this lame walled garden stuff

22:41 i wish the products weren't as good as they are

22:42 qed: mquander: the next phone i get wont be apple

22:42 hello N900

22:43 mquander: likewise.

22:44 qed: apple really set the stage for such a phone

22:44 but it doesnt change the fact that apple is now being outclassed by their competition in features and extensability

22:45 my dream: a tablet with really revolutionary tactile feedback mechanism -- a full OS with a layer of software to make it easy to use via touchscreen

22:46 im big on my keyboards. im certainly the minority here i think, but im typing on a 250$ keyboard. why? feedback.

22:47 the touch screens are a joke

22:48 without feedback or a neural interface the'll always be substandard

22:55 alexyk: when I call (map ... <some map>), the map is seq'd. If I do (pmap ... <some map>), will it seq first or do I have to seq manually?

22:57 I see it mostly at 100%, 400-500% inly blinks for a moment

22:57 only

23:01 I run pmap on a seq of pairs, then join them as a map with (into {}). Given keys don't overlap, is there a faster way?

Logging service provided by n01se.net