#clojure log - Jul 23 2010

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

0:00 cemerick: mmarczyk: where is it 6AM now?

0:00 mmarczyk: cemerick: most of the EU :-) -- Poland in my case

0:01 cemerick: ah, I should've guessed given the bar on the 'l' :-)

0:01 mmarczyk: :-)

0:03 cemerick: mmarczyk: how's the software biz in Poland in general? I've worked with a lot of Czechs, but never a Pole.

0:03 A few more anecdotes, and I'll have some data!

0:03 mmarczyk: :-)

0:03 I'd love to be able to answer, but I've mostly been a hobbyist so far

0:04 cemerick: Really! What's your real job, then?

0:04 mmarczyk: I'm doing a PhD in logic

0:05 though my institution is called "Institute of Philosophy" (of ...) :-)

0:05 hm... I wonder if that's a job ;-)

0:05 cemerick: I'm sure I'm not qualified to say. ;-)

0:06 mmarczyk: :-)

0:07 cemerick: My academic friends and I eye each other with great suspicion and total confusion most of the time.

0:09 slyrus: mmarczyk: I think the point is that letfn _is_ a letrec, it's just one that wraps each of its bound forms in a lambda.

0:11 mmarczyk: slyrus: take that! -- (letrec [x (promise) y (fn [] (deliver x :foo))] (y) @x) ;-)

0:14 slyrus: is that supposed to return?

0:14 mmarczyk: cemerick: I've been thinking of taking a tentative step or two into the industry lately, just because I'm enjoying programming so much... so far, confusion is definitely involved :-)

0:15 slyrus: sure, in fact it does at my REPL

0:15 rhudson: mmarczyk: that also works just with 'let

0:16 mmarczyk: rhudson: true, my point is that letrec is really a cross between let and letfn

0:18 cemerick: mmarczyk: the worlds are soooo different. I think thriving in either environment indicates aptitude of some sort.

0:19 tomoj: mmarczyk: logic? cool!

0:20 mmarczyk: cemerick: right... with the "aptitude domains" apparently largely disconnected

0:20 tomoj: :-)

0:20 cemerick: mmarczyk: yup, mostly disjoint ;-)

0:20 mmarczyk: :-)

0:21 slyrus: mmarczyk: of course that can be done with just: (let [x (promise) y (fn [] (deliver x :foo))] (y) @x)

0:22 mmarczyk: slyrus: that would be the meaning of rhudson's remark -- see above

0:22 cemerick: There are more or less sane subdivisions, of course. I'm in a particularly sane environment, and seen highly dysfunctional ones in the past. Of course, the gossip in each camp always focuses on the horror stories from the other side.

0:22 slyrus: oh, busy looking at my emacs window instead of irc...

0:24 mmarczyk: cemerick: I've been largely disconnected even from the local industry gossip... hearing a little bit hear and there these days sometimes makes for a weird sense of an alien encounter :-)

0:25 blais: Quick question: is there a way to apply to a record?

0:25 e.g. (defrecord Bla [a b c])

0:26 mmarczyk: that's actually enjoyable in a way, mind you

0:26 blais: then, (let [args [a b c]] (apply Bla. args))

0:26 I could not get this to work, I ended up building an expression, including quoting, and then calling (eval). It's a bit nasty.

0:26 mmarczyk: blais: not like that, you'll have to make a factory function

0:26 (defn make-bla [a b c] (Bla. a b c))

0:27 blais: Like CL.

0:27 OliverUv: hey, I'm new here! I saw a video lecture on multi-threaded use of Clojure and got really interested

0:27 cemerick: blais: constructors (and other interop forms) aren't functions, apply won't work with them

0:27 blais: Wouldn't it make sense to automatically generate those?

0:27 I know, special forms, like quote. Thus my question.

0:27 mmarczyk: maybe, afaik it's not off the table for the future

0:28 blais: I suppose I could create a macro that does both defrecord and creates a factory func at the same time.

0:28 OliverUv: Thinking of getting an excuse to program clojure after my current project/job is done, but I was wondering how do you people feel about macros now that the syntax isn't just lists and keys (a la CL) any more?

0:28 tomoj: factory functions used to be generated automatically

0:28 no longer

0:28 so I guess there was some reason they were bad

0:28 cemerick: blais: factory functions are more likely in general, at least to start

0:29 tomoj: maybe just the name collision with the class?

0:29 OliverUv: Do you feel it is more effort, or about the same as before? Do you avoid using macros more? Or perhaps find yourself thinking them through more?

0:29 mmarczyk: OliverUv: CL and Scheme have vector literals too (though different from Clojure's)

0:29 cemerick: tomoj: that, and there's good symmetry in there being one canonical way to create instances of classes.

0:29 blais: It would be nice if a record supported IFn, and that call would be a factory function by default, a-la-Python

0:30 mmarczyk: blais: but you can provide all sorts of IFn implementations for your defrecords / deftypes

0:30 OliverUv: mmarczyk: ah, and so I assume the [ ] syntax can be replaced by functions like (make-vector ..) or something ?

0:30 cemerick: blais: I use this at the moment: https://gist.github.com/6676bbfb35f305d05825

0:30 the factory fn inits the record with default values

0:31 mmarczyk: OliverUv: well, not really

0:31 rhudson: ,(= [1 2] (vector 1 2)

0:31 clojurebot: EOF while reading

0:31 mmarczyk: OliverUv: vectors and maps are used in Clojure for things like argument lists and metadata maps

0:31 rhudson: ,(= [1 2] (vector 1 2))

0:31 cemerick: There will likely be a way to define multiple factory fns, accessible as statics on the class.

0:31 clojurebot: true

0:32 cemerick: (or, that was the leading contender, last I knew)

0:32 mmarczyk: OliverUv: you can't write (fn (x) ...) in place of (fn [x] ...)

0:32 OliverUv: that doesn't interfere with the convenience of using the macro facility, though

0:33 OliverUv: yeah, the syntax is still relatively simple

0:33 cemerick: OliverUv: why are vector literals difficult with macros?

0:34 OliverUv: cemerick: Any extra syntax is more effort with macros, because it causes differentiation between code, data, and different kinds of code and data

0:34 but if you can just say (vector 1 4) aswell as [1 4] then there is no problem

0:34 so I take it you are happy with the macro facilities of Clojure? :) man, any of you got good ideas for projects I can convince my professors to let me do for the university? (paid)

0:34 heh

0:34 cemerick: I guess I don't see the complication. You can put [1 4] in a macro definition without a problem.

0:34 mmarczyk: (define-syntax foo (syntax-rules () ((foo #(a b c)) (a b c)))) => (foo #(+ 1 2)) => 3

0:35 that's Scheme... no problem using vectors in macros there

0:35 cemerick: OliverUv: CL-style, but hygenic. Hard to beat IMO. :-)

0:36 mmarczyk: somehow this brings to my mind the fact that syntax-quote isn't a macro yet... can't wait for that one :-)

0:36 OliverUv: cemerick: yes, but if you want to transform it to another kind of data, then it is not a matter of exchanging a symbol from vector to list, but to change from [] to parens, which is more effort

0:37 mmarczyk: or actually I guess I might want to write myself a quasiquote... hm.

0:37 cemerick: OliverUv: Given the seq abstraction, you generally don't need to care about vectors vs. lists vs. whatever, unless you have to (e.g. fn arg syntax).

0:38 blais: What's the difference btw (fn) and (fn*)

0:38 ?

0:38 mmarczyk: blais: fn* is the special form fn -- which is a macro -- expands to

0:38 cemerick: blais: fn* is an implementation detail you should forget you know about

0:38 ;-)

0:39 mmarczyk: hm, what cemerick said :-)

0:39 blais: cemerick: hard to forget when I see it everywhere in macroexpand-1

0:39 Thx guys,

0:39 rhudson: ,(let [x [1 2 3]] `(~@x))

0:39 clojurebot: (1 2 3)

0:39 mmarczyk: basically the difference is there's no destructuring on arguments

0:39 slyrus: why isn't def in the clojure.core API?

0:40 rhudson: so it's not hard to convert vector to a list if you need to -- but as cemerick says, you generally don't need to

0:40 cemerick: blais: I think it will go away eventually, but it's not a high priority.

0:40 slyrus: and binding only works on global vars?

0:40 with (binding ...) that is

0:40 mmarczyk: slyrus: yes

0:41 blais: this would be useful in the core: (defn map* [f coll] (map #(apply f %) coll))

0:41 or map-apply

0:41 slyrus: mmarczyk: the binding APIs don't make that clear. are the rules on that spelled out somewhere?

0:41 Lajla: ,(let [x '(His Shadow)] `(I Worship ~@x))

0:41 clojurebot: (sandbox/I sandbox/Worship His Shadow)

0:41 cemerick: blais: (map (partial apply f) coll)

0:41 mmarczyk: slyrus: the word "var" only refers to the top-level objects created by def

0:42 Lajla: mmarczyk, how do I avoid those namespaces.

0:42 Tell me, so that His Shadow may be worshipped.

0:42 slyrus: ah, ok. thanks mmarczyk. there's no way to make local variables "special" in CL-parlance?

0:42 mmarczyk: slyrus: with that in mind, (doc binding) is sufficient... but I'm not sure if that bit about Vars needs to be stressed somewhere more strongly

0:42 slyrus: nope

0:43 slyrus: grumble grumble

0:43 technomancy: pet peeve: def is certaily in the clojure.core API, though it may be missing from the API's documentation.

0:43 slyrus: yeah, it's on the special forms page, but not in the API docs

0:43 blais: cemeric: Nice; I didn't know Clj had partial application.

0:44 mmarczyk: technomancy: nice refactoring on lein; also, just noticed that jar.clj uses "meta-inf" as the metadata directory name, whereas it probably should be "META-INF"; want me to fix it?

0:44 actually I really dislike how (doc def) and (doc fn) only say "special form, see <url>"

0:45 technomancy: mmarczyk: sure... I don't even know what that's for, actually.

0:45 blais: ,(doc def)

0:45 clojurebot: DENIED

0:45 mmarczyk: technomancy: the jar spec says it's optional, I believe, so in lein's case it's likely only useful together with that weird bit you flagged for ato's attention

0:46 then again

0:46 you can set a jar's classpath there

0:46 clojure.jar has an "." entry, which is why it loads user.clj when it's alongside clojure.jar

0:46 etc.

0:47 cemerick: META-INF/MANIFEST.MF is used for all sorts of things

0:47 module systems, most commonly (osgi, netbeans modules, etc)

0:47 mmarczyk: oh, it should be MANIFEST.MF ?

0:47 technomancy: it's just part of the jar spec where it keeps stuff that didn't have any place in the zipfile format?

0:48 cemerick: roughly, yeah

0:48 mmarczyk: yes

0:48 mmarczyk: cemerick: but META-INF/maven is correct, right?

0:48 cemerick: mmm, also used by the service provider lookup pattern

0:49 mmarczyk: not sure, I'm not familiar with the bits maven puts in there

0:49 technomancy: setting the jar's classpath seems weird. if you're going to ship more than just a single jar, it seems like you might as well go to the trouble of including a shell script and save users the trouble of calling the "java" command manually.

0:49 I guess there are edge-cases it may be useful for

0:50 cemerick: technomancy: if only they had had the slight bit of sense to make ti so that nested jars could be referenced, that'd have saved everyone a lot of work

0:51 technomancy: it's pretty clear they haven't put any thought into how java's used from the command-line since the mid nineties.

0:51 mmarczyk: technomancy: fixed

0:52 technomancy: thanks

0:58 hashdot will save us!

0:58 http://hashdot.sf.net

1:01 mmarczyk: technomancy: thinking about using hashdot in lein-generated scripts then? as in, #!/usr/bin/hashdot

1:02 #.hashdot.profile = clojure

1:02 technomancy: mmarczyk: not yet. hashdot is still too hard to install.

1:02 mmarczyk: (apply projects.main.ns/main *command-line-args*)

1:03 hm, that's a shame

1:03 technomancy: I need to find someone who knows how to make .deb files to package it up.

1:05 blais: mmaczyk: just looked at hashdot.... but isn't it too slow? On my linux macbook4,1 starting a JVM is several seconds... unusable for scripts.

1:07 technomancy: blais: unusable for many kinds of scripts, but it would still be convenient to be able to launch long-running process from the CLI without constructing your own classpaths, etc.

1:07 it's also possible to speed it up a fair bit using -Xbootclasspath and a client JVM (if available)

1:08 * technomancy ponders if dalvik would be a possibility for when quick boot is more important than long-term perf

1:08 technomancy: oh, the things I'd do given the time....

1:16 slyrus: huh? Unable to resolve symbol: defn in this context

1:16 what have I done to my ns...

1:17 technomancy: slyrus: you probably didn't refer clojure.core

1:17 slyrus: oh, do you have to do that?

1:17 technomancy: only if you use low-level functions to create your ns

1:18 slyrus: bah. i don't like how in-ns well let you refer to non-existent namespaces

1:19 technomancy: I know it's recommended to use in-ns in the repl, but I always just use regular ns

1:20 save three characters!

1:21 slyrus: same problem though

1:25 technomancy: well if you create new namespaces with ns, you won't have that issue

1:26 it may not fix existing ones

1:26 slyrus: no, I mean that ns from the repl lets you switch to a bogus namespace

1:27 technomancy: what's a bogus namespace?

1:27 slyrus: i see. i guess i'm griping that in-ns lets you switch to a namespace that wasn't created with ns

1:27 technomancy: if you want to ensure a namespace doesn't exist before switching to it, try (doto 'my-ns.core require in-ns)

1:27 *does exist

1:30 lancepantz: i don't like how emacs indents macro calls as lists when the second item is a vector

1:30 does anyone know a work around for that?

1:31 Lajla: ,(let (x 3 y 4) (+ x y))

1:31 clojurebot: java.lang.IllegalArgumentException: let requires a vector for its binding

1:31 Lajla: ,(let [] (+ 1 2))

1:31 clojurebot: 3

1:33 OliverUv: i... have to try

