#clojure log - Oct 21 2011

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

0:00 amalloy: technomancy`: we should DDoS riddell.us

0:00 technomancy`: mwahaha

0:00 actually I wonder if clojurebot could be triggered to warn people upon any mention of those tutorials in a given line.

0:02 amalloy: technomancy`: lazybot recently got a regex-matching autoreply feature. i didn't add a user-facing way to add new replies, but i guess that's a good idea

0:03 but ugh, actually kinda hard. maybe i'll just tell him about riddell.us myself

0:07 $google lein tutorial

0:07 lazybot: [Tutorial - GitHub] https://github.com/ato/clojars-web/wiki/tutorial

0:08 technomancy`: =(

0:12 amalloy: technomancy`: there. hopefully this saves a few souls from riddell.us

0:12 lazybot: The riddell.us tutorials are much more highly-ranked on Google than they deserve to be. They're old and way too complicated. If you're trying to install Clojure...don't! Instead, install Leiningen (https://github.com/technomancy/leiningen/tree/stable) and let it manage Clojure for you.

0:13 technomancy`: lazybot: absolut botsnack

0:13 or barring that just a regular one

0:13 $botsnack

0:13 lazybot: technomancy`: Thanks! Om nom nom!!

0:13 * brehaut fears he needs to update his ring article

0:14 technomancy`: amalloy: nicely done

0:14 amalloy: technomancy`: of course, it already worked for people who were like: omg is this tutorial from two years ago any good??

0:14 lazybot: amalloy: What are you, crazy? Of course not!

0:21 jcromartie: I have to say, I installed Clojure via Leiningen on my Windows (Cygwin) box today. It was harder to get rlwrap than to get Clojure running.

0:22 1. Download lein 2. chmod +x lein && mv lein /usr/bin && lein repl

0:23 I <3 technomancy`

0:23 and lein of course

0:23 technomancy`: schweet

0:23 jcromartie: I was kind of surprised it just worked™ on Win7 + cygwin

0:30 amalloy: clojurebot: how does technomancy make stuff Just Work?

0:30 clojurebot: technomancy is to blame for all failures

0:31 jcromartie: that's ominous

0:31 like, *all* failures?

0:31 past, present, and future?

0:34 amalloy: counterexamples welcome

0:38 fmw: I'm trying to let a value in a macro, but I seem to have something wrong, because this works in a small test macro, but not in the larger actual one: http://paste.pocoo.org/show/495909/

0:38 any idea what I'm doing wrong?

0:40 I suppose this is not the best time of the day to ask ;)

0:41 scottj: not sure if `(let [~'params is always bad form but I think normally it should be `(let [params#

0:42 napping: is the "if" supposed to be at runtime?

0:42 fmw: scottj: doesn't the hash create a gensym (e.g. params__6622__auto); i.e. isn that meant for internal use within the macro?

0:43 napping: If you want it to fail when the macro expands, the ` needs to go inwards

0:43 scottj: fmw: yes

0:43 fmw: napping: which one?

0:45 napping: The if-not

0:45 fmw: napping: I think this has to happen at runtime, if I understand everything correctly, but I'm not sure I do. I'm new to clojure macros.

0:45 napping: right now, the macro makes one giant piece of syntax

0:45 You should be able to count the number of clauses

0:46 fmw: yes, I ran macroexpand-1 over it, to figure out what is going wrong, and that syntax looks correct

0:46 napping: as it is, all the bodies evaluat when they are spliced into list

0:46 hiredman: so I have this macro for generating deftypes for tuples, up to 10 elements

0:46 https://gist.github.com/1303118

0:46 napping: and the rest of it is just picking out one of the values

0:46 hiredman: it's kind of fast

0:47 I haven't checked to see if the storage requirements are much smaller than for a vector

0:47 amalloy: hiredman: aw, you should have just used JavaTuples

0:47 hiredman: (and all the interfaces aren't filled in yet)

0:47 amalloy: meh

0:47 amalloy: (not a real suggestion. those are awful)

0:47 napping: fmw, one red flag is that you are not actually splicing body inside the let

0:48 fmw: napping: maybe its best if I explain what I'm trying to do: it is basically a (cond) replacement, but with the params variable as the result of the uneven arguments and available to the body of the even arguments (so I can write (handle-this-uri-function (:feed params)) to supply the feed from the uri to that function)

0:50 napping: it's not working like a cond replacement. Look at the macroexpand-1 results again

0:50 fmw: the (routes-match ...) function either returns false or a map of params

0:50 napping: ok, let me compare a macroexpand-1 of cond to this

0:51 hiredman: https://github.com/hiredman/tuples/blob/master/src/tuples/core.clj

0:52 fmw: napping: ah, yes, I see the difference

0:52 hiredman: access via nth is about on par with pvectors

0:52 jcromartie: hiredman: what's the advantage of a tuple over a vector?

0:52 fmw: I started with the source for cond for my first version, btw, and worked from that, but dropped it for this recursive version

0:53 hiredman: jcromartie: (get0 a-tuple) is faster than (nth a-vector 0)

0:53 jcromartie: and (nth a-vector 0) is already O(1) isn't it?

0:53 hiredman: I have not confirmed yet, but I believe they'll take up less memory then the equivalent vector

0:54 jcromartie: log_32(n) because of the tree sharing

0:54 jcromartie: ah

0:54 OK so tuples don't do any sharing

0:55 hiredman: right

0:55 a tuple is really O(1)

0:56 and you don't have the machinery that is used to back pvectors

0:56 jcromartie: If I wanted to implement a super simple tuple, I'd use a function, though

0:56 well, a macro

0:56 hiredman: how so?

0:57 these tuples implement most of the interface of pvectors

0:57 (or will, once I get to the rest)

0:57 a macro is not a datastructure

0:58 you can make a macro that expands to [x y], but as I said, accessing the elements of a tuple via get[0-9] is faster than nth on a vector

0:59 amalloy: i think jcromartie is thinking of the way you can implement cons cells as just closures. doesn't really work well in clojure because you need to implement the various interfaces if you want to make them seqable etc

0:59 chewbranca: anyone have any ideas on this error when running lazybot "Map literal must contain an even number of forms" http://paste.lisp.org/display/125422

1:00 amalloy: haha is that still checked in? chewbranca: in ~/.lazybot/info.clj there's probably a map that looks like {true}

1:00 jcromartie: yah it would be very primitive

1:00 but here

1:00 (defmacro tuple [& xs] `(fn [idx#] (case idx# ~@(mapcat list (range (count xs)) xs))))

1:00 that's my O(1) tuple :)

1:01 hiredman: jcromartie: nah, it's going to be slower

1:01 jcromartie: with casE?

1:01 case

1:01 hiredman: case requires computing hashses

1:01 jcromartie: "Unlike cond and condp, case does a constant-time dispatch"

1:01 amalloy: jcromartie: a thousand years is constant time too

1:01 jcromartie: :P sure

1:01 chewbranca: amalloy: let mecheck it out, didn't realize it used ~/.lazybot as opposed to ./lazboy/.lazybot/info.clj

1:01 Chousuke: the hash function isn't very complex though

1:01 hiredman: would you like me to link you too the compiler source?

1:02 amalloy: chewbranca: it copies ./lazybot to ~ the first time it runs

1:02 hiredman: Chousuke: sure, and is fact a method call, and if you are indexing using numebrs it is likely to inline

1:02 but I think performance wise it might come out as a wash, and my tuples have a nicer interface

1:03 jcromartie: yes, absolutely :)

1:03 amalloy: hiredman: are you storing N fields, or one N-sized array?

1:03 jcromartie: I just thought it would be fun :P

1:03 hiredman: amalloy: N fields

1:03 chewbranca: amalloy: yeah was editing the local .laazybot/info.clj, but yes, there is a {true} in there lol

1:03 hiredman: but I only generate tuples up to size 10

1:03 fmw: napping: ok, I've been experimenting a bit and looking at macroexpand-1 output, but I'm afraid I'm not getting much further

1:04 amalloy: hiredman: you could make nth quite fast if you also used an n-sized array, i suspect, as long as the memory tradeoff doesn't matter

1:04 fmw: napping: the macro itself works perfectly, btw, just not the variable assignment

1:04 although the (let params [...]) is in the macroexpand-1

1:04 amalloy: since i assume you'd want to keep the N fields for fast getN

1:05 napping: don't the bodies end up outside that?

1:05 fmw: napping: let me paste the macroexpand-1

1:06 hiredman: actually my nth is already implement via case like jcromartie suggested, but it wasn't fast enough

1:06 jcromartie: oh really?

1:06 hiredman: (which is why I added TuppleAccess)

1:06 yeah

1:07 it performed very similarly to nth on pvectors

1:07 chewbranca: amalloy: good call, the {true} was the issue, fixing that has led me to the next error :/

1:07 amalloy: right, case would be my first effort too. but an array access is nearly as fast as a field lookup, if you don't mind storing everything twice

1:08 hiredman: I'd rather not, I'd like to keep these fast and light

1:09 since it is a macro you could conceivably tell it what strategy to use and it would just generate the tuples you want

1:10 amalloy: *nod*

1:10 fmw: napping: http://paste.pocoo.org/show/495919/

1:11 napping: its a bit messed up there - all in one line

1:12 let me format that a bit more pleasantly

1:13 amalloy: hiredman: is this in a repo anywhere yet? i'd like to poke at the bits and see how the various tradeoffs behave

1:14 hiredman: https://github.com/hiredman/tuples/

1:15 chewbranca: amalloy: good call on {true}, I commented that out and the weather and markov plugins and it worked

1:15 amalloy: chewbranca: yeah, info.clj tends to get neglected. send us a pull request with the fixes you made, if you don't mind?

1:15 hiredman: the inability of (deftype Foo ...) to call (new Foo ...) in its methods is a real drag

1:16 fmw: napping: http://paste.pocoo.org/show/495920/ still pretty horrible to read, but a lot better

1:16 amalloy: hiredman: really? it's always worked for me

1:16 hiredman: I seem to get all kinds of classloader issues

1:16 with 1.3?

1:16 amalloy: hiredman: haven't tried in 1.3

1:17 chewbranca: amalloy: sure, just commented and deleted stuff but I'll get out a pull request

1:17 hiredman: hmmm

1:17 actually it works at the repl, I wonder why it isn't working in my macro

1:18 ah, I was doing it wrong of course

1:19 fmw: napping: and here is the macroexpand-1 of the simpler macro that does work: http://paste.pocoo.org/show/495921/

1:20 napping: fmw: looks where the arguments ended up - inside the calls to list

1:20 fmw: napping: the body is different in those expands

1:21 the working one expands the body fully, the one that doesn't work lists the gensym var for body

1:22 napping: the working one expands to a let that has the body spliced into it

1:22 natto: has anybody watched Hickey's strangeloop presentation?

1:22 http://www.infoq.com/presentations/Simple-Made-Easy

1:22 I've a question about "queues" that he says around 55:20

1:22 napping: the broken one expands to a loop that iterates over a list made from the spliced arguments, and has inside that a let whose body is the gensym variable named from "body"

1:23 natto: if you have A calling B, and B is called whenever A calls it, you should "stick a queue in there" -- what does he mean by that and what's the clojure example?

1:23 napping: I'm not explaining it very well at all, but you need to move the division between what's done in the macro and what's done at runtime

1:23 fmw: napping: how do you mean? I only see one call to list: (clojure.core/list ["admin" :feed "edit"] but it doesn't seem to be inside that

1:24 chewbranca: amalloy: https://github.com/flatland/lazybot/pull/31

1:24 napping: that's the one - that's all the arguments

1:24 amalloy: hiredman: should this perform the same as https://gist.github.com/1303118? i only see get0 about twice as fast as vector-nth

1:24 napping: (next line gets the body :foo)

1:25 chewbranca: so debugging question for you guys, how would I determine that there was an error in info.clj from http://paste.lisp.org/display/125422 ?

1:28 scottj: chewbranca: I'd C-c C-k info.clj then re run the code that caused that error and hopefully NO_SOURCE_FILE:1 would be replaced with info.clj and the line number

1:28 hiredman: amalloy: yes, that is the same code

1:28 (I think I am on the osx preview release of java 7)

1:28 amalloy: interesting

1:29 napping: fmw: maybe more like this http://paste.pocoo.org/show/495926/

1:29 amalloy: my computer is much older and creakier, and using java 1.6

1:29 chewbranca: scottj: well that's the issue, I had no idea the issue was info.clj until I came in here and asked, just wondering if there is a better way to track it down that ask in here

1:29 amalloy: but for 1e9 iterations i get 28s and 41s respectively for tuples and vectors

1:30 fmw: napping: ah, I thought that list call was the list call I had in the function

1:30 but I removed that and it is still there

1:30 napping: well, it was all inside the `

1:30 amalloy: anyway, i'll fiddle with it some, just wanted to make sure i was working with the same code you were when you got those numbers

1:30 hiredman: sure

1:30 napping: so your pretty much everything in the defmacro was copied into the call

1:30 scottj: chewbranca: yeah, make sure your code was compiled with C-c C-k not entered at the repl or C-x C-e that way functions not prefixed with clojure should have the right file and line number

1:31 chewbranca: you can setup emacs to highlight the function calls that are yours and dim builtin clojure ones

1:32 hiredman: amalloy: yeah, the times I get for both are still within a second of what is in the gist for each

1:33 chewbranca: scottj: nice, I'll check that out

1:35 fmw: napping: when I run that I get java.lang.Exception: No such var: vix.core/body (NO_SOURCE_FILE:20)


1:37 napping: I modified your code before running it though, into http://paste.pocoo.org/show/495929/ (just removed the (count) check)

1:37 napping: oh, it needs a splice on body (not sure which kind, or if you need a do, etc)

1:38 why do you want to only get the count error when the code actually runs?

1:39 fmw: napping: having that at compile time would be better indeed, but I removed it altogether for now to make it simpler

1:39 napping: hmm, the base case is also wrong

1:42 fmw: napping: ah, when I splice that with ~ it works (i.e. ~body)!

1:44 napping: what do you mean about the base case being wrong, btw?

1:46 mvid: i dont really understand this error:

1:46 lib names inside prefix lists must not contain periods

1:47 what should i be looking for?

1:49 amalloy: mvid: broken ns form

1:50 it will look like (ns foo (:use (bar [baz.bang ...])))

1:50 or the same thing with require/import

1:52 napping: fmw: I think the recursion might run one step too many, or maybe I'm wrong about that

1:53 No, it should be fine - if the size is even and cases is nonempty you'll get a body and a route pattern (other than nil)

1:54 mvid: amalloy thanks

1:54 fmw: napping: I think so too, ~body is returned if that if clause is true. if it would run again it wouldn't execute correctly and it does

1:55 napping: thanks a lot for your considerable help, I really appreciate it, as I was completely stuck (this was my first non-trivial macro)

1:56 napping: Great, I'm glad I made some sense

1:56 fmw: napping: I don't fully understand what I did wrong yet, but I've got a clearer picture of it thanks to your code

1:57 napping: basically, splitting the operation between compile time and run time (the first if-let at compile time, the second at run-time)

1:59 I think I also have a general idea of why the need to happen at their specific times, but I guess I'll have to dive deeper into macros before I will grok it completely

2:00 I guess they're hard to explain in this form, and the best way ahead is just to experience a sequence of "eureka moments" by rereading the macro chapters in my clojure books and writing a few more ;)

2:01 napping: Do you know how macroexpansion works?

2:07 It might be easier to understand if you write more as a function

2:11 fmw: napping: I think I do, yes

2:12 although I still have to figure out the finer details of splicing etc (understand it generally, but need to learn about the specifics)

2:12 but got some good books for that, thankfully

2:13 napping: Well, then it's just the hard stuff you already mentioned

2:14 Still, it might help to write a defn rather than a defmacro, then you can call it with quoted things and see what happens without bothering with macroexpand-1

2:14 and make a defmacro that calls the function, to be able to actually use it in code

2:14 fmw: the problem is that I've been fine without macros so far, so even if I read the relevant chapters in the clojure books I have that was months ago and I didn't use that information, so I've got to refresh it a bit

2:15 the problem is that writing code without macros tends to give some less than elegant code sometimes (i.e. a lot more typing than when using a macro)

2:15 so started to refactor that

2:16 ah, now I understand what you mean by writing more as a function

2:18 btw, I might've said it already, but I really appreciate all the effort you've put into helping me understand my macro problem. I keep getting surprised by the helpfulness of this community :)

2:18 napping: I'm pretty new myself :)

2:19 fmw: how long have you been using clojure?

2:20 napping: Hmm, a few weeks? I looked over the design a while ago, though

2:20 (mostly learned about macros in Scheme)

2:20 fmw: napping: did you have a lisp background?

2:21 I've been using clojure for a couple of months now, but still have to explore some aspects of the language

2:21 ah, yes, I'm planning to learn Scheme and Common Lisp soon as well

2:22 working my way through SICP and the little schemer books, slowly ;)

3:03 georgek: hi, I just set up things for the first time in Emacs on Windows, and after clojure-jack-in I got this error, http://pastebin.com/wQej4hT4; lein swank works OK from the command line though

3:03 I used these instructions for set up, http://dev.clojure.org/display/doc/Getting+Started+with+Emacs

3:33 OK, these additional instructions do the trick, http://sourceforge.net/apps/wordpress/codesounding/2011/09/29/installing-emacs-24-and-clojure-mode-on-windows-7-step-by-step/, the key is making sure you can run sh

3:45 Blkt: good morning everyone

4:58 ejackson: morning all

6:11 Raynes: you ever sleep ?

7:34 G0SUB: I think this new numeric tower changes is 1.3 are confusing a lot of people (not me)...

7:34 may be we should document all the changes and the new semantics somewhere and widely circulate it.

7:35 the current docs in the wiki are not clear enough, apparently

7:37 Chousuke: There is a lot of reference-style documentation for Clojure but in-depth tutorials/explanations, essays or case studies seem a bit scattered

7:39 You can find it on the interwebs but it requires some google-fu :P

7:56 ljos: Is there an easy way to do this in parallel? : (take 10 (repeatedly #(rand-int 100))) . This is a really trivial example, but if the function that is run by repeatedly is going to take some time, but is not affected by the other values I think it should be doable. I could do (pmap (fn [n] (rand-int 10)) (range 0 10)), but then I have to create a collection first. In my case, I do not care about the order of the resulting collection.

7:59 raek: ljos: one way could be to use the .invokeAll method of ExecutorService (the underlying class that 'future', 'send', 'pmap', and others use)

8:00 cemerick: ljos: use pcalls, and repeat instead of repeatedly

8:01 raek: (->> #(rand-int 100) (repeat 10) (.invokeAll exe) (map #(.get %)))

8:02 ljos: nevermind... :-) what cemerick said does the same thing, but with existing clojure functions

8:02 ljos: :)

8:02 Thanks guys.

8:13 ...mhm.. how do I pcalls to run on the return of the repeat? It is a collection and pcalls doesn't run on collections. I came up with this, but it seems excessive: (eval `(pcalls ~@(repeat 5 #(rand-int 10))))

8:20 jcromartie: ljos: apply?

8:20 (apply pcalls (repeat 5 #(rand-int 10)))

8:20 ,(apply pcalls (repeat 5 #(rand-int 10)))

8:20 clojurebot: (3 5 8 5 5)

8:21 ljos: I just found that :P

8:22 Thank you though.

8:22 jcromartie: yeah :)

8:25 babilen: Hi all. I am looking for a library for path manipulations that supports multiple OSs. In particular I want things like (for example) (expand-user "~") → "/home/babilen" (unix) or (path/join ["foo" "bar" "baz"]) → foo/bar/baz (unix) ... etc. Essentially os.path (python) in clojure ;)

8:26 raek: babilen: clojure.java.io/file can join path segments in a OS-independent manner

8:26 ,(apply clojure.java.io/file ["foo" "bar" "baz"])

8:26 clojurebot: #<File foo/bar/baz>

8:26 Chousuke: see the documentation for Java Class library's File class too

8:28 babilen: Ok, I'll investigate that ... thanks raek, I found file before but wasn't aware that you can use it like that. Hopefully Java's file class has something like expanduser

8:28 thanks for the pointers

8:29 raek: ,(System/getProperty "user.home")

8:29 clojurebot: #<AccessControlException java.security.AccessControlException: access denied (java.util.PropertyPermission user.home read)>

8:30 raek: that will give you the equivalent of ~, but I don't know how to get the home dir of any user...

8:33 babilen: raek: Well, that would be a start. But I still have to check if the string I am handed contains a ~ at the beginning and normalise it. I would have hoped that there is a comprehensive path manipulation library for clojure or java already. If something else crosses your mind just let me know. :)

8:46 MasseR: 7win 21

8:47 bhenry1: i need some good resources on appending to a file. my data is too big to do it all in one shot

8:51 cemerick: bhenry1: FileOutputStream, clojure.java.io/output-stream, and clojure.java.io/writer can all append to a file instead of overwriting it.

8:51 raek: bhenry1: you can use an java.io.OutputStream (binary) or a java.io.Writer (text). the clojure.java.io namespace contains useful functions for constructing these objects

8:51 bhenry1: i am reading that spit appends if you set :append true

8:51 is that true?

8:51 raek: spit, c.j.io/writer, and c.j.io/output-stream takes an :append option

8:52 bhenry1: yes

8:52 bhenry1: cool.

8:52 raek: bhenry1: one alternative is to use 'print' instead of 'spit'

8:52 bhenry1: that might work then. thanks for the info

8:52 print with *out* set to a file?

8:52 raek: yes

8:53 bhenry1: i think i'll try the spit append first.

8:53 raek: (with-open [out (io/writer "my_text_file.txt")] (binding [*out* out] (doseq [line some-lines-here] (println line))))

8:54 *or*

8:54 bhenry1: raek: copied that into scratch in case i need it

8:55 raek: (with-open [out (io/writer "my_text_file.txt")] (doseq [line some-lines-here] (.write out line) (.newLine out)))

8:56 bpr: can i use the version of slime in marmalade with swank-clojure 1.4.0?

8:57 raek: a point: .write is far more lightweight than spit

8:58 bpr: i updated swank-clojure last night, and now (after shutting down and restarting my system) it seems swank and slime aren't getting along.

9:47 jcromartie: what's the best way to read all of the bytes from a stream and throw away the results?

9:47 because, in true mutable OO fashion, this actually requires me to do so

9:47 I have a loop right now

9:47 and a buffer

9:47 I guess the buffer is non-negotiable

9:48 (doseq (take-while #(not= -1 %) (repeatedly (.read stream buffer)))

9:48 or something like that

9:49 raek: jcromartie: loop/recur is fine here

9:49 jcromartie: yeah https://gist.github.com/5ac9951ec2f012212580

9:50 seems to be pretty clear

9:50 raek: (loop [i (.read stream buffer)] (when-not (= i -1) (recur (.read stream buffer))))

9:51 jcromartie: yup

9:53 TimMc: jcromartie: THere's no way to just advance the buffer, or maybe read a known length out?

9:54 jcromartie: I don't think so

9:54 TimMc: jcromartie: InputStream.skip?

9:55 s/buffer/stream/

9:55 jcromartie: ah ha

9:55 InputStream.skip is the thing

9:55 internally, it does read

9:55 into a buffer (according to the docs)

9:56 TimMc: By default, yes.

9:57 Subclasses will do fancier things.

9:57 jcromartie: of course, calling (.skip stream Long/MAX_VALUE) might read it into a buffer of that size

9:57 so it's not a one-off operation

9:57 or it shouldn't be

9:58 G0SUB: cemerick, Howdy!

9:58 jcromartie: and calling skip more than once might reallocate the buffer each time

9:59 cemerick: G0SUB: :-)

9:59 raek: jcromartie: note that skip returns the number of bytes actually skipped.

9:59 cemerick: I always forget that that's a zero, not an 'o'.

9:59 jcromartie: yes

9:59 G0SUB: cemerick, I hope you got my email...

9:59 fhd: I bet someone here has a clever piece of code that sets the inferior-lisp-variable depending on whether this is a Leiningen, Maven, cake etc. project?

9:59 cemerick: G0SUB: I did; no worries :-D

9:59 jcromartie: now... here's something I have always wondered: when people do operations involving buffers, they usually pick a power-of-2 size

9:59 is that just habit?

9:59 I know there are reasons to align memory in C

9:59 but in Java...

9:59 ?

9:59 G0SUB: cemerick, that's due to historical reasons, when I registered the nick, O was taken.

9:59 cemerick: Sorry for not replying, I'm lacking bandwidth these days.

9:59 pjstadig: jcromartie: we like round numbers

9:59 jcromartie: :P

10:00 G0SUB: cemerick, I completely understand that. That's why I didn't bug you further.

10:00 cemerick: G0SUB: you'll be at the Conj, I trust?

10:00 G0SUB: cemerick, can/should we do something to explain the new numeric tower changes to the masses?

10:00 cemerick, absolutely!

10:01 cemerick, I fear this might be a PR disaster...

10:01 cemerick: The maths stuff is the PR disaster?

10:01 G0SUB: cemerick, no, the lack of docs explaining the rationale.

10:01 cemerick, I am personally fine since I have taken the time to understand the implications

10:03 cemerick: There's lots of material out there, including http://dev.clojure.org/display/doc/Documentation+for+1.3+Numerics

10:03 G0SUB: cemerick, the current thread is making me uneasy...

10:03 cemerick: heh

10:03 G0SUB: cemerick, I know, but apparently that's not clear enough

10:03 cemerick: There was one a while back that was 100's of messages long :-)

10:04 stuarthalloway: my conj talk will cover the numerics stuff

10:04 and if nobody writes good docs before then I will

10:04 G0SUB: cemerick, true, and I read that too. and now this, with Nathan "proposing" certain very broad and breaking changes.

10:04 cemerick: I think few people understand the complexities of JVM numerics, prims / boxed, etc etc.

10:04 stuarthalloway: but I would be thrilled if somebody else did it

10:04 G0SUB: stuarthalloway, I wish I were qualified enough to do that...

10:05 people are not understanding that new semantics are actually simpler and way better than the one before.

10:05 `fogus: G0SUB: One way to become qualified is to write about it. :-)

10:05 cemerick: I take this as similar to immutable data structures. Clojure provides them, there is a (pleasant) degree of interop, but it's not going to buy into broken semantics wholesale.

10:06 G0SUB: `fogus, ;-)

10:06 cemerick: G0SUB: All of the books coming out after 1.3 will address it, presumably.

10:06 stuarthalloway: I don't think it belongs in an intro book

10:06 jcromartie: yay for long and double

10:06 that's a step in the right direction

10:07 G0SUB: cemerick, yeah, that'd be great.

10:07 * `fogus gets nervous when he sees (time (dotimes ...))

10:08 cemerick: stuarthalloway: I don't like the intro / advanced dichotomy.

10:09 I think you can do gentle-come-hither, talk turkey on tools and practical libraries, and do fuck-you-hardcore all in one book.

10:09 G0SUB: cemerick, all in < 500 pages?

10:09 cemerick: or, I hope that's practical, or we're going to bomb

10:09 zilti: Is clojure slime really as broken as it seems? (As broken as in "type an expression in the slime REPL and get half-a-minute pc-beeps and error messages")

10:10 cemerick: G0SUB: I hope so, 'cause I'm not writing any more pages. :-P

10:10 G0SUB: zilti, not in here.

10:10 cemerick, hehe

10:10 zilti: "error in process filter: Wrong type argument: characterp, nil"

10:10 jcromartie: zilti: nope

10:10 cemerick: I guess people's definitions of hardcore will vary, but *shrug*

10:10 jcromartie: zilti: sounds like an Emacs lisp error

10:11 G0SUB: zilti, could be related to the encoding system of swank

10:11 `fogus: cemerick: So you have a chapter on Fexprs then?

10:11 zilti: hmm

10:11 `fogus: ;-)

10:11 G0SUB: zilti, (setq slime-net-coding-system 'utf-8-unix)

10:11 cemerick: dammit

10:12 `fogus: OK, 3 more pages, just for you ;-)

10:12 `fogus: Sweet!

10:12 G0SUB: zilti, try evaluating this and try again.

10:13 zilti: G0SUB, evaluate in *scratch* didn't help - will try it in SLIME repl as soon as it stops beeping

10:14 G0SUB: zilti, eval this in *scratch*

10:14 zilti, and then reconnect

10:14 zilti, of course, this could be completely unrelated.

10:15 zilti: Oh. Have to restart emacs first. Emacs is acting completely weird now. M-x results in error message.

10:16 G0SUB: zilti, ah, somehow your emacs is borked.

10:16 zilti: Had to sigkill it now

10:17 G0SUB your setq didn't help - now autopair works in REPL but I'm still getting the same errors

10:18 G0SUB: zilti, hmm, strange. which emacs is this? which OS?

10:18 zilti: Emacs 23.3 on Linux 3

10:18 (Opensuse Tumbleweed)

10:19 G0SUB: zilti, you shouldn't face any problems with that.

10:19 zilti: That's the theory, yes

10:20 I even changed my slime version - I first used the "frozen slime for clojure compatibility" and now switched to the current cvs version. No difference. Btw the REPL still shows "20100404"

10:20 G0SUB: zilti, really unfortunate. It has always worked flawlessly for me/us.

10:20 zilti, the current slime won't work with clojure.

10:21 zilti, you'll need the forked slime IIRC.

10:21 simard: zilti: remove anything related to slime in your .emacs

10:21 then get clojure-mode from marmalade

10:21 that did it for me yesterday

10:22 I also removed the (setq inferior-lisp-program...) part

10:22 (from my .emacs file)

10:22 zilti: I don't have that in my .emacs

10:23 simard: are you doing a (require 'slime) in your .emacs ?

10:23 G0SUB: zilti, you can also try using my emacs system. it has built-in support for clojure. but then you'll have to throw away your own .emacs temporarily.

10:23 zilti, https://github.com/ghoseb/dotemacs

10:23 AWizzArd2: I could suggest to use the Emacs Starter Kit. There install just clojure-mode and install Leiningen. Then you can simply double click one of your code files so that Emacs opens and do M-x clojure-jack-in and you will have a running slime session that works.

10:24 zilti: Still get the same problems.

10:24 G0SUB: zilti, with my setup, you won't need to do anything. just get the submodules.

10:26 simard: zilti: I also did a lein upgrade, lein plugin install swank-clojure 1.3.3, removed anything related to slime from my .emacs file and restart it, then M-x clojure-jack-in worked..

10:26 zilti: G0SUB where's the clojure config part?

10:26 G0SUB: zilti, config/slime.el & config/clojure.el

10:27 zilti: simard: It's not that clojure-jack-in doesn't work - the slime repl doesn't

10:29 G0SUB: And where to get the compatible slime again?

10:29 G0SUB: zilti, https://github.com/technomancy/slime

10:32 zilti, Clojure mode is here https://github.com/technomancy/clojure-mode

10:33 zilti: I have clojure mode already

10:33 bpr: does anyone know why i'd get a FileNotFoundException in sldb when hitting C-c C-l in a file? I am able to do C-c C-k on that file just fine...

10:33 swank-clojure 1.3.3

10:34 zilti: "Versions differ: 2009-10-15 (slime) vs 20100404 (swank). Continue?"

10:34 And still having the same problem.

10:34 G0SUB: zilti, yes.

10:35 zilti, which swank-clojure do you have?

10:35 zilti: 1.3.3

10:35 bpr: btw, the message on that exception is: /home/brian/projects/rd-web/src/rd (Is a directory)

10:36 G0SUB: zilti, I have no idea why that's not working

10:38 zilti: What about that it's still even now "SLIME 20100404"? Is that the correct version?

10:39 bpr: i have 20100404.1 and swank-clojure 1.3.3 and things are working (largely)

10:39 zilti: hmm

10:41 AWizzArd2: Slime is not required anymore with a current setup.

10:41 clojure-jack-in will download a working slime automatically.

10:44 arohner: has anyone seen java.lang.ExceptionInInitializerError when using midje?

10:44 zilti: AWizzArd2: Obviously it is downloading a broken slime

10:45 AWizzArd2: On my compi it works.

10:45 Together with Emacs 24, the Emacs Starter Kit and clojure-mode and Leiningen.

10:46 bpr: AWizzArd2: iirc insalling clojure-mode with elpa pulls slime 20100404.1 in as a dependency

10:46 installing*

10:47 i could be wrong though... i have other things installed that might have listed slime as a dependency. so take that with a large grain of salt

10:47 AWizzArd2: in my elpa folder I have nothing that looks like slime. But: when I do c-j-i then in my .emacs.d I will get a folder swank/ into which two slime files get downloaded.

10:48 bpr: all I have to say is thank god for technomancy

10:48 AWizzArd2: ok, i must be wrong

10:48 AWizzArd2: Better let's thank his parents, I guess those exist :-)

10:48 bpr: haha

10:49 AWizzArd2: Now I just need to find a sane way to use Midje with Leiningen.

10:49 Writing tests and constantly going to the command line to run "lein midje" is too time consuming.

10:56 arohner: AWizzArd: are you an emacs user?

10:57 AWizzArd: https://github.com/marick/Midje/wiki/Midje-mode

10:58 AWizzArd2: ping the right username

11:02 AWizzArd2: arohner: oh good, that looks like the thing I wanted

11:17 Whenever I do clojure-jack-in a buffer *Compile-Log* opens which tells me that it is compiling the two files in ~/.emacs.d/swank/. How can I turn this feature off, if those files already exist in compiled form in that folder?

11:27 arohner: how can I enable midje-mode by default? What the wiki describes (using require) doesn't work for me. Slime is not present when Emacs is started, only after clojure-jack-in was done. How can I add a hook so that after c-j-i was successful the midje-mode will be entered?

11:28 arohner: AWizzArd2: I have (require 'midje-mode) (add-hook 'clojure-mode-hook 'midje-mode) in my .emacs

11:28 so it's enabled any time you're in clojure mode

11:29 AWizzArd2: Unfortunately this require thing doesn't work for me.

11:29 arohner: if require midje-mode doesn't work, it's probably not installed in the right location

11:29 where did you put it?

11:30 tylere: Is Programming Clojure still the recommended beginner book? It seems like it would be a bit out date by now

11:30 I bought the pdf a while back but never really got in to it

11:30 AWizzArd2: I did a M-x package-install midje-mode ==> that downloaded it from the Marmalade repository and installed it into ~/.emacs.d/elpa/midje-mode/

11:30 tsdh: What's the right maven syntax to specify in my leiningen deps that I want clojure 1.3.0 or better, but less than 1.4.0?

11:31 AWizzArd2: And I can activate it manually, after c-j-i via M-x midje-mode

11:31 arohner: try putting (require 'clojure-mode) (require 'swank-clojure) before the (require 'midje-mode)

11:33 AWizzArd2: I can also not require clojure-mode.

11:34 For example, to get paredit working on Clojure I did: (autoload 'paredit-mode "paredit") (add-hook 'clojure-mode-hook (lambda () (paredit-mode +1)))

11:34 tsdh: Ah, got it: [org.clojure/clojure "[1.3.0,1.3.9999)"]

11:35 arohner: AWizzArd2: is there anything in your .emacs about loading elpa or the clojure starter kit?

11:35 or (package-initialize)?

11:35 AWizzArd2: The .emacs file doesn't exist. All configs are in ~/.emacs.d

11:35 tsdh: Another thing: is it possible to query leiningen (or maven) what package pulled in some dependency?

11:35 AWizzArd2: Today many emacs user seem to not use the .emacs style anymore.

11:35 arohner: tsdh: lein pom && mvn dependency:tree

11:36 tsdh: arohner: Excellent, thank yeu.

11:37 arohner: mvn dependency:tree seems to download the complete internet...

11:37 arohner: tsdh: yeah, it only does that occasionally...

11:37 like the first time you use it that day

11:37 tsdh: arohner: Well, it's never bad to have a backup, right? ;-)

11:38 jcromartie: how can I write the dispatch value for a multimethod on a byte array?

11:38 [B doesn't work

11:38 ah

11:38 ,(Class/forName "[B")

11:38 clojurebot: [B

11:40 gfredericks: does anybody know the url to use for maven central in the lein repositories definition?

11:41 it is apparently hard to google for :/

11:41 cemerick: gfredericks: it's implied, you don't have to have it in there

11:42 arohner: gfredericks: like cemerick said, you shouldn't have to specify it, but if you're curious, http://repo1.maven.org/maven2

11:42 gfredericks: cemerick: but when I add a special repo it now asks for everything from there rather than maven central

11:42 AWizzArd2: It would be interesting for me to know the ips of all repos. So I could configure my firewall correctly…

11:42 gfredericks: arohner: thanks

11:42 arohner: it's in leiningen/core.clj

11:42 gfredericks: it took 3 minutes to download mysql-connector :(

11:42 arohner: noted

11:42 AWizzArd2: I saw that my Leiningen tried to contact "jboss" and something with "sonatype" in the name.

11:43 grepping the Leiningen sources didn't reveal any mappings

11:43 cemerick: gfredericks: Ah, sure. Easy way to specify your local proxy repo, that is.

11:43 I think that was along the lines of a lein patch I got in a while back, though I don't know if it's been rolled into a release yet.

11:44 tsdh: amalloy_: Why does ordered-0.3.0 depend on clojure-contrib-1.2.0? It doesn't use anything of it at all. And probably the dependency on ordered-set-0.2.2 only for benchmarking purposes might not be warranted.

11:50 bpr: what's the best way to cause the slime repl to dump a namespace and reload it from source?

11:57 jcromartie: I want to get a SHA-1 hash of a Clojure map

11:57 is that feasible?

11:58 obviously everything needs to be sorted

12:00 raek: jcromartie: then you first need to define a mapping from clojure maps to sequences of bytes

12:00 jcromartie: yeah that is the tricky

12:00 part

12:01 especially if I want (= (sha-1 {:x 1 :y 2}) (sha-1 {:y 2 :x 1}))

12:01 raek: if you just want _a_ hash value that's consistent within the JVM instance, you could use .hashCode

12:01 bpr: i don't know if you'll find it helpful, but gloss is a great way to define a mapping from clojure data to bytes

12:02 https://github.com/ztellman/gloss

12:02 raek: there is of course the _very_ naive (-> m (pr-str) (.getBytes "UTF-8"))

12:02 bpr: but of course as raek alluded, there's also clojure.core/sorted-map and clojure.core/hash

12:03 yup

12:04 raek: jcromartie: one idea is to define your own Hashable protcol and implement it for clojure data structures

12:04 jcromartie: yah

12:04 fliebel: Talking about Gloss, can it do little endian and padding?

12:06 raek: (extend-protocol Hashable IPersistentMap (sha-1 [m] (let [ks (sort (keys m))] (reduce combine-hashes initial-hash (apply concat (for [k ks] [(sha-1 k) (sha-1 (m k))])))))

12:06 bpr: fliebel: it can def do padding

12:06 raek: then you could define this "sha-1" recursively

12:07 bpr: fliebel: as far as little endian, i'm not sure how easy that will be. It uses java.nio.ByteBuffer so it's def possible

12:07 fliebel: bpr: How? I need to have some things 16-bit aligned.

12:07 Cozey: Hello. which appengine library would you recommend? appengine-clj, appengine, appengine-magic ?

12:07 bpr: fliebel: I just don't know whether the endianness is exposed via the api

12:08 Cozey: I've had good success with appengine-magic

12:08 raek: so the sha-1 of a collection would be based on the sha-1 of its elements in some specific way

12:08 Cozey: bpr: thanks, i'll try it

12:09 opqdonut: raek: making that as good as SHA-1 is probably nontrivial

12:09 and if the "good" properties of SHA-1 aren't needed then .hashCode is the right thing, I guess

12:11 jcromartie: opqdonut: well I already have a sha-1 function that can hash it's own output (byte arrays)

12:11 so it's well on it's way

12:12 opqdonut: I mean making the combine-hashes be robust against collisions etc

12:12 jcromartie: it's not a protocol but it's multimethods

12:12 opqdonut: what if the hash of, for example, a seq was the hash of the concatenation of all of it's members?

12:12 its

12:12 opqdonut: _that's_ fine

12:13 as long as you only hash once you're safe, I think

12:13 bpr: fliebel: I would recommend checking on the aleph google group, but it seems that 16-bit alignment could be achieved using finite-blocks

12:13 fliebel: jcromartie: you could have a look at how String does it

12:13 jcromartie: I mean

12:13 the hash of the concatenation of the hashes of its members :)

12:13 opqdonut: that's probably less fine

12:13 fliebel: bpr: aleph? for gloss?

12:13 opqdonut: but I guess my point is What Do You Want To Do?

12:13 jcromartie: like, (sha-1 (mapcat sha-1 some-vector))

12:13 bpr: well, the aleph group discusses gloss, lamina, and aleph

12:14 jcromartie: opqdonut: actually, I don't have a purpose for this yet :P

12:14 bpr: but the software library you'd be using would be gloss

12:14 jcromartie: I just started writing a sha-1 multimethod for streams, strings, files

12:14 cemerick: Is there a corollary to *e in Ruby/irb?

12:14 jcromartie: which I do have a use for

12:14 cemerick: $!

12:15 opqdonut: I mean, if you're doing something security-related, hashing hashes isn't okay a priori

12:15 if you just want to do content-based addressing or something, then it is

12:15 jcromartie: it's not security related

12:15 but maybe the Clojure/Java hash of the object is good enough?

12:15 I mean, is that supposed to be a perfect hash?

12:16 it's good enough for Clojure's comparison operators, right?

12:16 opqdonut: it's supposed to be a hash

12:16 :)

12:16 .hashCode tends to work well for hash tables in practice, for instance

12:16 jcromartie: but Clojure's ##(hash {:x 1 :y 2}) is decent

12:16 lazybot: ⇒ 2027824014

12:17 opqdonut: in general, if you combine hashing functions (i.e. first apply one, then the second), the resulting hash is as weak as the weaker of the hashing functions

12:18 but this is getting slightly academic. do whatever you want.

12:18 jcromartie: ##(map hash [(range 10) [0 1 2 3 4 5 6 7 8 9] '(0 1 2 3 4 5 6 7 8 9)])

12:18 lazybot: ⇒ (-1631921466 -1631921466 -1631921466)

12:19 jcromartie: anyway, I'm out of my league here... I don't have a specific need for this quite yet

12:19 I *do* have a need for quick polymorphic hashing of strings and streams

12:19 which I've got

12:19 so

12:19 off I go!

12:20 cemerick: jcromartie: Thanks :-)

12:20 similar, but doesn't persist outside of the rescue block, it seems.

12:20 jcromartie: hm

12:21 BTW cemerick I always keep this on hand when doing Ruby http://www.zenspider.com/Languages/Ruby/QuickRef.html

12:21 I don't know if it's out of date but it's usually very handy

12:22 cemerick: jcromartie: I think it's accurate. $! just seems to be reset once you clear the rescue block. Useful for catching all errors, I guess.

12:22 jcromartie: yeah

12:23 or on the REPL

12:23 I believe

12:23 or, not... never mind!

12:23 cemerick: heh :-)

12:23 seeing that reference page really drives home how perl-inspired ruby is

12:23 or, perl-influenced

12:25 jcromartie: $> << $!.to_s

12:25 cemerick: Of course, why didn't I think of that! :-P

12:25 `fogus: jcromartie: highly useful. Thanks!

12:26 jcromartie: actually just $> << $! is enough to print the message :P

12:26 yuck

12:26 cemerick: I still don't know what it does

12:26 eval'd to #<IO:0x100178b98>

12:27 jcromartie: it will return the output stream, but print the exception

12:28 * cemerick is so very, very happy that he never used ruby

12:28 * ejackson envies him

12:28 jkkramer: but it's so *easy*!

12:29 cemerick: No. No, it's not. :-)

12:29 ejackson: and its so FUN,FUN,FUN

12:29 jcromartie: hah

12:29 cemerick: My brain does not have a gem-shaped hole, it turns out.

12:29 jcromartie: I do whip up Ruby scripts to do stuff

12:29 build tasks, etc.

12:29 a messy language for messy projects

12:30 cgray: is it possible to show other people your solutions to problems on 4clojure?

12:30 jcromartie: I use Rake to run builds, DB migrations, and generate config files for a .NET web app

12:30 ejackson: hah, I've spent the last few days translating mathematica into matlab, you wanna talk messy with me.

12:30 jcromartie: heh yes

12:31 matlab is insane

12:31 ejackson: bring a mop buddy :)

12:31 jcromartie: it drove my wife to tears in school

12:31 and she did fine in C++

12:31 actually, no, that was tears too

12:31 but less tears

12:31 cemerick: ejackson: That sounds absolutely soul-crushing

12:31 ejackson: we

12:31 does what we must to pays the rent

12:32 i might get a reduction in rent if there is one less soul present, you think ?

12:34 jcromartie: ejackson: that's the opposite of how it usually works, isn't it?

12:34 ejackson: with various souls splitting the rent

12:34 ejackson: on a rent per soul basis, yes :)

12:37 i was especially tickled by being sortof forced to use a for loop, using i as the index, and then discovering that i was no longer sqrt(-1) for the rest of the surrounding scope. hahaha. keep eyes open in the dark forest of mutability.

12:39 TimMc: Assignment leads to mutation. Mutation leads to pointers. Pointers lead to suffering!

12:40 ejackson: ha ! yes indeed.

12:41 jcromartie: (inc TimMc)

12:41 (does that still work?)

12:41 TimMc: (from http://www.ccs.neu.edu/home/matthias/)

12:43 ejackson: its good to relearn your lessons from time to time. like playing scales. in this case on a keyboard of needles.

12:43 not that i'm whining :)

12:44 jcromartie: so

12:44 there's this debate over wether SHA1(SHA1(SHA1(... SHA1(x)))) is good enough right?

12:44 n times

12:45 for login purposes, I can just take the 500,000th hash of a password, which takes about a second on my machine

12:46 ejackson: best lest n approach infinity to be sure.

12:46 raek: jcromartie: git also uses some SHA alorithm for something that looks like what you're doing

12:46 jcromartie: so I just made cracking salted SHA-1 passwords half a million times slower

12:46 r

12:46 ight

12:46 ?

12:46 now this is the security realm

12:46 not the file content index realm

12:48 simard: is there a reader syntax for floats ? ie.: (type 0.5) evals to double, and 0.5f will not work

12:48 stuarthalloway: simard: clojure 1.3 does not use floats internally

12:49 simard: ok so I should use gl*d instead of gl*f by default then

12:49 (opengl)

12:50 stuarthalloway: btw, I like your book.

12:52 TimMc: jcromartie: bcrypt!

12:52 Why use a fast hash when you can use a slow one?

12:53 tolstoy: Read through the whole core api last night. Probably a good thing to do every other day while learning. Lots of stuff there I keep re-inventing!

12:54 But then I saw "seque". What's it about?

12:54 jcromartie: TimMc: why use a slow when when you can use a fast one many times?

12:54 tolstoy: I read http://clojuredocs.org/clojure_core/clojure.core/seque, but I'm not sure why seque is any different than lazy-seq or just list or something.

12:54 jcromartie: I really don't understand why (nth (iterate sha-1 x) 500000) isn't sufficient

12:54 I mean

12:54 am I missing something?

12:55 technomancy`: jcromartie: at the very least you're missing the fact that you're not cryptographically qualified to know whether you're missing something. =)

12:55 llasram: tolstoy: Realizes the backing seq in a different thread. Could allow parallelizing different steps of serial processing pipelines implemented in terms of lazy seqs

12:56 jcromartie: technomancy`: no, I know that

12:56 tolstoy: llasram: Ah. Doesn't say anything about an additional thread in the doc-string.

12:56 jcromartie: technomancy`: I'd like to know what's going on though

12:57 tolstoy: llasram: Ah, I see, "in the background" is the clue.

12:58 chewbranca: I find it funny that people are absolutely freaking out that he's using iterated sha over bycrypt, when the really security issue at hand, is don't make your database public..

12:59 technomancy`: weeeeeell it never hurts to have multiple lines of defense

12:59 pjstadig: it doesn't?

12:59 * pjstadig rethinks his entire philosophy

13:00 llasram: tolstoy: Yeah, might be obscure. If found it crawling through source, so I saw how it used an agent :-)

13:01 chewbranca: absolutely, iterated sha is another line of defense, but my point is that the people responding are acting like its going to be the end of the world that he's not using bcrypt; just too much troll bike shedding for my tastes

13:01 tolstoy: llasram: Might be a cool way to wrap a rabbitmq-consumer.

13:04 jcromartie: yeah, pretty much chewbranca

13:04 cemerick: yikes, switching to a namespace stomps all over any vars whose names match those usually referred in from clojure.repl

13:05 technomancy`: well, the only reason he was inventing his own crypto scheme over bcrypt was to avoid pulling in another dependency.

13:06 raek: cemerick: are you using 'ns' instead of 'in-ns'?

13:07 cemerick: raek: no

13:07 I wonder if it has always been thus

13:13 stuarthalloway: cemerick: has been thus since clojure.repl was added

13:13 rhickey finds it irritating too, but the semantics are consistent. There is no stomping

13:14 jcromartie: https://gist.github.com/3bac44cdcdbb27fbb75b

13:14 stuarthalloway: the goal of having the repl vars at hand competes with the goal of getting the repl vars out of core

13:14 jweiss: does slime-who-calls work well for emacs users here? For me, i get different results depending on which reference i run it from (even if they're calls to the same fn)

13:15 jcromartie: (depends on an unlisted sha-1 function but... you get the idea)

13:15 technomancy`: jweiss: the heuristic it uses is very naive. I wouldn't trust it much over a fancy jar-aware grep.

13:15 jcromartie: that's bcrypt, basically

13:16 jweiss: technomancy`: if you want to change a fn's arguments, what do you use to find references?

13:16 jcromartie: OK I've gotta stop

13:16 I'm out of my depth and this is silly

13:16 cemerick: stuarthalloway: If my source file's namespace defines doc, I can load it, and evaluate evaluate somens/doc. If I switch to somens, doc and somens/doc both resolve to repl/doc. Seems like complete stompage.

13:16 jweiss: just plain grep (even though that gets false positives)?

13:16 technomancy`: jweiss: yeah

13:16 jweiss: ok

13:17 technomancy`: it occurs to me that the new dynamicity changes require functions to store references to the defns they use to support redef

13:17 which could possibly be leveraged to create badass refactorisms

13:18 * cemerick read that as refactorgasms

13:18 hiredman: technomancy`: hmmm?

13:19 nickmbailey: that might be the best word i've ever heard

13:19 technomancy`: cemerick: maybe that too; the possibilities are endless.

13:19 hiredman: well, each downstream consumer of a non-dynamic defn must be updated when the defn is recompiled, yes?

13:19 hiredman: no

13:20 that's not how non-dynamic vars work

13:20 cemerick: technomancy`: you're thinking of the defunct ^:static

13:20 hiredman: it just removes the need to check for a threadlocal binding

13:20 technomancy`: cemerick: no, this was from the conj

13:21 something about keeping track in a static field that hotspot inlines better than standard var lookup

13:21 hiredman: no, you are mixing it up

13:22 if a var is not dynamic, the compiler emits a call to getRawRoot on the var

13:24 vars are always stored in the "constant pool" of a fn

13:24 (a bunch of static fields)

13:24 and have been since at least 1.2

13:24 technomancy`: hiredman: ok, so you're saying this isn't necessarily new

13:24 gotcha

13:25 hiredman: javap mode some aot'ed fns

13:25 technomancy`: either way doesn't it seem ripe for a refactoring tool?

13:26 hiredman: I dunno, what kind of refactorings?

13:27 technomancy`: I was thinking specifically of arglist changes like jweiss was doing

13:29 hiredman: technomancy`: don't see how having a list of vars works with arglists

13:29 technomancy`: not necessarily automated refactoring, but "I'm gonna change this defn; please to identify the spots that will need to be updated."

13:29 though things like the removal of an argument would be trivial to automate

13:30 jweiss: i would think this should be possible today in theory, since slime-edit-definition works reliably

13:31 but then again my theory might require every symbol to be analyzed

13:33 simard: is it possible to use (apply) on a static class function ?

13:34 jweiss: simard: you mean static method?

13:34 simard: jweiss: yes

13:34 jweiss: i believe the answer there is no

13:35 methods aren't fns

13:35 someone with better java-integration fu than me can tell you the way it's done :)

13:35 technomancy`: is it just me, or is the number of hits per page on lein search too small?

13:37 stuarthalloway: cemerick: I am not seeing the stompage you report. Is it possible that some tool is trying to help you by automatically using clojure.repl on your behalf

13:37 sounds like the kind of convenience that technomancy might add :-)

13:38 technomancy`: what's that? cemerick switched to Emacs?

13:38 * technomancy` rushes to post on hacker news

13:38 stuarthalloway: technomancy: not that I know of, just poking fun

13:39 technomancy`: oh you know me; I love a good unsubstantiated rumour.

13:40 jcromartie: oh look http://www.infoworld.com/d/application-development/microsofts-roslyn-reinventing-the-compiler-we-know-it-176671

13:41 a REPL

13:41 jweiss: i saw that ^ didn't sound that revolutionary to me either

13:41 jcromartie: next year it will be persistent data types

13:41 or STM

13:42 technomancy`: nah they already tried an STM and couldn't make it work

13:44 tncardoso: why 4 clojure block nth? http://www.4clojure.com/problem/21

13:44 jweiss: i wonder when will be the last time someone claims as new something lisp has had for decades... probably still decades away

13:46 jcromartie: tncardoso: to make you implement nth yourself :)

13:46 tncardoso: jcromartie: ok :)

13:47 jcromartie: the message is "nth is bad!", i thought it was a bad practice

13:47 srid: that problem doesn't block nthnext though

13:47 then, a solution could be: #(first (nthnext % %2))

13:48 or, #(first (drop %2 %))

13:53 llasram: Huh. Apparently running `pmap' over a chunked seq causes futures for the operations to be realized 32 at a time, no matter how many CPUs you have

13:53 Well, I guess 64 at a time if you have >32 CPUs, etc

13:54 I wonder if that would be considered a bug?

13:54 dnolen: llasram: you can defeat chunking by wrapping in a lazy-seq that enforces one at a time.

13:54 llasram: dnolen: Oh, sure. I've got my `seq1' handy

13:55 dnolen: Was just surprised pmap didn't do it implicitly.

13:56 dnolen: llasram: worth bringing up on the clojure-dev ML

13:56 llasram: kk. Will-do

14:12 TimMc: jweiss: Never.

14:13 jweiss: TimMc: you may be right

14:21 TimMc: Maybe the average age of LISP-reinventors will decrease. :-)

14:22 amalloy: TimMc: increase, as time progresses and the same things are reinvented

14:29 bpr: Can someone tell me what I'm doing wrong: https://gist.github.com/1304564

14:29 jweiss: bpr - you can't type hint as bytes

14:29 bpr: the last line is the compiler's error message

14:30 what's the hint?

14:30 i thought ^(type)s meant an array of that type

14:30 jweiss: oh maybe i'm wrong, but that didn't look right to me

14:31 yeah i guess that is correct

14:32 TimMc: There is a bytes function...

14:32 dnolen: ,(class (byte-array))

14:32 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$byte-array>

14:32 dnolen: ,(class (byte-array []))

14:32 clojurebot: [B

14:32 dnolen: ^"[B"

14:32 is what you want

14:32 bpr: oh rly?

14:33 thanks!

14:33 dnolen: np

14:33 TimMc: ,(prn (class (into-array ["foo"])))

14:33 clojurebot: [Ljava.lang.String;

14:33 TimMc: &(prn (class (into-array ["foo"])))

14:33 lazybot: ⇒ [Ljava.lang.String; nil

14:35 TimMc: ,(.getName (class (into-array ["foo"]))) there we go

14:35 clojurebot: "[Ljava.lang.String;"

14:35 bpr: hrm, now the compiler says: java.lang.NoClassDefFoundError: java/lang/[B

14:36 TimMc: ,(doc shorts)

14:36 clojurebot: "([xs]); Casts to shorts[]"

14:37 TimMc: bpr: You didn't put quotes around it.

14:38 bpr: yes i did

14:38 TimMc: hmmm...

14:38 You're right... that's a different error!

14:39 ,^"[B" (byte-array 0)

14:39 clojurebot: #<byte[] [B@2ad3e6>

14:39 TimMc: &^"[B" (byte-array 0)

14:39 lazybot: ⇒ #<byte[] [B@14aa3df>

14:39 bpr: are clojurebot and lazybot running 1.3?

14:39 i'm using 1.2.1

14:39 TimMc: One of each.

14:40 bpr: ah

14:40 TimMc: ,*clojure-version* ##*clojure-version*

14:40 clojurebot: {:major 1, :minor 3, :incremental 0, :qualifier nil}

14:40 TimMc: &*clojure-version*

14:40 lazybot: ⇒ {:major 1, :minor 2, :incremental 0, :qualifier ""}

14:44 TimMc: bpr: I see, it only errors once you try to reify.

14:45 bpr: http://dev.clojure.org/jira/browse/CLJ-737

14:46 bsod1: anyone knows why while editing clojure files with vimclojure, `o` in normal mode takes too much time? A<enter> is instant, but `o` takes about a second on my machine?

14:48 TimMc: bpr: Fails in 1.2.1, works in 1.3.

14:48 bpr: TimMc: ok. thanks

14:57 ghiu: hi, i defined *db* like this (def *db* {:classname "org.sqlite.JDBC" :subprotocol "sqlite" :subname "/Users/gu/dev/org.github.pistacchio.deviantchecker/resources/data/data.sqlite"}) the file exists and has the correct table

14:57 when i try to access it like this (sql/with-connection (sql/with-query-results res ["select * from galleries"] (into [] res)))

14:58 this is what i get

14:58 java.lang.Exception: no current database connection (NO_SOURCE_FILE:0)

14:58 how come it can't find it?

14:58 amalloy: TimMc: lazybot's ## is a bit quirky (on purpose) - it only activates if the thing you're trying to eval is a collection of some kind, like ##(list *clojure-version*)

14:58 lazybot: ⇒ ({:major 1, :minor 2, :incremental 0, :qualifier ""})

14:59 amalloy: that is, if the form you want to eval is a collection. the eventual value doesn't have to be. so eg ##'1 works because (quote 1) is a collection, but ##2 doesn't

14:59 lazybot: ⇒ 1

15:00 amalloy: this is basically to prevent him from annoying people who are trying to talk about ##java or whatever

15:05 ghiu: i don't think just defining *db* does anything. you need to pass it to some sql function/macro, probably sql/with-db or sql/with-connection or something

15:05 zackmaril: Let's say I am using clojure-jack-in and evaling a file. If I am trying to :use clojure.contrib.math and I am getting an class path error, what could be going wrong?

15:07 raek: zackmaril: and you have added contrib as a dependency in project.clj?

15:08 zackmaril: Yes. Is this right? [org.clojure/clojure-contrib "1.2.0"]

15:11 raek: zackmaril: yes. have you run lein deps since you added that?

15:11 (and restarted the swank server)

15:11 zackmaril: Ah! That could be key

15:12 That did it!

15:12 Thank you

15:18 ghiu: amalloy: i use with-connection, if you read a couple of rows after the definition :D

15:18 amalloy: ghiu: you didn't pass *db* to with-connection

15:19 ghiu: oh, you're right, but i just past the wrong line, this is the one still not working: (sql/with-connection *db* (sql/with-query-results res ["select * from galleries"] (into [] res)))

15:20 gar3thjon3s: has anyone noticed that the *slime-repl* buffer does get created in emacs-starter-kit v2 and emacs 24? (im using outside of a lein project, starting ~/.lein/bin/swank-clojure and doing M-x slime-connect in emacs)

15:21 *does not

15:21 seancorfield: quick Q about *ns* - if i'm in a function inside ns foo.bar should I expect *ns* to be foo.bar or the namespace from which the function is called?

15:23 chouser: I'm not sure *ns* has any real meaning at runtime

15:23 I think It's the namespace being compiled at the moment, which is the current REPL namespace when you're in a REPL.

15:24 hiredman: seancorfield: it will most likely be clojure.core

15:24 (when running in production)

15:26 seancorfield: a quick repl experiment shows it's the namespace that originated the "request"... so, is there something that yields the actual "current" (compiled) namespace?

15:27 opqdonut: you can get it load-time

15:28 seancorfield: i'm using tools.logging and i want to pass in the "current" namespace and i was hoping not to have to hardcode it in each namespace...

15:30 i can put (def ^:private my-ns *ns*) into each namespace and then (log my-ns my-data) i guess... is this not a use case folks have run into? just curious

15:31 opqdonut: (defmacro log [thing] `(really-log ~*ns* ~thing))

15:31 or something to that effect

15:44 simard: hum, what is reify actually used for ?

15:45 jweiss: simard: creates a one-off impl of an interface

15:46 seancorfield: i've used it to create an instance of java.io.FilenameFilter that matches a given regex

15:47 https://gist.github.com/1304756

16:46 bendlas: Hey, do you know a good way to kill a running embedded swank server, without restarting the JVM?

17:32 jcromartie: WTF is Gosu

17:32 I mean, obviously, a language

17:32 Raynes: A programming language with hostile creators.

17:33 jcromartie: weird

17:34 yeah "not lisp" isn't usually part of a feature matrix

17:34 a

17:34 and when I look at Gosu code... it just looks like Java without semicolons

17:34 technomancy`: it shouldn't be too surprising that there are all these languages attempting to do nothing more than be slightly better than java

17:34 considering "better than java" is so easy a goal to attain

17:36 fliebel: I'm aiming for more interesting than dart.

17:36 Raynes: Dart is as interesting as a tracfone.

17:36 fliebel: w/me googles

17:36 jcromartie: ah, apparently Gosu stems from some insurance industry software company?

17:37 it's about that exciting

17:37 Dart make me cringe

17:37 Raynes: Tracfone is a prepaid wireless service with plastic feature phones from the 90s.

17:37 jcromartie: they made JavaScript worse

17:38 fliebel: Raynes: Check my phone: http://www.excellentmobiles.com/images/philips_files/philips162_b.jpg real dutch.

17:38 Raynes: Yeha, those kinds of phones.

17:39 yeah*

17:39 jcromartie: as far as I can tell Dart adds type checking, the "class" keyword, and importing libraries

17:39 fliebel: Raynes: Awesome!

17:40 technomancy`: next time I buy a phone I am totally visiting excellentmobiles.com

17:41 fliebel: technomancy`: You'll love these: https://www.johnsphones.com/

17:41 technomancy`: classy

17:42 fliebel: How did we end up talking about phones...

17:43 You can write clojure on the johnsphone btw, booklet and pencil included.

17:44 Raynes: That thing is $100?

17:44 Seriously? Psh.

17:44 technomancy`: well, it doesn't exactly have any competition.

17:44 fliebel: only the gold one

17:47 * fliebel is going to record a Clojure video gitorial, but sleep first

17:49 jcromartie: I guess there's no way to read a stream twice without loading it all into memory

17:49 fliebel: jcromartie: Why do you read it twice?

17:50 jcromartie: to copy a file and get its SHA-1

17:50 but I have a solution, actually

17:50 DigestInputStream

17:50 it updates the message digest as the stream is read

17:51 hm

17:51 never mind, there's really not a good way to do this, since I need the digest before I write the file, and there's no native way to move files in Java

17:51 TimMc: File is named after its digest?

17:52 jcromartie: yes

17:52 TimMc: hmm

17:52 fliebel: jcromartie: I thought Nio fixed that?

17:52 jcromartie: maybe?

17:52 I'm using clojure.java.io

17:52 TimMc: jcromartie: c.j.io doesn't have a file mover?

17:53 jcromartie: it's not a native OS move (i.e. rename)

17:53 it has to copy the data

17:53 jodaro: nice

17:53 the repl is a great way to spend time

17:53 i just played around with -> vs. comp vs. juxt for a while

17:53 TimMc: jcromartie: That's kind of terrible.

17:53 jcromartie: that's just the JVM

17:54 it implements a very small set of features over files

17:54 input and output streams at the core

17:54 exists, creation, mkdir, etc.

17:54 but no copy or move

17:54 TimMc: jcromartie: File.renameTo(File)

17:54 jcromartie: wut

17:55 DERP!

17:55 hiredman: there exists a patch to make copy use nio's FileChannel's transferTo for copy

17:55 jcromartie: how did I miss that

17:55 TimMc: :-)

17:55 jcromartie: :P

17:55 TimMc: c.j.io doesn't have it, but I guess it only fills in gaps in j.io

17:55 jcromartie: OK so I can use the digest stream to write to a temp file, get the final digest, then rename the temp file after the digest

17:55 perfect

17:56 TimMc: As long as you never try to write to the same temp file from multiple threads.

17:57 File/createTempFile with the desired directory

17:57 dnolen: ok being able to remotely debug mobile WebKit devices w/ browser REPL - AWESOME

17:58 TimMc: When do we get FireClj?

17:58 FijreBug

17:58 Raynes: I'd kill myself if someone named a project that.

17:58 Seriously. I've got the rope ready.

17:58 amalloy: TimMc: just FjreBug

17:58 TimMc: :-(

17:58 haha

17:59 amalloy: the J is...i dunno, swedish or something

17:59 scottj: you have the ropjure ready?

17:59 Raynes: fjrebug is one thing. fijrebug is another.

17:59 TimMc: Motto: "You can't spell FijreBug without JRE"

18:01 ...and I'm going home.

18:02 amalloy: TimMc: keep an eye out for rabid "fans" who want to dismember you

18:02 TimMc: ?

18:05 amalloy: big fans of fijrebug

18:05 i was implying that someone here (probably Raynes) would follow you home with evil intent

18:06 scottj: dnolen: you mentioned debugging js on phones is pain, have you seen http://phonegap.github.com/weinre/

18:09 actually looks to be just a repl not a real debugger

18:13 dnolen: scottj: I have not seen that! Thanks.

18:21 sdbo: Hi, does anyone know a trick to ensure read-string reads a string inside some dynamically evaluated namespace? I want to execute serialized code on a different machine to implement a work queue.

18:34 tolstoy: Hm. Autodoc broken for lein + clojure 1.3? Alas.

19:57 yy: #haskell

19:57 oops wrong window

19:58 technomancy_: ~guards

19:58 clojurebot: SEIZE HIM!

20:29 technomancy_: dakrone: clj-http doesn't have any built-in support for trusting self-signed certs, does it?

22:03 devn: If clojure fails to succeed I think I will probably just quit programming.

22:07 duck1123: devn: what do you consider succeeding? Hasn't it already?

22:08 Even if it's not the #1 language, it's still fairly successful by this point.

22:14 dnolen: devn: ha, you still got Racket and Haskell, could be worse.

22:15 brehaut: im not frightened by the languages that historically have succeeded. you can keep your C++ thanks

22:15 s/not/more/

22:17 dnolen: devn: but honestly, I think the future of Clojure is really brightened with ClojureScript. It's Clojure's trump card over all the other popular functional langs.

22:18 alandipert: also, people will be solving hard problems on the jvm until the end of time. and when they call us, we have clojure

22:19 brehaut: dnolen: have you seen websharper for F#?

22:20 dnolen: brehaut: I have not, is it any good?

22:20 brehaut: dnolen: ive not used it, but it does look impressive

22:21 you can write your javascript in F# with just a handful of annotations

22:21 http://www.websharper.com/samples/HelloWorld

22:22 dnolen: brehaut: does it have a browser REPL? ;)

22:22 scottj: opa is also interesting, as an ml that works on server and web client, though license is questionable

22:23 dnolen: scottj: anything designed specifically for the web is doomed.

22:23 brehaut: dnolen: F# has a nice repl, no idea how websharper integrates with it.

22:24 dnolen: i think clojurescript is more likely to be successful, im just pointing out a tool that does look like a reasonable choice

22:24 dnolen: brehaut: I don't doubt that. Devil is in the details of course.

22:25 brehaut: definately

22:25 and web has a lot of details

22:25 dnolen: argh

22:26 I actually got my first excuse to use ClojureScript today - debugging an HTML5 app locked/trapped inside a iOS WebKitView

22:26 browser REPL to the rescue

22:27 brehaut: dnolen: http://www.webkit.org/blog/1620/webkit-remote-debugging/

22:28 however i think you may need a ios dev account to actually make use of it in the iphone

22:28 dnolen: brehaut: heh yeah I'm aware of that, more work to setup than browser REPL :)

22:28 brehaut: hah yeah :)

22:29 alandipert: dnolen: sweet!

23:05 maxalwings: New to clojure, I am using lein swank and I am getting this exception | http://pastebin.com/bkhQW7YB

23:05 Help!

23:08 I really could use your help.

23:49 scottj: maxalwings: when you run lein swank?

Logging service provided by n01se.net