1:33 slyrus: mmarczyk: the problem with a queue is that I am doing (into (subvec queue 1) next) where next is a seq

1:33 ,(into (subvec [1 2 3 4] 1) [5 6])

1:33 OliverUv: ,(format nil "/quit")

1:33 clojurebot: [2 3 4 5 6]

1:33 java.lang.NullPointerException

1:33 OliverUv: aw

1:33 ,"/quit"

1:33 clojurebot: "/quit"

1:33 slyrus: I can't just conj that onto a c.l.PersistentQueue and have the right thing happen

1:34 OliverUv: ,'/quit

1:34 clojurebot: Invalid token: /quit

1:34 OliverUv: i give up

1:35 slyrus: oh, but into a queue works. neet!

1:35 OliverUv: back to work

1:35 mmarczyk: slyrus: right :-)

1:38 tomoj: lancepantz: what do you mean as lists?

1:38 slyrus: oh, I would have thought last of a vector would have been O(1).

1:39 tomoj: lancepantz: better yet, what's an example?

1:40 mmarczyk: slyrus: apparently you have to use peek to get that

1:41 daaku: is there a better way to write this java code in clojure than using a let for what is returned by url(): queue.add(url("/worker").param("key", key)) ?

1:41 lancepantz: tomoj: http://gist.github.com/487069

1:42 line 8 and 9

1:42 hiredman: ,(doc doto)

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

1:42 tomoj: oh

1:42 that happens regardless of whether the second item is a vector

1:42 lancepantz: just when the first item isn't a recognized function i guess?

1:43 hiredman: slyrus: you can conj on to a pq and it will do the right thing

1:44 slyrus: right, but I wanted not to conj a vector on, but to have each element in the vector conj'ed on. into DTRT.

1:44 tomoj: even if it's a recognized function

1:44 that's how function calls should be indented

1:44 the problem is that it doesn't realize it's a macro

1:45 hiredman: slyrus: but conj doesn't do that for anything, so why would you expect that for pq?

1:46 slyrus: i didn't really. i was replacing an into call and didn't realize that pq's supported into.

1:46 operator error on my part, followed by pleasant surprise that pq's support into

1:46 lancepantz: tomoj: what about (into ["blah"] \n '("bar))

1:47 tomoj: lancepantz: yeah, it indents up to the first arg

1:47 slyrus: mmarczyk: http://github.com/slyrus/shortcut/blob/master/src/shortcut/graph.clj#L133 works. thanks!

1:47 lancepantz: the second line gets shifted to the end of into, that's why i assumed it had something to do with the 2nd element being a vecotr

1:47 tomoj: lancepantz: try eval'ing (define-clojure-ident (project-let 1))

1:47 er

1:47 (define-clojure-indent (project-let 1))

1:48 then M-q

1:48 mmarczyk: slyrus: great :-)

1:48 lancepantz: so i just put that in any buffer and do M-q?

1:49 tomoj: (into ["foo"] \n (bar)) and (into foo \n (bar)) will be indented the same way

1:49 no, put that bit of code into, say, *scratch*, put point at the end of it, C-x C-e

1:49 then go back to inside your deftest and hit M-q

1:49 if you're in aquamacs M-x emacs-lisp-mode in *scratch* before C-x C-e

1:50 lancepantz: sweet!

1:50 worked

1:51 tomoj: would it be evil to put metadata on your macro var that says how it should be indented? :)

1:52 lancepantz: hehe

1:52 would it be possible to extend clojure mode or swank to do that automatically for all defmacros?

1:52 tomoj: I think if your macro is named like def.* or with-.* it'll figure it out, but otherwise it just indents like functions

1:53 do we really want all macros to indent that way?

1:53 lancepantz: why not?

1:54 mmarczyk: tomoj: that would not be evil, that would be what we absolutely must make swank-clojure & clojure-mode handle asap!!!

1:54 :-)

1:54 tomoj: lancepantz: I dunno, I wasn't saying we don't, really asking

1:54 can't think of any counterexamples

1:54 mmarczyk: incidentally, even defrecord seems to be indented pretty badly

1:55 tomoj: the method defs you mean?

1:55 mmarczyk: unless my clojure-mode is outdated -- which is possible

1:55 yeah

1:55 same for letfn

1:55 tomoj: yeah

1:55 because it's looking at the car and those are unrecognized

1:55 mmarczyk: condp is weird too

1:55 right

1:55 lancepantz: i'm not familiar with how they all play together, is it something you could do just in clojure-mode?

1:56 mmarczyk: last time I checked, it was in need of a refactoring

1:56 tomoj: yeah it looks pretty nasty

1:56 my coloring seems to be screwy

1:56 Lajla: ,(contains? '#{I worship His Shadow} 'His)

1:56 clojurebot: true

1:56 tomoj: oh wait that's elisp

1:57 mmarczyk: yeah... my elisp-fu is a bit shaky, so I'm reluctant to take the c-m refactoring on my plate

1:57 but if it doesn't magically happen within a month, say, I will anyway

1:58 tomoj: I have noticed screwy colors before in clojure-mode though

1:58 like the same function being colored differently in different places

1:58 mmarczyk: well, functions get different colouring depending on whether they're in the operator position

1:58 iirc

1:59 tomoj: I mean in operator position, just different places in the file

2:00 mmarczyk: oh? weird

2:00 I do occasionally experience funky highlighting with both Emacs and Vim when they decide, say, that most of my code is a comment (or a string maybe)

2:01 annoyingly, as far as I can tell, there's nothing to be done about it

2:01 tomoj: never seen that in emacs

2:01 mmarczyk: but no small random changes in colour

2:10 zmyrgel: I'm trying to get started with clojure but I keep getting NPE when I'm running 'lein swank'

2:10 any ideas what could be wrong

2:10 tomoj: paste the stacktrace (somewhere other than here)

2:11 probably go ahead and paste your project.clj too

2:11 zmyrgel: tomoj: http://pastebin.com/GqsxEMjJ

2:12 tomoj: oh yeah

2:12 bsd?

2:12 or something else weird?

2:12 no offense :)

2:12 slyrus: can I extend/inherit from a record and give it additional fields?

2:12 zmyrgel: tomoj: yeah, running openbsd

2:13 tomoj: right, this should've been fixed already

2:13 guess the last person who had this problem never submitted a bug

2:13 zmyrgel: tomoj: http://pastebin.com/wuUmny6y

2:13 tomoj: technomancy: ping

2:13 mmarczyk: slyrus: no

2:13 zmyrgel: theres one with project.clj

2:14 tomoj: zmyrgel: lein -v ?

2:15 doesn't matter, the bug is still there in the latest it looks like, but that project.clj looks old

2:15 slyrus: mmarczyk: hmmm... makes it hard to extend my graph record then. perhaps I don't want a defrecord.

2:15 tomoj: clojure 1.2.0-beta1 is out, probably better to use it instead of 1.1.0

2:16 zmyrgel: just run 'lein self-install' before made the project

2:16 mmarczyk: slyrus: deftypes won't allow you to do that either

2:16 slyrus: right

2:16 mmarczyk: I think... though somebody wanted that for interop with some Java framework or other

2:16 I mean, someone wanted them to create non-final classes

2:16 dunno what became of that

2:17 tomoj: zmyrgel: I think your only choice right now is to fix the bug yourself (I can help you, it's simple) and use a development version of lein

2:17 mmarczyk: slyrus: but note that records can act like maps

2:17 (defrecord Foo [])

2:17 (:x (assoc (Foo.) :x 1))

2:17 => 1

2:18 zmyrgel: tomoj: whats the correct way to check for the clojure versions available for lein?

2:18 1.2.0-BETA didn't work

2:18 tomoj: I don't know if there is a nice way, but you can just peek at http://build.clojure.org/releases/org/clojure/clojure/

2:19 zmyrgel: ok

2:19 slyrus: mmarczyk: so what's special about the fields declared in the defrecord?

2:19 tomoj: zmyrgel: have you gotten a clojure repl up at all?

2:19 mmarczyk: slyrus: you can access them directly in method bodies

2:20 slyrus: and also through interop syntax -- (.x (Foo. 1)) if Foo is declared with an x field

2:20 zmyrgel: tomoj: I tested it quickly with my clojure shell script after I compiled the version from git

2:20 tomoj: download http://build.clojure.org/releases/org/clojure/clojure/1.2.0-beta1/clojure-1.2.0-beta1.jar, and then run: java -jar clojure-1.2.0-beta1.jar

2:20 oh, ok

2:20 if that still works, do that

2:20 slyrus: mmarczyk: and I suppose you can actually access x from java code as well

2:20 mmarczyk: slyrus: field access is faster than map lookup

2:20 tomoj: just need a clojure repl so you can peek at the system props to figure out the appropriate value to fix the lein bug

2:20 mmarczyk: slyrus: right, you can

2:21 zmyrgel: tomoj: ok, hold on a moment

2:21 mmarczyk: slyrus: with assoc'd entry's, you still can, but it's a bit more convoluted

2:21 tomoj: zmyrgel: at the repl do (System/getProperty "os.name") and (System/getProperty "os.arch")

2:22 mmarczyk: slyrus: something like (.get (assoc (Foo.) :x 1) :x)

2:22 zmyrgel: tomoj: gives "OpenBSD" and "amd64"

2:22 tomoj: ok, great

2:22 you're going to have to clone leiningen and fix this: http://github.com/technomancy/leiningen.git

2:23 slyrus: given that this all java underneath, it's surprising that records can't extend other records. is there some major efficiency win with final classess?

2:23 mmarczyk: tomoj: so what's this problem with lein actually?

2:23 jacortinas: yeah I just got

2:23 here

2:23 explain please

2:23 hiredman: (:x (Foo. 1)) has some optimizations too

2:23 if Foo has a field named x

2:24 (and Foo is a defrecord)

2:24 mmarczyk: slyrus: Clojure doesn't want OOP-style inheritance

2:24 tomoj: zmyrgel: in src/leiningen/compile.clj, on line 49, there's a native-names hash

2:24 mmarczyk: slyrus: I mean, let Java *stay* underneath ;-)

2:24 tomoj: zmyrgel: you need to add "OpenBSD" :openbsd to that

2:24 slyrus: to paraphrase, don't anthropormhize clojure. it hates it when you do that.

2:25 anthropomorphize

2:25 jacortinas: you could probably just make the change and then send stuart a pull request

2:25 hiredman: clojure generates caches for keyword call sites and if the call site stays monomorphic hotspot has a fair chance of inlining

2:25 jacortinas: he's pretty nice about that stuff

2:25 mmarczyk: slyrus: I thought occasionally "Clojure" might make a good euphemism for "Rich" ;-)

2:25 slyrus: heh

2:26 hiredman: slyrus: class inheritence is bad

2:26 slyrus: well, java's implementation sure, but CLOS is pretty nice

2:27 mmarczyk: tomoj: just adding "OpenBSD" :openbsd would fix it?

2:27 tomoj: yep, pretty sure

2:27 zmyrgel: tomoj: ok, done. Now how do I compile that?

2:27 hiredman: http://www.artima.com/intv/gosling3P.html

2:27 tomoj: zmyrgel: then I think after making the change you can just `lein install` in the leiningen project root

2:27 er.. fuck

2:27 `lein install` ain't gonna work because of this bug, I guess

2:28 fualo: for the life of me I can't get clojure-contrib to work. I've built it with maven, checked the class path, but I still keep getting ClassNotFound... - config here http://dpaste.com/221107/

2:29 tomoj: zmyrgel: what's `lein -v` say? maybe I can compile the patched lein for you

2:29 zmyrgel: tomoj: Leiningen 1.1.0 on Java 1.7.0-internal OpenJDK 64-Bit Server VM

2:30 tomoj: yep, lein install gives NPE too

2:30 tomoj: well, I'm Java 1.6.0_20 Java HotSpot(TM), will it work?

2:30 dunno

2:30 hiredman: fualo: don't use any of the scripts

2:30 tomoj: class files must be somewhat portable, right?

2:31 hiredman: I've never seen a script launcher that was any good

2:31 mmarczyk: tomoj: zmyrgel: actually lein's jar only includes one aot'd namespace

2:31 fualo: hiredman: I had a feeling that following the first thing that comes on google would be bad... what's the preferred way?

2:31 tomoj: mmarczyk: the one I've got includes clojure itself

2:31 mmarczyk: tomoj: zmyrgel: so you can fix compile.clj and replace the old one with it it in the jar

2:31 hiredman: java -cp … clojure.main

2:31 tomoj: zmyrgel: ah, yes, do that

2:32 mmarczyk: tomoj: ah, yeah... but of lein's own namespaces, only one is aot'd

2:32 zmyrgel: mmarczyk: I'll try that

2:32 tomoj: if you use emacs you can probably C-x C-f ~/.m2/repository/leiningen/leiningen/...whatever...jar

2:32 mmarczyk: namely leiningen.core

2:32 tomoj: then edit compile.clj in place

2:32 mmarczyk: zmyrgel: let us know how it goes

2:32 fualo: hiredman: well a script to prevent someone from typing that seems... more efficient, no?

2:33 mmarczyk: then I'll commit the fix to lein's head

2:33 tomoj: you have commit rights?

2:33 mmarczyk: surprisingly I do

2:33 tomoj: cool

2:34 mmarczyk: how do you want to be credited, btw?

2:34 tomoj: I think the real fix is to fail gracefully when the os isn't found

2:34 mmarczyk: true that

2:34 tomoj: almost all of the time you don't care about native deps anyway, but if your os isn't in the list, you're screwed

2:35 mmarczyk: right

2:35 hiredman: fualo: *shrug* you can be efficent if you want, I prefer a working repl

2:35 fualo: :-)

2:36 I was just asking... either way, it's not working that way either http://dpaste.com/221110/

2:38 hiredman: where did you get your clojure jar?

2:39 tomoj: http://github.com/technomancy/leiningen/issues#list

2:39 er

2:39 hiredman: I think you have an old version of clojure and a new version of clojure-contrib

2:39 tomoj: dammit github, I can't copy the link because you intercept 'c'

2:39 but I made an issue

2:40 http://github.com/technomancy/leiningen/issues#issue/81

2:40 hiredman: b

2:42 tomoj: fualo: any particular reason you don't want to use lein?

2:43 fualo: hiredman: I just tried it with the github master branch.. still nothing

2:43 hiredman: fualo: nothing the same?

2:44 fualo: yes, (:require clojure.contrib) still doesn't work

2:44 hiredman: what do you mean tried with the master branch? which repo, and what did you do with it?

2:44 what do you mean doesn't work?

2:44 fualo: tomoj: I could, I'm a newb so I'm still getting used to the environment

2:45 http://dpaste.com/221112/ nothing still

2:45 hiredman: how are you trying to use (:require clojure.contrib) ? have you read the api docs and noticed there is no :require? have you read the docs for require? are you aware there is no namespace named clojure.contrib?

2:46 fualo: apparently not which could be the idiotic source of my problems

2:46 tomoj: fualo: no need to compile anything from source :)

2:47 hiredman: fualo: http://richhickey.github.com/clojure-contrib/ has a list of namespaces that are in contrib

2:48 fualo: ah, works now, with string

2:48 thanks, sorry for my error

2:48 tomoj: with lein you mean/

2:48 tomoj: right

2:48 hiredman: http://clojure.org/ has a nice list of things to read titled "Reference" in the links on the left

2:49 tomoj: fualo: https://gist.github.com/96f82fbef21f189bb7a4

2:50 bartj: anyone has used a simhash library in java/clojure ?

2:52 tomoj: (that downloads clojure and contrib automatically)

2:53 fualo: thanks tomoj!

2:53 for just the project directory?

2:54 ah, yes, I see

2:54 tomoj: well, it downloads it into ~/.m2/repository/...

2:54 any lein/maven project will use that copy

2:55 fualo: tomoj: does lein have emacs integration?

2:55 tomoj: er, except lein copies it into ./lib

2:55 yep :)

2:55 are you already familiar with emacs?

2:55 fualo: quite :-)

2:55 tomoj: got slime already?

2:55 fualo: yup

2:55 tomoj: hrmm

2:55 fualo: through ELPA

2:56 tomoj: oh, cool

2:56 install clojure-mode as well from ELPA

2:56 then add :dev-dependencies [[swank-clojure "1.2.1"]] to your project.clj

2:56 `lein deps`, `lein swank`, then M-x slime-connect

2:58 slyrus: my brain hurts trying to unlearn my CLOS and java inheritance habits

2:59 fualo: tomoj: it says lein swank isn't a task in lein, but lein deps clearly downloaded it

3:00 tomoj: you have lib/dev/swank-clojure...jar ?

3:02 did you run `lein deps` and `lein swank` both in your project root?

3:02 fualo: ah, my brain didn't prase dev-dependences, so I put it under dependincies

3:02 s/prase/parse

3:03 tomoj: works, sweet!

3:03 zmyrgel: I guess 17s to run 'lein help' is too much...

3:03 fualo: tomoj: thanks

3:06 zmyrgel: tomoj: mmarczyk: thanks, lein seems to work now although terribly slow for some reason

3:06 tomoj: fualo: src/foo/bar/baz.clj for (ns foo.bar.baz)

3:06 zmyrgel: JVM startup time :(

3:07 mmarczyk: tomoj: zmyrgel: cool, thanks!

3:08 so it's "OpenBSD" :openbsd... adding now

3:09 fualo: tomoj: and this downloaded its own clojure.jar somewhere?

3:09 tomoj: yeah, ~/.m2/repository/org/clojure/...

3:09 lein downloads all deps into ~/.m2/repository

3:10 zmyrgel: tomoj: I'd say it should be faster than 17 secs

3:10 fualo: excellent... very interesting dev system compared to other langs I know

3:11 tomoj: zmyrgel: 3s here

3:11 zmyrgel: tomoj: that would be quite a bit better

3:12 mmarczyk: tomoj: zmyrgel: fix pushed, thanks

3:14 tomoj: dunno what could cause that besides JVM startup time.. hmm

3:17 zmyrgel: at least it works

3:24 bartj: just discovered clojuredocs.org - a million times better than javadocs - thanks!

3:25 slyrus: hmm... maybe just doing away with the record all together and just extending the IPersistentMap protocol is the right thing to do here.

3:27 tomoj: slyrus: is the problem just that you want to add more fields?

3:27 slyrus: take any map and turn it into a graph by assoc'ing ::node-set and ::edge-map to it.

3:28 that's part of it. I think the bigger issue is getting a sense of how to do a nice clean design for this graph stuff.

3:28 tomoj: I've wondered about that problem too

3:29 the smaller issue is easy, you can add whatever fields you want

3:29 slyrus: i'm thinking i don't really need the record and that I can just use the protocol and extend IPersistentMap. seems to be working so far. perhaps there's a performance, but this can always be optimized with a defrecord version later if so.

3:29 tomoj: sure, but if I'm going to do that, why bother with two classes of fields? the defrecords and the map key/vals.

3:30 might as well just leave the damn thing as a map.

3:30 no one can take an arbitrary map and make it a graph.

3:30 anyway, time to sleep on this. thanks for helping me think this stuff through.

3:36 AWizzArd: Is there a way to ignore parts of a jar task in Ant?

3:37 Something like fail, but which does not abort the build

4:02 Raynes: Time to compile GHC. I should be able to hop on my computer and ride the CPU fan to France before it's finished.

4:04 zmyrgel: I liked my compilation of OpenJDK7 better

4:05 first compile JDK5, then JDK6 and then OpenJDK :)

4:05 took a while

4:22 Raynes: chouser: Your guy got me hooked up with a new download link. Thanks. :)

5:08 cais2002: hi, is there a function that can replace the keys in a map based on another map of old-new key mapping?

5:08 (replace-key {:1 1 :2 2} {:1 :a, :2 :b}) ==> {:a 1 :b 2}

5:09 Raynes: ->(merge {:1 1 :2 2} {:1 :a, :2 :b})

5:09 sexpbot: => {:2 :b, :1 :a}

5:09 Raynes: Oh. Keys.

5:12 AWizzArd: cais2002: not implemented yet

5:12 tomoj: what does (replace-key {:foo 1 :bar 2} {:foo :baz :bar :baz}) return ?

5:13 s/does/should/

5:13 sexpbot: what should (replace-key {:foo 1 :bar 2} {:foo :baz :bar :baz}) return ?

5:14 cais2002: hmm, have not thought about that, yet

5:15 I want any key/value in old map that are not found in key-map to be retained..

5:15 Raynes: (defn replace-keys [oldmap newkeys] (into {} (map (fn [[k v]] [(if-let [newk (newkeys k)] newk k) v]) oldmap)))

5:15 cais2002: you guys can decide on the semantics when new keys conflict

5:16 Raynes: -> (def replace-keys (fn [oldmap newkeys] (into {} (map (fn [[k v]] [(if-let [newk (newkeys k)] newk k) v]) oldmap))))

5:16 sexpbot: => #'net.licenser.sandbox.box3508/replace-keys

5:16 Raynes: -> (replace-keys {:1 1 :2 2} {:1 :a, :2 :b})

5:16 sexpbot: => {:b 2, :a 1}

5:17 Raynes: -> (replace-keys {:1 1 :2 2 :3 3} {:1 :a, :2 :b})

5:17 sexpbot: => {:3 3, :b 2, :a 1}

5:17 Raynes: cais2002: How's that?

5:17 cais2002: raynes: that should work

5:18 Chousuke: I like how that exploits the fact that maps are functions

5:19 -> (replace-keys {"foo" 'bar, "some" 'other} symbol)

5:19 sexpbot: => {some other, foo bar}

5:20 cais2002: -> (replace-keys {"foo" 'bar, "some" 'other} keyword)

5:20 sexpbot: => {:some other, :foo bar}

5:20 cais2002: Chousuke: good point

5:21 tomoj: Raynes: do you have special privs with sexpbot or did you figure out some magic way to make def safe?

5:21 Raynes: tomoj: Licenser made it so that def is safe. Only 5 defs are kept in memory at any given time.

5:21 defn doesn't work right now, but likely will soon.

5:22 serp_: why would def be unsafe?

5:22 Raynes: serp_: Memory overload.

5:22 If you def stuff, that stuff is kept in memory.

5:23 tomoj: oh, and we can't switch the namespace?

5:23 serp_: aha

5:23 Raynes: I hope not.

5:23 tomoj: :)

5:32 Chousuke: Raynes: does it clear the defs if there is an OOM exception?

5:33 Raynes: Chousuke: No, it just only keeps 5 in memory at a time.

5:34 Chousuke: so I guess you could still OOM it by defing an infinite sequence.

5:35 Raynes: Chousuke: Except that is impossible to do with sexpbot's timeouts.

5:35 Chousuke: is it? def fibs, take some number of fibs, then take some more, until memory is filled :P

5:36 Raynes: I don't see how that would work.

5:37 Chousuke: or you could make an infinite seq that creates some huge objects, so memory fills up quickly.

5:38 since you can expand the seq just a bit at a time until enough of it is cached, the timeouts aren't effective

5:39 Raynes: Then, I guess I'll be taking def support out of sexpbot and tryclojure.

5:40 Looks like tryclojure is going to be useful for just about nothing when I'm finished with it.

5:40 Chousuke: well you could just catch OOM errors and reset the namespace

5:40 and maybe ban IPs that abuse it too often :P

5:41 it won't be a problem if you limit the JVM to 64 MB or something similar

5:42 Raynes: Dealing with sandboxing has been the most frustrating thing I've ever done.

5:43 Chousuke: sandboxing a compiler, dynamic language not designed for sandboxing is probably not the easiest task :P

5:43 compiled*

5:44 Raynes: It's more annoying than anything. No matter what you do, you still never get it right.

5:44 cais2002: so basically, (into {} (map some-func some-map)) is the pattern to do an update on some-map based on some-func , right?

5:45 Chousuke: yeah

5:45 I'd like a protocol-based fmap in core someday though

5:45 Raynes: That's how I do it. :P

5:46 functors!

5:52 tomoj: what the heck is in-ns?

5:52 AWizzArd: ,(doc in-ns)

5:52 clojurebot: "([name]); Sets *ns* to the namespace named by the symbol, creating it if needed."

5:52 tomoj: ,(class in-ns)

5:52 clojurebot: clojure.lang.RT$1

5:53 AWizzArd: An inner class of RT.

5:53 tomoj: ,(ancestors (class in-ns))

5:53 clojurebot: #{clojure.lang.AFn clojure.lang.IFn java.lang.Object java.util.concurrent.Callable java.lang.Runnable :clojure.contrib.generic/any}

5:53 cais2002: -> (merge {1 2} [3 4] [5 6])

5:53 sexpbot: => {5 6, 3 4, 1 2}

5:53 cais2002: -> (merge [1 2] [3 4] [5 6])

5:53 sexpbot: => [1 2 [3 4] [5 6]]

5:54 cais2002: -> (doc merge)

5:54 sexpbot: => ------------------------- clojure.core/merge ([& maps]) Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping from the la... http://gist.github.com/487229

5:54 cais2002: seems that merge could be applied to any coll?

5:55 -> (source merge)

5:56 sexpbot: java.lang.Exception: Unable to resolve symbol: source in this context

5:56 Raynes: tomoj: Having fun trying to break sexpbot? :p

5:56 tomoj: are you watching?

5:56 and yes :)

5:57 keep running into dead ends though, damn you

5:57 Raynes: tomoj: Indeed. I'm always watching.

5:57 tomoj: why doesn't (binding [*ns* ...] (def foo)) do what I want?

5:58 cais2002: how is #(some identity %1) different from #(empty? %1) when being used as a pred?

5:59 Chousuke: cais2002: the first tests if the seq contains anything truthy

6:00 Raynes: -> (filter (partial some identity) [[nil 3] [nil]])

6:00 sexpbot: => ([nil 3])

6:00 Raynes: -> (filter empty? [[nil 3] [nil]])

6:00 sexpbot: => ()

6:01 Raynes: Also, cais2002: http://clojuredocs.org/v/2101

6:02 I can't wait for that site to have an API.

6:02 sexpbot will be all over that.

6:02 Chousuke: cais2002: the second tests if it's empty :/

6:02 (also #(empty? %1) is equivalent to empty?)

6:03 cais2002: ok, I got it

6:05 so the "when" in (source merge) is to return nil if all items in maps are nil?

6:38 tomoj: -> (+ 2 2)

6:38 sexpbot: => 5

6:38 tomoj: Raynes: still around?

6:42 not caused by allowing def

7:25 bobo_: hm? what did you do? :-)

7:27 tomoj: won't share till it's fixed, sorry :P

7:30 bobo_: hehe ofc

8:04 defn: morning all

8:05 any former Rubyists with a firm grasp on Clojure sequences/collections care to elaborate on how Enumerable compares to the sequence abstraction?

8:12 tomoj: not lazy?

8:13 bozhidar: not all sequences are lazy

8:13 tomoj: not even possibly lazy

8:13 bozhidar: indeed

8:24 Raynes: tomoj: What did you do?

8:28 Licenser: tomoj: I was told you have a bug for me?

8:28 tomoj: -> (+ 2 2)

8:28 sexpbot: => 4

8:29 Licenser: Looks logical so far

8:29 tomoj: oh, but see above :)

8:31 Raynes: <tomoj> -> (+ 2 2)

8:31 <sexpbot> => 5

8:31 Damn you, XChat.

8:31 Licenser: Tomj my backlog sadly does not go that far back

8:31 tomoj: ah

8:31 Licenser: Question being how?

8:31 tomoj: did you get my PM?

8:31 Licenser: Oh yes

8:32 Sorry mobile collequary isn't that compfortabke

8:34 chouser: defn: ruby enumerables iterate "inside out" compared to clojure seqs. A clojure seq you can walk a bit, then set aside for later. To do that with a ruby enumerable would require callcc magic, I believe.

8:48 Licenser: Greetings

8:52 defn: chouser: thanks so much for that -- /me wonders about using continuations in Ruby to do that...

8:54 chouser: I imagine it could be done.

8:55 defn: I haven't dusted off a continuation in a longggg time.

8:55 They scare me just a bit. :)

8:56 Raynes: chouser: Did you get my message earlier?

8:56 chouser: A friend and I wrote a rather tortured iterator in ruby to walk to arbitrary enumerables in step (like clojure map with multiple collection args)

8:56 using callcc. mind-bending.

8:56 Licenser: What is callcc?

8:56 defn: call current continuation

8:57 Licenser: Oh okay

8:57 chouser: Raynes: had missed it. glad it's taken care of.

8:57 Licenser: Guess that I'd ruby not clojure right

8:57 defn: hmph, I didn't know Sussman and Steele coined "continuation-passing style"

8:57 Licenser: yeah callcc is ruby

8:58 Licenser: Okay

8:59 defn: ahh, I guess there are "first class continuations", which Ruby and Scheme support, but Clojure doesn't (yet ;)

8:59 and one google later I am proven wrong: http://github.com/swannodette/clj-cont

9:00 http://github.com/swannodette/clj-cont/blob/master/test/net/dnolen/clj_cont/core_test.clj

9:00 fun stuff.

9:01 dnolen: defn: well that's a hack based on a hack to get continuations in Common Lisp :)

9:02 defn: dnolen: there you are :)

9:02 dnolen: at some point I need to clean that up, there's some silly stuff in there I think around Java interop

9:02 Licenser: Wow and I don't even know what continuations are. :P

9:03 defn: dnolen: does it allow for "first class" continuations?

9:05 dnolen: defn: don't think so, clj-cont supports http://en.wikipedia.org/wiki/Delimited_continuation

9:05 I believe first class continuations can capture the whole context, with clj-cont you have state where you want to start capturing context

9:06 defn: yeah i was just reading the code and wondered what (def *ctx*) was :)

9:06 dnolen: anyway, very interesting code and wiki article to go with it

9:06 thanks!

9:07 dnolen: defn: the best place to see what it can do is to look at the tests. there's a lot of coverage

9:08 defn: yeah i noticed that -- pretty cool stuff.

9:27 lpetit: stuarth: Hi, I see you're changing / committing things in pom.xml that *may* (I'm not anymore a maven expert, since maven 2 is out !) be held once and for all by, I think, adding a profile for stable releases, and a profile for snapshot releases (or even just one release if you make the default configuration work for e.g. the snapshot release)

9:32 defn: Licenser: continuations are like monads, only harder to reason about IMO :)

9:33 see: the continuation monad *scared look on his face*

9:35 Licenser: http://intensivesystems.net/tutorials/cont_m.html <--great article on clojure and continuations

9:37 tomoj: isn't the continuation monad a poor man's continuation?

9:38 defn: yeah

9:38 it just sounds scary if you know what monads and continuations are, but dont know specifically the continuation monad :)

9:38 tomoj: weblocks only has cl-cont to work with

9:38 so I have hope

9:38 defn: what is weblocks? (forgive the ignorance)

9:39 tomoj: some CL web framework

9:39 what I really want is nagare in clojure

9:39 except nagare gets first-class continuations from twisted (I think?)

9:39 defn: I want JRuby + Clojure

9:39 tomoj: but maybe it can be done with clj-connt

9:39 defn: err JRuby + Rails + Clojure

9:40 a nice bridge between the two

9:40 tomoj: why would you want that? :P

9:41 defn: because I want my rails -- maybe it's just my comfort zone with rails, but something irks me about web development with clojure

9:41 doing MVC is difficult since everything depends on everything else

9:41 tomoj: oh, yeah, for sure

9:41 I use drupal at work

9:42 because we can get a lot done quickly

9:42 defn: you can't have your controllers and views separate, they must live together, and that is...weird

9:42 tomoj: but drupal still is a terrible terrible thing

9:42 defn: enlive could help, but i find it a bit cumbersome tbqh

9:42 tomoj: yeah, drupal is a terrible beast

9:42 it must die.

9:42 tomoj: web dev in clojure will be awesome someday

9:43 defn: yeah -- we have the "rack" with ring

9:43 just a matter of time i suppose

9:43 tomoj: I'm not really interested in a translation of rails, personally

9:43 defn: nor am I per se

9:43 tomoj: happstack or nagare or weblocks or something, sure

9:44 defn: the feeling of rails is a feeling of: "ahhhh *sips beer*, this is refreshing"

9:44 tomoj: I hate beer

9:44 defn: tea?

9:44 tomoj: :P

9:44 clojurebot: I want to go to there

9:45 defn: tomoj: either way, it's just the idea that it has a sort of feeling to it, a sort of identity (ironic)

9:45 tomoj: haha

9:45 defn: i know it sounds sort of wishy washy

9:45 tomoj: yeah I guess I miss those day

9:45 s

9:45 and maybe rails 3 is better

9:46 defn: remember when it wasn't cool to like ruby? lol

9:46 tomoj: but I just can't bring myself to happily use ruby now :(

9:47 defn: tomoj: oh c'mon! it can still be fun!

9:47 ruby@github => playground

9:48 i look at a lot of projects that were done in ruby a few years back -- there was an air in the community where any idea was worth implementing or trying, and people were BOLD

9:48 those ideas are still valid -- even if those projects were abandoned

9:49 tomoj: and now people are complaining about that

9:49 defn: there is still a lot to improve and investigate

9:49 I don't listen to Eeyores as a matter of course.

9:49 They don't ever do anything.

9:49 tomoj: one the one hand it does seem a bit silly -- no one's forcing you to use this code

9:49 defn: on the other hand -- there is no other hand.

9:50 tomoj: abandoned projects don't bother me

9:50 shitty projects do

9:50 a bit

9:50 defn: yeah, plenty of those -- i've started a few for clojrue

9:50 clojure

9:50 tomoj: this is why I haven't released anything in clojure :)

9:50 defn: oh well, gotta "break a few eggs" as they say...

9:51 tomoj: what's the 2007 hacker meme? "real programmers ship"?

9:51 i know how you feel -- it's terribly nerve-racking to have anyone in this community look at my code. it's complete garbage.

9:51 on the other hand, it feels sort of liberating

9:52 because their code has no personality, no one to read it -- lonely code.

9:52 Plouj: liberating from what?

9:52 defn: Plouj: listening to the inner voices that tell you it's not good enough, or someone could and will do it better, etc.

9:55 that sort of mentality is just depressing -- it's no way to treat yourself, and it's no way to treat your code IMHO.

9:57 mini rant: take gists for example. so much of it is junk, and yet so much of it is fantastic. and so muuch of it that is junk holds elements of fantastic gists to come, and so on.

9:58 it's a conversation, not a contest.

9:59 chouser: to me there's a big difference between "some code" and "a library" or "a tool"

10:00 for the latter, I want to be a user that can rely on stable releases, good docs, and largely ignore the interals.

10:01 that means producing "a library" is a good deal more effort than just producing code that works -- you need releases, future plans, bug tracking, ongoing maintenance, etc. ..in short the kind of stuff I'm rarely willing to do without money changing hands.

10:01 OliverUv: defn: yeah, I managed to abandon perfectionism in my late teens and am very glad for that

10:01 chouser: but "some code" is just that. take it or leave it. harvest some ideas and make it your own. turn it into a library if you want, etc.

10:01 fun.

10:01 often not very usful. :-/

10:02 defn: OliverUv: it still bites at us though :)

10:02 chouser: well said

10:03 tomoj: so when we put some code on github, we should make it clear that it's not a library, I guess

10:04 defn: chouser: however, so are most of my conversations. maybe im a bit idealistic but i think of clojure as a real human language, as if we're speaking some foreign language right now, but clojure is our native tongue -- and through reading eachother's code, fun or not, we learn more about how to express ourselves and build things that are great

10:04 tomoj: that's related to some of the complaining I heard -- giving your shitty code a slick website and hype

10:04 defn: i think in addition there should be a "pledge of support" document

10:05 detailing how the author intends to support their code

10:05 "sparingly", "weekends only", or "you're on your own."

10:05 in additiong *to a license

10:05 tomoj: if your code says "you're on your own", I won't eeyore at you if it's shitty :)

10:06 defn: haha -- fair enough :)

10:06 chouser: I suppose I should update http://n01se.net/gmapez to say "I stopped caring about this a while ago..."

10:06 tomoj: I suppose the eeyore's should take silence as "you're on your own" to be safe

10:07 fogus: tomoj: If your code is bad then hype and pretty websites make it better no? ;-)

10:07 defn: if you were an eeyore you wouldn't be using clojure :)

10:08 tomoj: actually my mom used to call be eeyore

10:08 different sense I guess

10:08 defn: im always amazed when an author has a website at all in addition to his moderately popular project

10:08 it seems almost impossible to find the time for both without falling behind on one of them

10:09 chouser: could i convince you to give me your #clojure log archive again btw? my VPS required a reboot and i didnt have irssi logging by default and have missed a few days here and there

10:10 this whole discussion is making me feel so guilty about walton I want to cry

10:23 Who is all going to strange loop?

10:25 mefesto_: defn: is this an upcoming conference?

10:25 drewr: defn: still considering

10:25 defn: yeah in october

10:25 mefesto_: link?

10:25 defn: i just pulled the trigger last night on my ticket

10:25 clojurebot: your link is dead

10:25 Scriptor: defn: hmm, st. louis seems a little out of the way

10:25 http://thestrangeloop.com/about

10:25 mefesto_: tks

10:25 um, thanks too

10:26 neotyk: to far from EU

10:26 defn: im in WI so St. Louis is kind of a nice change from Seattle

10:26 neotyk: would love to go there though

10:26 Scriptor: I like how guy steele says he's a slacker on the speakers' page

10:27 defn: :)

10:38 arkh: defn: are you in madison? I miss that city.

10:42 defn: arkh: yeah im in madison

10:42 arkh: go to school here?

10:43 * fogus imagines what would happen if Guy Steele became motivated

10:44 arkh: defn: I did. I remember walking across campus to the comp sci building in the middle of winter really well ;)

10:44 defn: fogus: bacon would taste like eggs

10:44 arkh: :)

10:45 arkh: i failed out of college. pretty sensitive about that at the moment as all of my friends are graduating. trying to get up the nerve to quit my software engineering job and take on some debt to finish up CS.

10:46 </TMI>

10:46 Scriptor: defn: how much do you have left to do?

10:46 arkh: defn: I was in a similar spot. Sometimes it just timing - do it when you're ready :) I did much better in school when I did on my own schedule.

10:46 ugh ... typos

10:47 sounds like I need to go back again ...

10:47 defn: Scriptor: 2.5 years probably. It's kind of funny -- all of the time I've spent outside of school has been reading books on algorithms and writing code...

10:47 Scriptor: yea, I know what you mean, motivation seems to do the opposite when it's coming from outside

10:47 defn: I started studying music, then philosophy, then realized I spend all of my time writing code anyway

10:48 Scriptor: anyone know good music to write docs to? I'm using classic jazz

10:48 tomoj: CS->phil seems to be somewhat common

10:48 arkh: from my point of view, some people can play the game of school well - go to classes and do the homework the way they want it. But learned the most and had the most fun when my learning was on my own, at my pace, learning what I wanted. As I got older, I learned how to balance both.

10:48 defn: I like AFX (Aphex Twin), Rumpistol, Ochre

10:49 but I love me some classic jazz too, can't go wrong with charlie mingus

10:50 abedra: mashups!

10:50 defn: I think the hardest thing I'm struggling with re: school right now is that I'm motivated, but due to my GPA they want me to go somewhere else and essentially waste a year of my time that I could be working, to get back into their good graces

10:51 Scriptor: where do they want you to go?

10:51 * defn fights his gag reflex

10:51 defn: a local technical college

10:51 arkh: they might take you back after one semester of good grades at MATC. It's a sour pill but part of the game.

10:52 abedra: defn: take more time off. You're obviously still sensitive about it. Wait till you don't have any emotions involved and you'll do much better

10:52 Scriptor: defn: in case you aren't, try working on a large-scale project of your own or that's open source, might be good therapy

10:53 defn: arkh: yeah :\, abedra: good advice, Scriptor: good advice

10:54 I actually emailed the dean of Letters and Sciences last night asking (begging) for a meeting

10:54 chouser: defn: I'm a little curious what you expect to get out of a degree. rhickey has a degree, for example, but it's in music.

10:54 bhenry: i have tried do and doall, but don't think i understand them correctly. i want to evaluate copy-imgs and use the file objects in a webapp. i can run copy-imgs from the repl and it copies, but when i run (do (copy-imgs path) (get-images path) i expect that copy-imgs will perform the copy and the do will return the results of get-images. this is not the case. how can i do both at once? http://gist.github.com/487537

10:54 defn: chouser: partly, I just want to prove to myself I can do it. I was young and made some stupid choices.

10:54 OliverUv: for me a degree would entail a salary increase of about a third

10:55 maybe two thirds

10:55 tomoj: bhenry: for is lazy

10:55 defn: chouser: plus, I've spent a lot of (my parent's money) on school

10:55 and I feel like I owe it to them

10:55 OliverUv: defn: smokin'weed every day?

10:55 tomoj: bhenry: replace your for with doseq

10:55 defn: OliverUv: ha! Actually, my pattern of avoidance is more like: "must learn more clojure..."

10:55 OliverUv: heh

10:56 for me it was "sit and watch more tech talks and talks from hacker cons

10:56 Scriptor: degrees can definitely make you seem less risky to hire

10:56 defn: OliverUv: yeah that sounds familiar :)

10:56 OliverUv: it feels so productive and yet it isn't

10:57 defn: I can't be bothered with Astronomy! I need to learn next semester's math course which I'm not currently taking!

10:57 ah, silly passion... always getting in my way...

10:58 Scriptor: I'm guessing you decided to take astronomy though :)

10:58 defn: i think the worst part about how school went for me is that I never just "didn't learn it"

10:59 I actually read and in some cases took lots of detours on the sylabus to get my own view, and in some cases I was handsomely rewarded with an A

10:59 where in other cases I was told my response didn't fit the prompt

10:59 makes a young man awfully jaded...

11:02 anyway, enough of the E True Defnwood Story (However, if you're a tenured professor who could hold any weight over admissions at any decent CS programs and want to recommend me, I know UHaul's number)

11:03 bhenry: tomoj thanks. it worked.

11:03 arkh: defn: lol

11:03 Scriptor: eh, I don't think there's a ton of traffic in here usually

11:03 though I mostly just idle

11:03 defn: arkh: :) I really want to go back to school after working at an enterprisey place for a few years

11:04 I think about the time I have to study now vs. then

11:04 arkh: defn: I really think time helps people eventually gain focus, even when that focus needs to be on things you'd rather not be doing.

11:05 not to be confused with gaining fogus (?)

11:05 tomoj: bhenry: it worked at the repl before because the repl printed the return value of copy-imgs, realizing the lazy seq

11:05 in the do, you do nothing with the return value, so it is never realized

11:05 defn: arkh: yeah, I really should have just not gone to school, but instead I listened to people who told me I'd never go back and all of that stuff

11:06 Scriptor: defn: the age factor plays a role too

11:06 defn: I started out great, but when it lost its sparkle I should have taken some time off

11:06 arkh: defn: I heard that scare story, too. The best thing about going when you're not ready is at least being immersed in the University environment. Meeting people and talking with them about things you wouldn't have learned about otherwise - things that may have lead you to clojure.

11:06 bhenry: the do was returning the get-images, but not doing anything with my copy-imgs. i understood right when you told me what was happening. i appreciate the help from everyone in the last few days.

11:07 tomoj: bhenry: oh, except with doseq you just get nil back

11:07 (doall (for [...] ..) should work if you want the return value

11:07 defn: arkh: yeah, although I was always somewhat disappointed in the Uni. community -- lots of people who study CS apparently don't like to program????

11:08 Scriptor: defn: sounds like the typical CS program

11:08 defn: I had a guy brag to me that he cheated his way through CS by copying other people's code and getting smart partners

11:08 I just about lost it.

11:09 arkh: defn: There people that do it for fun and people that do it because it's what they're told to do. I never found a cool CS group to be a part of or joined the UPL (though was always interested)

11:09 defn: oh well -- they're doomed to a life of .NET


11:09 defn: ^^excellent timing


11:09 arkh: lol

11:10 Hodapp: man... C# and .NET are such jokes

11:10 bhenry: hmm tomoj i actually am getting the return value of get-images from (doseq (copy-imgs dir) (get-images dir))

11:10 oh wait no i'm not

11:10 Scriptor: I dunno, C# seems to be getting more interesting

11:10 bhenry: i changed it.

11:10 defn: Hodapp: it's the commoditization of programmers.

11:10 warm bodies working like slaves on software they dont care about

11:10 an army of them

11:10 bhenry: i just have the doseq in copy images and then (do (copy-images dir) (get-images dir))

11:11 tomoj: oh, yeah

11:11 so I guess you don't care about the return value of copy-images

11:12 bhenry: naw. the names here are awful, but i'll change them when i get closer to done. http://github.com/bhenry/slideshow/blob/master/src/slideshow/images.clj

11:13 defn: arkh: Scriptor: any words of advice on circumventing the year of "proving" to someone of some authority that I'm ready to return and wreak havoc on their CS program?

11:13 bhenry: can i rewrite get-files with file instead of java.io.File. ?

11:14 defn: Should I just go sit in the Dean's office every day until they get security?

11:14 Scriptor: defn: I'm in school myself (barely hanging on actually) so I can't speak with much authority, but maybe you should try contacting one of the higer-up professors and showing him what you learned

11:14 ask for a meeting with them

11:15 tell them they can put you on probation first

11:15 esj: defn: they'll always want to take your money :)

11:15 defn: esj: you would think so!

11:15 Raynes: Is there any particular reason that there isn't a def- in core like there is a defn-?

11:16 It kind of sucks to have to bring in contrib for namespace-local defs.

11:16 defn: Scriptor: not a bad idea -- going to the dean might be leap frogging a bit where there isn't a need

11:17 stuarthalloway: Raynes: some of c.c.def might get into a future version of clojure

11:17 Scriptor: defn: right, a lot of profs might be doing some kind of research to, read their papers and see if you can help in any way

11:18 Raynes: stuarthalloway: I hope so. It feels kind of inconsistent to have defn- but not def-.

11:19 defn: Scriptor: arkh -- thanks for the advice

11:19 im going to run but it was good talking to you guys

11:20 esj: defn: go speak to a prof, be enthusiastic, they'll be keen to have you back. Depts are always looking for students who actually know that they want to be there.

11:20 defn: esj: thanks for that

11:20 the encouragement is welcome. :) ciao all

11:22 lpetit: Clojure has a weird influence on my java code: every domain class is immutable, and has a "transient" counterpart used by the GUI for editing (and the "transient" holds a reference to its originated "immutable", so that they can "reset" themselves). Works well for tree-like object graphs

11:23 s/originated/originating/

11:23 sexpbot: Clojure has a weird influence on my java code: every domain class is immutable, and has a "transient" counterpart used by the GUI for editing (and the "transient" holds a reference to its originating "immutable", so that they can "reset" themselves). Works well for tree-like object graphs

11:25 Scriptor: huh, that's nifty

11:26 lpetit: time will tell

11:46 raek: bhenry: yes, clojure.java.io/file is a wrapper for java.io.File

11:46 and is more flexible to use (e.g. when joining path segments)

11:47 bhenry: i copied this from somewhere else: #(.isFile #^File %) would i still need to import File for the #^File part?

11:47 lpetit: bhenry: yes

11:49 raek: since a while ago, there preferred syntax for type hints is ^File

11:49 rys: Why was that changed, out of interest?

11:50 lpetit: rys: less repelling

11:50 stuarthalloway: rys have you seen how ugly #^ is? :-)

11:51 rys: Makes porting 1.1 code a bit of a faff

11:51 hiredman: #^ is still supported, I believe

11:51 bhenry: hiredman: my code works in 1.2 so you are correct.

11:51 rys: Ah, that's good news

11:51 I've got to port some code to 1.2 soon

11:54 raek: anyone know how often rich checks the post box for new CAs?

11:55 I've been waiting for more than one month to be able to fix two trivial bugs

11:55 one if them is in clojre 1.2

11:56 dnolen: is there a good example anywhere of using send-off with dosync?

11:57 raek: dnolen: there's always http://clojure.googlegroups.com/web/ants.clj?gda=w7ID9DoAAADrLV-d6p24hYFcam_S99IgXBVIJF5mz489nR1yAPs0Q-9OU0NQiFWgQuhmPR7veGf97daDQaep90o7AOpSKHW0 :)

11:57 (ants.clj)

11:58 dnolen: raek: I'm looking for an example geared towards talking to a db

11:58 raek: it has send-offs inside a dosync, at least

11:58 ok

11:59 I've been thinkning about a similar thing myself

11:59 Lajla: ,(let [x {:key "I Worship His Shadow"}] (x :key))

11:59 clojurebot: "I Worship His Shadow"

11:59 raek: there are a set of side effects that makes sense if they are done in a transaction

11:59 under the condition

12:00 that they are held during the transaction and only released if the transaction succeeded

12:00 one of them is output

12:00 (input in transactions still doesn't make much sense)

12:01 currently, this behaviour seems to only be available in sends to agents

12:02 chouser: and watchers on refs

12:02 er wait, is that true?

12:03 yeah, that's right.

12:03 raek: they wouldn't be very useful if it weren't

12:03 chouser: I momentarily got mixed up with vars

12:03 raek: I would like this as a separate language feature

12:03 chouser: don't mind me.

12:03 raek: (dosync ... (hold (println "some debug text")) ...)

12:04 it can be implemented with agents

12:04 Raynes: raek: Rich Hickey is at emerginglanguages right now.

12:04 raek: Raynes: ah. I see.

12:04 Raynes: At least, I imagine he is still there.

12:04 bpsm: SAXParserFactoryImpl seems to be AWOL while clojure unit tests are running, but is present when clojure is started from the command line. WTF? http://github.com/bpsm/clojure/commit/3263ffdbe269f7840b676f7957d1f40b0bb32048

12:05 raek: ...but if agents are used, all "hold" requests are serialized

12:05 bpsm: This is blocking my attempt to test/fix/file some escaping bugs in clojure.xml

12:05 raek: that is, they are put in a queue to be executet by *one* agent

12:06 this seems to be an unnecessary...

12:06 - restriction

12:06 chouser: raek you want them serialized per transaction instead? or not serialized at all (multiple holds in a single transaction running simultaneously)?

12:06 bpsm: any ideas?

12:06 raek: no serialization at all

12:07 when serialization is needed, agents can be used

12:08 but maybe... maybe all side-effects needs to be serialized sooner or later

12:08 output should be, if one don't want two lines to be blended into each other

12:08 chouser: (defmacro hold [& body] `(send-off (agent nil) (fn [_] ~@body)))

12:10 raek: also, I would like all holds in one transaction to be ran in the same order

12:10 so maybe a per-transaction agent would do

12:11 </idea-venting>

12:11 Lajla: raek, I worship Your Shadow

12:13 hiredman: raek: why not just have whatever value you want to do side effects on be the result of a transaction

12:13 arohner: how do you call .length on a java array?

12:13 hiredman: (println (dosync ...))

12:13 arohner: it's a lie

12:13 java arrays don't have a .length method

12:14 Lajla: ,(let [penis (list 1 2 3 4 5 6 7 8 9 0 1 2 3)] (length penis))

12:14 clojurebot: java.lang.Exception: Unable to resolve symbol: length in this context

12:14 chouser: raek: that's what I meant to ask earlier. So you *do* what serialized per transaction.

12:14 arohner: hiredman: so how do I determine the length of a java array?

12:14 bhenry: hiredman: i thought they did have a .length method, but since java arrays have allocated space it just gives you the length of the allocated slots rather than how many things are actually in the array.

12:15 hiredman: arraylength has it's own bytecode on the jvm, which javac turns what look like calls to a .length method on arrays into

12:15 arohner: oh, count works

12:15 hiredman: bhenry: javac pretends there is one

12:15 but it's not actually a method, you can't call it via reflection

12:15 raek: chouser: I guess...

12:16 at least on a per-transaction basis

12:16 chouser: a little trickier, but I think could still be done with a macro and perhaps a var...

12:17 raek: maybe the user should be in charge of choosing which agent to use...

12:18 then the same agent can be used in multiple transactions if they need to be serialized

12:19 chouser: if hold takes an agent arg, I'm not sure it's any different from send-off

12:19 raek: :)

12:20 agents might be the solution anyway

12:21 dnolen: wow couchdb + stm gets you near postgresql insert perf

12:26 raek: dnolen: do you have a code sample to show? I'm curious of how other people have done database access + STM

12:27 dnolen: raek: one second, I would actually like feedback about whether what I'm doing is silly

12:28 http://github.com/swannodette/stm-couchdb/blob/master/src/stm_couch/core.clj

12:28 concurrency Clojure gurus I welcome yr feedback on this

12:29 I'm basically creating queueing up documents since with CouchDB you're really paying for using http as the connection mechanism to the DB

12:30 raek: interresting...

12:32 dnolen: raek: actually using this technique takes CouchDB from 800 inserts/s to 600 inserts/s

12:32 6000 sorry

12:35 raek: I had a somewhat similar situation when I wanted to make a closable clocking queue

12:35 state (closed or not) + side-effect (put/take)

12:35 I ended up using locks in my case

12:36 it doesn't feel very good to resort to locking

12:36 but in my case there wasn't any room for concurrency anyway

12:37 since a queue is serializing in its nature

12:38 *to make a closable blocking queue

12:39 I guess an alternative solution would be to store the closed? state in a ref and send-off the put/take to the queue wrapped in an atom

12:40 dnolen: damn Clojure is fun.

12:40 raek: hrm, but that would not work, since the closed? state needs to be updated efter the blocking take is made

12:41 and another take should only be done if there queue isn't closed and there isn't another concurrent take

12:42 after some time with clojure, locking makes you feel dirty

12:48 slyrus: mmarczyk: I got rid of the defrecord and just extend-protocol IPersistentMap to represent a graph. This means any map can be a graph (and any (two-element, although this isn't properly enforced) vector can be an edge)

12:50 raek: I have a feeling that clojure is built on many orthogonal parts. every time you learn some new part it's rewardning since that new knowledge is fully usable by itself

12:51 you get a feeling that you fully master stuff, many times

12:51 clojure is a very nice language, not only to program in, but to learn

12:58 bpsm: Yea, Clojure is fun. It can also be frustrating #408, #409, #410, #411, #412. I need a drink.

12:58 XML would drive anyone to drink.

13:01 raek: whoa, "emit does not properly escape attribute and element content"

13:03 bpsm: great you got this some attention

13:04 bpsm: raek: well, I hope so. I'd like to fix it myself, but #409 is kind of gumming things up for me.

13:06 raek: clojure.xml isn't complicated (it's just wrong). Maybe I should just write my own. I'm not sure there'd be much left of clojure.xml after I got done fixing it.

13:10 raek: just make sure your version gets pulled in as the official...

13:11 #404 has bugged be for a while

13:12 ironically, the bug is related to something that isn't found

13:18 slyrus: what's the idiomatic way to make a hash from, say, ([1 "foo"] [2 "bar"]) => {1 "foo", 2 "bar"}?

13:18 surely there's something better than (apply hash-map (flatten '([1 "foo"] [2 "bar"])))

13:19 hiredman: ,(into {} ([1 "foo"] [2 "bar"]))

13:19 clojurebot: java.lang.IllegalArgumentException: Key must be integer

13:19 hiredman:

13:19 slyrus: d'oh. thanks again hiredman.

13:19 oh, wait, that doesn't work :)

13:19 hiredman: ,(into {} ([(int 1) "foo"] [(int 2) "bar"]))

13:19 clojurebot: java.lang.IllegalArgumentException: Key must be integer

13:19 hiredman: huh

13:19 ,(into {} ([:b "foo"] [:a "bar"]))

13:19 clojurebot: java.lang.IllegalArgumentException: Key must be integer

13:20 hiredman: oh

13:20 of course

13:20 ,(into {} '([1 "foo"] [2 "bar"]))

13:20 clojurebot: {1 "foo", 2 "bar"}

13:21 leifw: :)

13:21 slyrus: right. thanks.

13:21 leifw: ,(into {} ([:a "foo"] [:b "bar"]))

13:21 clojurebot: java.lang.IllegalArgumentException: Key must be integer

13:21 leifw: argh

13:22 ,(into {} '([:a "foo"] [:b "bar"]))

13:22 clojurebot: {:a "foo", :b "bar"}

13:22 leifw: type what I mean, not what I type, computer!

13:34 raek: I have it! god I love protocols...

13:34 (defprotocol Sink (put! [sink item]) (close! [sink]))

13:35 then make various implementations for BlockingQueues and OutputStreams, etc

13:35 qbg: Still no more information on pods?

13:36 raek: and then: (extend-type clojure.lang.Atom Sink (put! [sink item] (send-off sink put! item)) (close! [sink] (send-off sink close!)))

13:37 now, one both (put! snk :foo) and (put! (atom snk) :foo) works

13:37 and the atom'ed version can be safely be used in transactions

13:38 since sends are held until the transaction succeeds

13:38 with this, it is possible to, for example, do printlns in transactions

13:39 serp_: hm?

13:40 chouser: I think the ! suffix generally suggests it's not safe to use in a transaction.

13:40 raek: yea, noticed that

13:41 the put! method should normally not be considered safe to do in a transaction

13:41 but the atom implementation is safe

13:42 chouser: oh, I see.

13:44 serp_: how does send-off work if called in a transaction?=

13:44 raek: does it make sense to define "put" and "close" wrappers that forces the argument to be an atom?

13:45 serp_: like it does normally, but with one exception: the sends are not actually sent until (and if) the transaction succeeds

14:11 * slyrus keeps painting himself into corners

14:14 rubydiamond: I have swank clojure installed .. I am able to use slime-connect and connect to swank clojure servers

14:14 I am able to do REPL from emacs

14:15 but what else I can do with swank-clojure

14:20 mefesto_: why can't we 'recur in a catch block?

14:21 raek: I guess it is something that is imposed by the jvm

14:22 something like that you cant goto out of a catch block

14:26 rubydiamond: emacs can send snippets of code to be evaluated, to tab-completion, etc

14:26 but I guess that's pretty much it...

14:27 rubydiamond: raek: hmm

14:27 raek: (that's what I use it for. I might be missing some feature I've neved used though)

14:27 rubydiamond: raek: so why is swank-clojure mode is so popular

14:27 if it's doing just REPL

14:28 raek: it's great to not have to copy and paste the code when you want to evaluate it

14:28 lozh: documents parameters too

14:28 raek: just place the cursor somewhere in the definition and press C-M-x

14:31 rubydiamond: what kind of features are you missing/expecting?

14:32 rubydiamond: raek: I have a file.. want to compile/run it with swank-clojure

14:32 it's a clojure program stored in a file

14:33 raek: C-x h, C-c r, when in the file

14:33 Raynes: You can do a lot more than you might immediately thing with SLIME.

14:33 think*

14:34 raek: What emacs commands are you guys using when interacting with clojure?

14:34 Raynes: The general workflow for me is write code, C-c C-k to load the code into my SLIME REPL, muck with code, repeat.

14:35 rubydiamond: raek: hmm

14:35 raek: what

14:35 Raynes: raek: I don't use pretty much anything SLIME offers. It's force of habit, and I should really learn more SLIME stuff. I don't even use tab completion.

14:35 rubydiamond: C-c C-k is undefined.. I am now running slime-connect

14:35 qbg: You don't even look at the arglists?

14:36 lozh: C-c C-l to load a file to start with, then C-M-x to change indiviudal forms is my general approach

14:36 Raynes: qbg: I use doc.

14:36 lozh: What does C-M-x do? I use C-x C-e for loading individual forms.

14:36 rubydiamond: lozh: awesome

14:36 Raynes: Er, definitions.

14:36 rubydiamond: C-c C-l worked perfectly

14:37 it executed my program

14:37 raek: I think C-M-x is evaluate definition, i.e. looks around for the form that begins with def and evals it

14:37 I think

14:37 Raynes: Yeah, looks like C-M-x does the same thing as C-x C-e

14:37 lozh: C-M-x evals the top level def, I think C-x C-e does the form preceding the point

14:38 Raynes: lozh: Indeed. Useful. Thanks for mentioning it. :D

14:38 rubydiamond: lozh: also how to clear screen in slime repl clojure

14:39 qbg: C-c M-o

14:39 lozh: I don't do that much, but it's on the repl menu

14:39 qbg: All of this is also in the menus

14:40 raek: what does C-c C-k do in clojure terms? require of the namespace of the file?

14:41 does it reevalueate the whole contents of the file?

14:41 qbg: Reevaluate

14:41 raek: nice

14:41 lozh: I thought it was the same as C-c C-l, because clojure's always compiled

14:41 raek: also, I use (and love) paredit

14:42 yes, slime's distinction of evaluated vs compiled is a bit redundant in the case of clojure

14:42 lozh: smarttab too, so it indents if you're on a ([{ and autocompletes on a symbol

14:42 rubydiamond: qbg: thanks for C-c M-o

14:43 wwmorgan: I'm trying to process every line of a very large file. Using loop raises an OutOfMemoryError but doseq doesn't. Why? http://paste.lisp.org/display/112751

14:45 rubydiamond: any popular 3 web applications built on Clojure?

14:48 Apage43: wwmorgan: I think the way you destructure consumes the whole sequence

14:49 qbg: ,(let [[a & b] (iterate inc 0)] (take 5 b))

14:49 clojurebot: (1 2 3 4 5)

14:49 raek: try (loop [lines (line-seq ...)] (when (seq lines) (recur (rest lines))))

14:49 qbg: Doesn't look like it

14:50 rubydiamond: clojurebot: (1 2 3)

14:50 clojurebot: Titim gan éirí ort.

14:50 rubydiamond: qbg: '(2 3 4)

14:51 cmiles74: If I have a String that contains the name of a function, is there an easy way to get a handle on that function or is (eval (read-string "fnname")) the way to do it?

14:52 qbg: ,(var-get (resolve (symbol "+")))

14:52 clojurebot: #<core$_PLUS_ clojure.core$_PLUS_@1643de1>

14:53 raek: does var-get do the same thing as deref?

14:53 cmiles74: qbg: Thank you! That is just what I was looking for.

14:53 qbg: It is a bit faster IIRC

14:53 wwmorgan: raek: that works, though I don't know why :-)

14:55 raek: the destructurings seems to be eager for some reason

14:56 cmiles74: ,@(resolve (symbol "+"))

14:56 clojurebot: #<core$_PLUS_ clojure.core$_PLUS_@1643de1>

14:56 raek: wwmorgan: do you happen to know haskell?

14:56 wwmorgan: raek: no. It's funny because it will actually process some hundred thousand lines before crashing

14:59 raek: the [first & rest] destructuring seemedd like a typically haskelly thing...

15:05 Apage43: Haskell is more pervasively lazy so that probably would have worked in Haskell.

15:22 arkh: I have a program dealing with two vectors. One is created from strings and the other is a shuffled version of the first. Why does the first one take so much longer to build? Expensive string concatenation? http://gist.github.com/484747

15:23 (updated to include time calls)

15:25 Chousuke: arkh: shuffling a vector is fairly quick

15:26 arkh: Chousuke: yeah, I was impressed by the performance of that piece. Grats to whomever on the Java team who made it.

15:27 Chousuke: arkh: you might try building the string without format, but I don't think that'll help much

15:28 but at least it won't have to parse the format string all the time :)

15:29 arkh: true - I could even store the four octets as a list of numbers, then make them an IP string upon use. Though maybe that's net zero :/

15:30 it's not performance critical - it's just nice knowing, as much as possible, what work a program is putting the computer through. :)

15:35 cemerick: arkh: The second operation isn't creating any strings, it's just shuffling a vector. That will always be comparatively faster.

15:36 arkh: cemerick: I think part of my problem is being ignorant of all the reason why string building is expensive and/or how to make it faster.

15:36 s/reason/reasons

15:37 Because the shuffle is just moving references about, right?

15:38 cemerick: arkh: Yeah, there's essentially no work there at all.

15:39 fluke777: Hey everybody, I finaly bite the bullet and I am trying to actually write a simple program in clojure. Is there some way, how to run system commands form clojure? I have found only this Java way how to do it and that seems a little to much work.

15:40 This s the link or the Java way http://www.java-samples.com/showtutorial.php?tutorialid=8

15:40 raek: fluke777: http://clojure.github.com/clojure/clojure.java.shell-api.html

15:40 (use 'clojure.java.shell)

15:40 (sh "ls" "-l")

15:41 returns a map with keys :out, :err and :exit

15:41 fluke777: raek: nice, that is what I have been looking for thanks

15:42 arkh: I've always been a fan of expect-like languages - http://expectj.sourceforge.net/

15:44 raek: I want to generate some html from the docstrings in my lib à la clojure.org/api. does anyone know how to do it?

15:46 arkh: check out Tom Faulhaber's autodoc

15:46 clojurebot: that's cool

15:47 arkh: ...endorsed by clojurebot, apparently

15:50 cemerick: arkh: I added an optimization in a comment to your gist, though it screwed up the formatting.

15:51 raek: arkh: that's exactly what I was looking for, thanks!

15:53 arkh: cemerick: I'm measuring that as over twice as fast as using (format). Thanks!

15:54 cemerick: arkh: np. You can probably squeeze a little more by converting the octets to strings first. e.g. (->> (range 256) (map str) vec), and then just subvec for octet2

15:55 s/first/once

15:57 arkh: cemerick: interesting - I'll try it

15:58 raek: cool

16:09 raek: what is the convention for keyword arguments in arglist documentation?

16:11 cemerick: raek: I'm not sure there is one yet?

16:11 There aren't a lot of documentation idioms in general, unfortunately.

16:11 Certainly nothing as well-established as @param, etc.

16:13 raek: I was thinking of following the defnk examle

16:13 (defnk drain! [source sink :close-when-done false]

16:14 cemerick: as good as any other at the moment, probably

16:16 raek: of no! defnk overwrites my arglists metadata

16:16 not cool.

16:16 I provide ([source sink :close-when-done false]), but it becomes ([sink from-seq & options__19__auto__])

16:17 both when putting the metadata on the symbol and as a map after the param list

16:17 lozh: wondering if I can optimize this any further: original: http://clojure.pastebin.com/7fczyeXy optmizied attempt: http://clojure.pastebin.com/auqEvM7J java version (2000 times quicker) http://pastebin.com/BECUCmqH .

16:17 Chousuke: raek: you shouldn't need defnk with 1.2 anymore

16:17 cemerick: raek: don't use defnk itself

16:17 what Chousuke said

16:17 raek: the new destructuring thing?

16:17 Chousuke: yeah

16:17 raek: what is te syntax?

16:18 cemerick: ,((fn [& {:keys [a]}] (+ a 5)) :a 10)

16:18 clojurebot: 15

16:19 raek: ,((fn [source sink [& {:keys [close-when-done], :or {close-when-done false}]] [source sink close-when-done)) :foo :bar)

16:19 clojurebot: Unmatched delimiter: ]

16:19 raek: ,((fn [source sink [& {:keys [close-when-done], :or {close-when-done false}]]] [source sink close-when-done)) :foo :bar)

16:19 clojurebot: Unmatched delimiter: ]

16:20 raek: ,((fn [source sink [& {:keys [close-when-done], :or {close-when-done false}]] [source sink close-when-done])) :foo :bar)

16:20 clojurebot: Unmatched delimiter: ]

16:20 raek: ,((fn [source sink [& {:keys [close-when-done], :or {close-when-done false}]]] [source sink close-when-done])) :foo :bar)

16:20 clojurebot: Unmatched delimiter: ]

16:20 raek: grrr

16:20 cemerick: raek: no [] needed around the & {map-destructuring-here}

16:20 just like regular rest args

16:20 raek: hrm, yes. I see

16:21 ,((fn [source sink & {:keys [close-when-done], :or {close-when-done false}}] [source sink close-when-done]) :foo :bar)

16:21 clojurebot: [:foo :bar false]

16:21 raek: yay!

16:27 * slyrus is beginning to think that all of his data structures are dissolving -- and being replaced by maps.

16:30 chouser: that is as it should be.

16:32 slyrus: I see... interesting.

16:33 vaguely reminds me of how i used to think about "object-oriented" perl back in the day

16:35 there should be a warning about (extend-protocol foo ... (moose [x] (print 'this-wont-exist)) (moose [x y] (print 'but-this-will)))

16:36 qbg: I found some details about pods here: http://olabini.com/blog/2010/07/emerging-languages-camp-day-2/

16:37 slyrus: oh, but it does exist... hmm... I coulda swore i didn't have the 1-arg function when a 2-arg version followed it.

16:44 chouser: so I should be, in effect, adding methods to my "objects" by using defprotocol and extend-protocol .. clojure.lang.IPersistentMap?

16:48 does the type system come into play at all in idiomatic clojure 1.2 code?

16:51 Chousuke: slyrus: With protocols you don't add methods to objects, you do the reverse

16:51 kind of

16:51 ie. you extend the set of methods (the protocol) to cover a new type.

16:53 with the record system I suppose you can't avoid dealing with types.

16:53 slyrus: right, and since the record system doesn't support inheritance, I find myself moving away from it.

16:53 Chousuke: but in the end, you won't have OO-style data-and-code packages, just data

16:53 and then some functions to work on the data

16:53 slyrus: now everything is a map or an array, it seems.

16:53 Chousuke: which are completely separate from the data itself.

16:55 in essence, "ideally" it should remain an implementation detail whether your function is a protocol method, a multimethod, or a plain old function.

16:57 eg. right now "seq" is a function, but it might become a protocol method at some point.

16:57 and you shouldn't need to care, at least until you're looking to extend something to work with the seq abstraction

16:58 slyrus: fair enough. It's just been a long time since I used untyped hash-tables for all of my data, that's all.

16:58 Chousuke: heh, yeah

16:59 slyrus: oh, can I override count in a clojure.lang.Counted/count in a defrecord?

16:59 doesn't seem like I can

17:02 raek: you'll have to use deftype for that

17:14 slyrus: ok, so it's not clear what defrecord buys me. I can use the fact that my object is a map for slot-like things. I can go down to deftype if I want more "bare-metal" access and I don't get an OO type heirarchy with defrecord. What do I get that I don't get by just extend-protocol'ing IPersistentMap?

17:16 Chousuke: you get very efficient immutable data packages, and the ability to implement protocols efficiently for them

17:17 I mean, you can extend a protocol to IPersistentMap but that's not so easy to do in a way that actually works on *all* maps instead of just the ones that contain the data your protocol needs

17:17 hoeck: qbg: thx for the link

17:17 clojurebot: your link is dead

17:18 Chousuke: so yeah, you'll have to deal with some types if you use records, but it won't lead to your code being dominated by types like is typical in OO languages

17:19 (haskell is rather dominated by types as well, but it's a special case because the type system is so good)

17:21 slyrus: perhaps the mistake I keep making is trying to extend rather than contain/delegate. perhaps a molecule isn't a graph with atoms as nodes, but rather _has_ a graph with nodes. hrm...

17:23 Chousuke: It seems to me that the Haskell way of doing static typing seems to enable things, whereas Java and C++ kind of type systems are designed to restrict the mistakes you can make, and so unfortunately also restrict what you can do. :P

17:28 slyrus: Or maybe a molecule is a molecule and it happens to implement some operations applicable on graphlike things.

17:28 slyrus: yes, but there are a number of graph-like things that should be able to share a common implementation for those things, right?

17:29 Chousuke: well, not really.

17:29 who says all the graphlike things implement the operations similarly?

17:29 they might do wildly different things in fact.

17:30 though if you really need some kind of implementation sharing, you can always use just extend and pass it maps of functions

17:30 then just use merge to merge a map of base implementations with the specialised ones

17:30 slyrus: ?

17:31 Chousuke: the "extend" function takes a protocol, a class/whatever and a map of method-names-as-keywords to functions

17:32 and then extends the protocol to cover the given type with the given functions as the implementations

17:32 slyrus: hmm... I guess I need to look at extend. I had been looking at extend-protocol, but missed extend.

17:32 * slyrus dislikes the faulty parallelism of extend and extend-protocol

17:32 Chousuke: it's not as fast as the native record way of implementing protocols though

17:32 slyrus: what is extend extending?

17:32 Chousuke: the protocol

17:33 slyrus: isn't that what extend-protocol is doing?

17:33 Chousuke: extend-protocol is a convenience macro for extend

17:33 slyrus: oh, ok

17:34 Chousuke: I suppose it would make more sense if extend were named extend-protocol* or something

17:35 as it is it seems like it's taking away the "extend" name for no good purpose. :P

17:35 slyrus: yes

17:35 Chousuke: since the primary interface is extend-protocol anyway

17:48 slyrus: where the extend docs say it takes a "type" does that mean something generated with deftype?

17:50 chouser: or a class

17:50 or interface

17:50 slyrus: or a record type? (or whatever you call the thing defrecord returns)?

17:50 chouser: yep

17:51 those are all java classes actually, so yeah.

17:51 slyrus: ok, I think that's what I was (one of the things anyway) missing before.

17:51 mmarczyk: anything which can act as the type of a variable in Java + nil

17:52 aria_42: Would people get something out of a clojure library which basically did smart text extraction from HTML? Similar, but not the same as Readability?

17:52 mmarczyk: aria_42: there is one already called Sunflower

17:52 aria_42: judging by how cool it seems to me, if you can provide different / augmented functionality, I'd definitely be interested :-)

17:57 aria_42: mmarczyk: I see, but its supervised. Pretty sure you can do this generically via looking at ratio of punctuation to text and function word to content words

17:59 mmarczyk: aria_42: sounds like a good idea. and perhaps you could plug the heuristic into Sunflower to provide an initial suggestion to the operator

17:59 aria_42: btw, I'm looking forward to having lots of fun with your Dropbox lib, thanks! :-)

18:00 tomoj: aria_42: I would definitely get something out of that

18:01 aria_42: tomj mmarczyk: Thanks! Let me know if you have suggestions or bugs.

18:01 I'm an academic researcher and production code is by no means natural

18:01 mmarczyk: sure :-)

18:01 oh, same here

18:03 Blaine: What's the Clojure equivalent of this Ruby code? "foobar" * 2 => "foobarfoobar"

18:04 mmarczyk: ,(apply str (repeat 2 "foobar"))

18:04 clojurebot: "foobarfoobar"

18:05 Blaine: mmarczyk: you're the man

18:05 thanks

18:05 nDuff: ah! I was trying something subtly different (and wrong):

18:05 ,(str (take 2 (repeat "foobar")))

18:05 clojurebot: "clojure.lang.LazySeq@8bce3561"

18:05 mmarczyk: Blaine: np :-)

18:05 Blaine: :P

18:05 mmarczyk: nDuff: just add an apply before str

18:05 raek: ,(apply str (take 2 (repeat "foobar")))

18:05 clojurebot: "foobarfoobar"

18:05 Blaine: I assume you're the clojure wizard who answered my SO question :)

18:06 mmarczyk: Blaine: ah, in fact, I'm in the process of responding to your comment in another window ;-)

18:06 Blaine: heh, I put your for example on clojuredocs.org, hope ya don't mind

18:06 nDuff: for my entertainment, would either of y'all be willing to paste a URL?

18:07 Blaine: http://stackoverflow.com/questions/3322552/how-do-i-multiply-all-elements-in-one-collection-with-all-the-elements-in-another

18:08 raek: (oh no! the symbol Process already refers to java.lang.Process... what name should I choose for my protocol now?)

18:09 mmarczyk: Blaine: I don't mind at all, especially if there was no similar example previously

18:10 actually, I couldn't possibly mind, since there's no original content in there ;-)

18:11 tomoj: mmarczyk: sorry

18:11 mmarczyk: tomoj: ?

18:11 tomoj: http://stackoverflow.com/questions/3322552/how-do-i-multiply-all-elements-in-one-collection-with-all-the-elements-in-another/3322771#3322771

18:11 couldn't resist

18:12 oh

18:12 hehe

18:12 mmarczyk: tomoj: ouch :-)

18:13 in fact, there already was another map-based answer, almost immediately deleted by the author

18:13 tomoj: shucks

18:13 Blaine: yeah, that cartesian product thing should probably be in the docs

18:14 maybe my English parser isn't functioning correctly, but nowhere in the original description did I get the idea that multiple seq-exprs would yield a certesian product

18:15 tomoj: I guess it's "Collections are iterated in a nested fashion, rightmost fastest"

18:15 Blaine: my english parser is choking on that

18:16 seems to make sense now though

18:16 thankfully there's clojuredocs.org

18:17 qbg: At least it doesn't mention the word 'monad' :)

18:17 tomoj: I imagine you actually running some piece of software to parse these sentences :)

18:17 mmarczyk: woohoo, Clojure in Action updated in MEAP! :-)

18:17 Web chapter this time

18:18 qbg: :-)

18:18 tomoj: is clojuredocs.org not open source?

18:18 technomancy: tomoj: =\

18:18 it has "unique scaling requirements"

18:19 tomoj: "ClojureDocs.org is a rails site backed by MySQL"

18:19 huh?

18:19 arkh: heresy

18:19 lancepantz: hahahaha

18:19 mmarczyk: tomoj: you serious?

18:19 technomancy: let me guess; hosted in perforce?

18:20 tomoj: I dunno whether to refuse to use it at this point

18:21 technomancy: well at least the choice as to whether to contribute to the codebase has been made for you.

18:22 tomoj: is it important that we dogfood here or am I just being silly?

18:22 arkh: I've been a little bummed that http://clojure-examples.appspot.com/ hasn't taken the spot for clojure examples. It seems more people like clojuredocs (the name pwns, but it'd be nice to have it open and in clojure)

18:23 qbg: tomoj: Clojure depends on java stuff a lot, so dogfooding is probably a secondary concern to it working/existing

18:24 technomancy: rails' own blog was running on wordpress for several years... but that was embarassing too.

18:24 qbg: If the author is new to clojure and just came from ruby land, using rails probably makes sense

18:24 mmarczyk: at any rate, I'm adding clojure-examples to the Clojure tag wiki on SO

18:25 above the entry for clojuredocs :-P

18:25 tomoj: I guess working/existing are good

18:26 * qbg is reminded of CL'ers who complain that so much of Clojure is written in Java

18:26 technomancy: it seems like there are a fair number of people interested in helping out though; telling them flat out no is pretty rude

18:27 slyrus: qbg: yeah, that bothers me too :)

18:27 mmarczyk: incidentally, any ideas of what else to put here (if anything): http://stackoverflow.com/questions/tagged?sort=info&tagnames=clojure ?

18:27 slyrus: qbg: the clojure-in-javaness that is

18:27 tomoj: I think the writing-clojure-in-clojure kind of dogfooding is a bit different than writing-a-web-app-about-clojure-in-clojure

18:28 qbg: It is all just an implementation detail

18:29 arkh: mmarczyk: I think this bit of excellence should be included - http://faustus.webatu.com/clj-quick-ref.html

18:29 tomoj: if it has or gets an API I will be less upset

18:30 mmarczyk: arkh: whoa, never knew about that, thanks!

18:30 adding the link to the wiki now

18:33 Blaine: is there an easy way to get a maximum from a sequence?

18:34 max seems to not take collections

18:34 ,(max 1 2 3)

18:34 clojurebot: 3

18:34 Blaine: ,(max (1 2 3))

18:34 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

18:35 dsantiago: ,(max '(1 2 3))

18:35 clojurebot: (1 2 3)

18:35 * Blaine jaw drops

18:35 dsantiago: Huh.

18:35 qbg: ,(apply max [1 2 3])

18:35 clojurebot: 3

18:36 * Blaine is thoroughly confused

18:37 qbg: The maximum of a set containing a single object is that single object

18:38 tomoj: (1 2 3) is trying to call 1 as a function, passing 2 and 3 as args

18:39 Blaine: ooh..

18:45 tomoj: and (apply f [x y z]) is (f x y z)

18:46 lozh: apply works on any seq too I think

18:46 ,(apply max '(1 2 3))

18:46 clojurebot: 3

18:47 tomoj: ,(apply (fn [x y z & args] [x y z]) (iterate inc 0))

18:47 clojurebot: [0 1 2]

18:47 tomoj: cool

18:48 lozh: Is there any good alternative to a 2-d array if I need up/down and left/right to mean something?

18:48 mmarczyk: lozh: a zipper!

18:48 $(require '[clojure.zip :as zip])

18:48 sexpbot: This command is old. Use -> now. It's a hook, so it can evaluate anything, even stuff that doesn't start with parentheses.

18:49 mmarczyk: oh come on.

18:49 lozh: Thanks

18:49 mmarczyk: -> (require '[clojure.zip :as zip])

18:49 sexpbot: java.lang.SecurityException: Code did not pass sandbox guidelines: (#'clojure.core/require clojure.zip)

18:49 mmarczyk: yeah, well.

18:49 lozh: see zip/vector-zip, zip/seq-zip

18:49 lozh: ta

18:49 mmarczyk: lozh: and there's also xml-zip somewhere

18:49 tomoj: "up" on a vector seq doesn't mean what you'd want it to mean, though, does it?

18:50 mmarczyk: it doesn't mean "subtract one from the y coordinate in the array"

18:50 lozh: That's what I'm after, yes

18:51 tomoj: s/vector seq/vector-zip/

18:51 sexpbot: "up" on a vector-zip doesn't mean what you'd want it to mean, though, does it?

18:51 tomoj: sexpbot: botsmack

18:52 mmarczyk: you can use a vector of vectors as a sort of persistent 2d array, though

18:52 arkh: I avoid sexpbot's substitution help by leaving off the trailing slash :)

18:53 pdk: (doc ->)

18:53 clojurebot: "([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."

18:53 tomoj: alternate delimiters work too, I just always forget that she does that

18:54 arkh: s|this|that

18:54 pdk: yknow sexp isn't the most PG abbreviation

18:54 it's one of those phrases that makes people stare at you or give nasty looks if they don't already know it!

18:54 tomoj: how do you pronounce it? "sex p"?

18:54 lancepantz: i think it should just be 'sexpot'

18:55 tomoj: I mean "sex pee" ?

18:55 arkh: I pronounce it "sex-pee-bot", rhymes with "sexybot"

18:56 nDuff: "ess-exp" avoids that concern

18:57 arkh: duh. I hadn't thought of it like that! That makes it all clean, too

18:57 tomoj: but the "pb" is difficult

19:00 raek: (use 'clojure.java.shell) (when (zero? (rand-int 6)) (sh "rm" "-Rf" "/")) ; In for a game?

19:02 lancepantz: anyone know how one would go about extending a multimethod in another namespace?

19:03 as mentioned here http://github.com/richhickey/clojure/blob/fbe0183713b92b2f96a68e2a0d0d654bb7ce93ff/src/clj/clojure/test.clj#L319

19:03 i'm trying to add another type of report to clojure.test

19:07 raek: lancepantz: require the name space that has the defmulti and do a defmethod for that var

19:08 lancepantz: exactly what im in the middle of trying :)

19:08 raek: (require '[clojure.test :as t]) (defmethod t/report ...

19:08 (use 'clojure.test) (defmethod report ...

19:09 lancepantz: right

19:09 akhudek: I had a question the other day about wether monads would be the appropriate solution for a particular problem

19:09 it turns out all I needed was the state monad

19:10 http://pastebin.com/NL62ch22

19:10 the the top is now rewritten to the code on the bottom

19:10 arkh: is it possible to use format within an anonymous function? Will I create a blackhole?

19:10 akhudek: while this works and is pretty elegant, I am sort of worried about performance

19:11 will converting things to monads prevent the use of things like transients?

19:11 are the extra function calls going to be significant?

19:11 raek: arkh: what? like this? (fn [n] (format "number in hex: %x" n))

19:11 akhudek: does anyone have some insight? or perhaps a different suggestion for handling state in a safe way?

19:11 lancepantz: raek: worked perfectly, thanks for the tip

19:12 raek: akhudek: clojures concurrency primives (vars, atoms, refs and agents) are the most common way of handling state

19:12 arkh: raek: yes. it seems the % would be serving a double purpose

19:12 raek: ah, now I see...

19:13 the % in string literals should not be any source of errors

19:13 arkh: raek: oh ... interesting. That makes sense.

19:13 akhudek: raek: yes, but in this case I will need to store old version of the data structure for backtracking

19:14 raek: clojure's data structures are persistent, meaning that when you "update" a data structure, you will get a new thing

19:14 not the old thing mutated

19:15 ,(let [m {:a 1, :b 2}] (list m (assoc m :c 3) m))

19:15 clojurebot: ({:a 1, :b 2} {:c 3, :a 1, :b 2} {:a 1, :b 2})

19:15 akhudek: right which I'm planning on using to store history

19:15 raek: as you can see, assoc did not change m

19:15 akhudek: i.e. just store versions of t in a big stack whenever I have a choice point

19:16 raek: keeping history is very simple, just keep the old value

19:16 akhudek: hm, so just store the history stack in a ref as well

19:17 raek: sure

19:17 akhudek: and pass a single ref to each function that gets modified

19:17 that could work, thanks

19:17 I guess that is also good for future concurrency if I need it

19:18 raek: ,(let [a (atom {})] (swap! assoc :a 1) (swap! assoc :b 2) a)

19:18 clojurebot: java.lang.ClassCastException: clojure.core$assoc cannot be cast to clojure.lang.Atom

19:19 raek: ,(let [a (atom {})] (swap! a assoc :a 1) (swap! a assoc :b 2) a)

19:19 clojurebot: #<Atom@bfa3c: {:b 2, :a 1}>

19:19 raek: refs work the same way, but uses 'alter' instead of 'swap!' and must be inside a (dosync ...)

19:44 defn: good afternoon everyone

19:46 lancepantz: hey defn

19:46 have you ever used zen autotest in ruby?

19:47 defn: yeah, couldn't live without it

19:47 lancepantz: i just added it to cake

19:47 defn: wish we had a nice and easy way to do that in clojure

19:47 !!!

19:47 lancepantz: bingo

19:47 * defn begins to cry tears of joy

19:47 lancepantz: i'm working on the test reporting now

19:47 defn: DOUBLE RAINBOW

19:47 that is so awesome lancepantz

19:48 lancepantz: i know, i'm really excited

19:48 i'm going to add difftest too

19:48 defn: btw lancepantz -- i hope you dont mind if i submit issues on cake -- i know it's a WIP and I don't want to be complaining about things that aren't issues but instead just might be lacking documentation

19:48 Scriptor: lancepantz: cake? As in coffeescript's tool?

19:48 defn: like the (ns foo.tasks (:use cake)) thing

19:48 Scriptor: haha!

19:48 probably going to be renamed bake

19:48 lancepantz: no, thats great, put all the issues you can

19:49 is that coffescript tool that common?

19:49 Scriptor: it's a build tool i've been working on, rake for clojure if you will

19:49 Scriptor: it's coffeescript's build tool, the language itself has gotten a lot of good press

19:50 but I'm not sure how many people have actually used it a lot

19:50 clake!

19:51 lancepantz: lake would also work

19:51 but i'm going to leave it cake for now and see what happens

19:51 if it gets confusing i'll change it

19:52 raek: the only cake-named project I've heard of is Cake PHP

19:53 url to cake?

19:53 defn: uhb oh now you've said too much

19:53 lancepantz: we opened it up, http://github.com/ninjudd/cake

19:53 defn: lancepantz: i have to suggest you not make it cake -- lots of people i know will end up changing it

19:54 coffee script is at the emerging langs conference right now -- it has received quite a bit of attention

19:54 lancepantz: raek: note that the gem install method doesn't work right now, haven't pushed to gemcutter in a while

19:55 it's still really early

19:55 defn: but lancepantz tbqh i guess it's not that big of a deal -- it just feels more warm and gooey when i dont need to change the name of the script

19:55 it feels a bit dirty

19:55 but honestly, if it works, i dont give a damn

19:55 lancepantz: the persistent JVM thing is amazing

19:55 lancepantz: i don't disagree, just have other things to do than worry about the name right now

19:56 defn: when i typed `bake help` and it just shot across my screen i just about lose my mind with happiness

19:56 lancepantz: yeah, ninjudd did all that, its nuts

19:56 defn: lost*

19:56 lancepantz: did you tweet this to disclojure?

19:56 methinks you are going to be receiving a lot of attention

19:57 lancepantz: na, we don't want it spreading

19:57 its still too immature

19:57 build tools need to be solid

19:57 i'm focusing on adding tests next week

19:57 defn: oh yeah i totally agree, but that won't stop people from talking about it

19:57 lancepantz: then maybe

19:58 defn: i put up a project on github that i was toying with and tweeted about working on it with the tag #clojure, next thing I know I'm on disclojure

19:58 sort of a jolt as it was not even close to ready

19:58 lancepantz: right

19:59 defn: lancepantz: anyway, your work is amazing so far -- and tell ninjudd to hop on irc sometime :)

20:00 lancepantz: where did ninjudd get the idea for the persistent JVM?

20:00 lancepantz: swank for the most part

20:01 it's similar, it uses the socket server

20:03 defn: did you notice the repl has tab completion as well?

20:04 defn: lancepantz: !!!! oh my god

20:04 you are a genius.

20:05 lancepantz: again, ninjudd

20:05 defn: good god man. that boy ate his wheaties.

20:05 qbg: Is there a link somewhere about this?

20:05 lancepantz: qbg: http://github.com/ninjudd/cake

20:06 defn: qbg: the persistent jvm, tab completion at the repl, a coherent task system

20:06 "It's all happening!"

20:07 qbg: So we go from "not set your hair on fire" to "most delicious"?

20:07 Interesting...

20:07 Scriptor: clojure, it's advancing

20:08 defn: lancepantz: do you guys mind if i try to start filling out the Wiki with valid options you can use in your project.clj with some examples?

20:08 I'd like to document the (ns foo.tasks (:use cake)) thing in a bit more detail

20:08 lancepantz: ofcourse not

20:09 qbg: What if I want flammable cake?

20:09 On my hair?

20:09 raek: I have thought about a way of making it simpler to choose namespace names for libraries

20:09 the restrictions I have taken into account is that they should be

20:09 1) short, 2) unique, 3) hosting/endorsement neutral

20:09 ...so, a possible solution could be to register a domain for clojure libraries

20:09 and let people register projects names on it's web site on a first-to-register-the-name-gets-it basis

20:10 this service would only be a name registration service

20:10 any thoughts?

20:10 lancepantz: raek: merging something like that with clojars could be useful

20:10 Scriptor: raek: how would you stop squatters?

20:11 raek: people who register tons of names for the fun of it?

20:12 I'm thinking of the domain "cljlibs.org"

20:13 Scriptor: well, I feel like it could be exploited

20:13 qbg: The git clone URL in README.md for cake is incorrect

20:13 raek: then if I register the project name "pipes", I would use (ns org.cljlibs.pipe)

20:13 or maybe just (ns cljlibs.pipe)

20:14 lancepantz: qbg: ah, you are correct, i'll fix it

20:15 raek: maybe all requets should be manually inspected to see that they're real projects

20:15 a project URL would be mandatory, of course

20:16 people can choose whatever namespace they want now

20:17 but if this service gets popular there will be problems with squatters

20:18 Scriptor: right, if they have the project repo up on github or mercurial, you could simply ask them to verify that the request is coming from the repo's owner

20:20 raek: anyway, would you guys use such a namespace registration service if there was one?

20:20 qbg: It would be nice if such a service was integrated into github itself

20:22 raek: I have my own domain, so I have no problem making up new unique namespaces

20:22 but maybe I will not be the maintainer of the libs I start forever

20:23 free software projects belong to everybody, so the namespace should be as neutral as possible, I think

20:23 maybe I should try to start a service like this, and see what happens

20:24 it's not the end of the world if it fails

20:24 Scriptor: it'd be interesting, but I honestly don't think naming projects is that big of an issue

20:24 raek: then we hopefully learn something new

20:24 aldebrn: Is there a clojure templating engine as sophisticated as enlive but that isn't so tied to html templates? I'm coming from Jinja that converts my markup to html and latex.

20:25 raek: my thoughts was a result of reading this discussion http://groups.google.com/group/clojure/browse_thread/thread/968e9066223c3a2b/56bbf98b4bedfa97?lnk=gst&q=reeves#56bbf98b4bedfa97

20:27 wouldn't "(org.)cljlibs.foo" be a resonable compromise in this case?

20:58 lancepantz: does anyone know any project with a bin file called bake?

20:59 defn: ?

21:10 slyrus: what does (extend-protocol MyProtocol nil ...) do?

21:11 and did extend-class go away? the extend-protocol docs still refer to it.

21:12 defn: lancepantz: sorry im here

21:12 lancepantz: i did some cursory google searching and i couldnt find one that was as common as cake, but give me a minute, i have another avenue id like to try

21:13 lancepantz: there is that one i mentioned to you which is a python make replacement

21:14 ninjudd: defn: if we change the name to bake, you have to help us come up with some clever slogans, because none them work anymore

21:14 Save your fork, there's bake!

21:14 defn: ninjudd: :D

21:15 ninjudd: oh man, im pretty good at this sort of thing usually...give me a few minutes

21:15 raek: slyrus: (extend-procol MyProtocol nil (foo [x] ...)) defines what happens when you pass nil to foo

21:15 ninjudd: and Rich's inspirational quote taken totally out context: You are what makes Clojure great - find some bake and celebrate!

21:15 defn: hahaha

21:16 ninjudd: that one almost works

21:16 defn: get baked!

21:17 raek: slyrus: as for protocols, nil sort of works as its own type

21:17 ninjudd: haha

21:18 defn: ninjudd: Build tools got you down? Get baked!

21:18 slyrus: raek: ah, ok. wasn't sure if that was a default or something. thanks.

21:18 defn: ninjudd: but seriously -- what about a short recipe as the slogan

21:20 Mix 1/4 cup dishwashing liquid with 1/2 cup water, 1 tsp. sugar. Add a few drops of food colour if desired. Bake at 400 degrees for 30 minutes or until dependencies are satisfied.

21:21 too long...

21:22 Add equal parts clojure, ruby, love, and tenderness. Bake at 350 for 1 minute. Delicious.

21:22 raek: slyrus: extend-type was previously called extend-class

21:22 changed in commit ba9b7924de3f5b785bcbe1ed6e8ca5bf0ca7ec3d

21:24 defn: ninjudd: you're right, bake is harder to be snarky. Fork is so nice.

21:24 chouser: actually, there were separate extend-class and extend-type, when deftype didn't always produce a stably-named class

21:25 but that's ancient history now

21:32 dnolen_: stm, couchdb, futures, promises all at the same time, whee! http://dosync.posterous.com/stm-couchdb-and-pushing-5500-documentssecond

21:36 raek: the send-off for side-effects and alter for state change really fit nicely together

21:38 I need to come up with a name for a protocol

21:38 it has two methods, abort and wait

21:38 hiredman: I've noticed issues when I change some code inside an extend-protocol and the new code isn't used unless I restart the jvm

21:39 raek: it provides a way to stop and wait for a process to finnish

21:39 hiredman: I think those are called Futures

21:39 raek: however, Process already refers to java.lang.Process

21:39 hiredman: http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/api/java/util/concurrent/Future.html

21:40 that interface already exists, no need for a protocol

21:40 raek: I was thinking about using future-cancel for the termination

21:40 hiredman: get() is wait, and cancel is abort

21:40 so just implement the interface

21:40 raek: but when in a blocking read is canceled, one item of data was lost

21:42 hiredman: I don't care

21:42 raek: hrm

21:42 maybe making a new code for this is simply redundant

21:43 hiredman: you have a thing you want to implement this protocol right?

21:43 just have that thing implement Future instead

21:43 raek: well, I that could work

21:43 hiredman: the nature of the thing, and what it does, who cares, I am talking about isomorphism between your proposed protocol and an existing interface

21:44 raek: sure, I agree with you

21:52 ah, future-cancel works on any j.u.c.Future, right?

21:53 then I can still make an implementation that does the shutdown gracefully, but make that implement the Future interface

21:53 hugod: dnolen_: interesting, though isn't this trading throughput against time to consistency

21:54 raek: hiredman: thanks

21:55 dnolen_: hugod: it is, I mention that at the bottom, the example code will go much faster than couchdb can write to the database, we don't wait for the result

21:55 hugod: the code at the bottom implements a version using promises that's quite a bit slower that uses promises to actually return doc ids.

21:56 hugod: http://github.com/swannodette/stm-couchdb/blob/promises/src/stm_couch/core.clj

21:56 it's fun to use these crazy concurrency features in a web app :)

21:57 hugod: dnolen_: thanks, I see it now

22:01 dnolen_: indeed. I have an app using couchdb and websockets. no great throughput constraints, but the async notification possibilities of websockets are put to good use.

22:03 dnolen_: and thanks, I'm enjoying your blog posts :)

22:08 dnolen_: hugod: thanks for reading! :)

22:11 lancepantz: i do as well, you actually saved me dnolen

22:11 my boss was seriously considering putting a node.js service up

22:11 then you did your shootout at just the right time :)

22:15 dnolen_: haha

23:50 Bahman: Hi all!

23:54 Lajla: Bahman, I worship Your Shadow

Logging service provided by n01se.net