#clojure log - Feb 01 2011

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

0:02 amalloy: since it sounds like you just want the handy (for) bindings

0:29 arohner: amalloy: thanks for the hint. I ended up with (dorun (apply pcalls (for [foo bar] #(body...)))

0:29 I needed to use #() rather than constantly, because constantly is a fn, so it evaluated its body

0:30 amalloy: sure, constantly was just an example

2:13 sritchie: hey all -- does anyone have any advice on how to read floats out of a binary file with clojure?

2:14 java's DataInputStream is assuming that the file was written using floatToIntBits, which isn't the case

2:21 amalloy: sritchie: floats, or doubles?

2:22 sritchie: floats

2:22 I have an array I usually read in python, using numpy's numpy.fromfile method

2:22 I'm trying to use a datainputstream in java, but i think it's reading the bytes in backwards

2:22 or, rather, opposite of what python does

2:24 amalloy: sritchie: see the docs at http://www.scipy.org/Numpy_Example_List_With_Doc#fromfile

2:24 they say not to rely on tofile..fromfile to store data as they will be stored in a platform-dependent way

2:25 sritchie: yeah, that makes sense --

2:25 I'm actually reading this data set --

2:25 http://iridl.ldeo.columbia.edu/SOURCES/.NOAA/.NCEP/.CPC/.PRECL/.dataset_documentation.html

2:26 I just happen to have some working python code that uses fromfile

2:26 I think java is just reading the bytes in backwards, from what python does

2:26 amalloy: so my guess would be that numpy is storing them in whatever order your processor happens to be using while java is using network byte order

2:27 sritchie: amalloy: do you know of any way I could specify a different byte order? I have to live with this data set, unfortunately

2:27 amalloy: sritchie: flip the bits around yourself

2:29 sritchie: ah, okay, i'll just use to-byte-array, then Float.intBitsToFloat(bits);

2:30 amalloy: sritchie: that will be just as backwards since that's what datainput is doing already

2:30 sritchie: sorry, I meant I'll take four bytes at a time, flip them,

2:30 and then feed them in to intBitsToFloat

2:30 amalloy: right, that's probably the way to go

2:31 sritchie: great, thanks

2:32 amalloy: &(Integer/toHexString (Float/floatToIntBits (float 66.6)))

2:32 sexpbot: ⟹ "42853333"

2:33 amalloy: &(Integer/toHexString (Float/floatToIntBits (float 7.5))) is probably more useful :P

2:33 sexpbot: ⟹ "40f00000"

2:34 amalloy: sritchie: ^ is something to aim for in your bit-fiddling if it turns out to be more interesting than just reversing all four bytes

2:34 sritchie: yes, that's really useful

2:35 amalloy: the next step is converting bytes from a byte array into a hex string

2:37 amalloy: sritchie: plenty of implementations of that exist, but why do you need to?

2:38 sritchie: amalloy: I've got a byte array, and I was thinking that I'd need to take 4 bytes off of the front, and then combine them into a hex string to feed into intbitstofloat

2:38 benreesman: anyone had luck using ac-slime with swank-clojure?

2:38 amalloy: intbitstofloat doesn't want a hex string, though

2:38 it wants an int

2:40 and while i'm sure better solutions exist, i wrote https://github.com/amalloy/bit-packer for fun a while back and it would do what you want

2:41 (unpack your-byte-array 256) will do the trick, if the bytes are in the right order (as mentioned in the readme)

2:43 sritchie: this assumes big endian, right?

2:43 tomoj: you have a float, and then what?

2:44 amalloy: i can never remember which "end" big-endian refers to. it assumes LSB first

2:44 sritchie: I'm unpacking this binary file into 12 360x720 pixel arrays, where the float on each pixel is mm of rainfall in that .5 degree square on the earth's surface

2:44 amalloy: yeah, I think it assumes what java assumes -- this obnoxious binary file has it backwards

2:44 amalloy: sritchie: so? (reverse)

2:44 tomoj: oh

2:45 sritchie: oh, reverse before the unpack then after would do the trick, wouldn't it

2:45 amalloy: um, you shouldn't have to reverse after...the whole point is that the bits are in the wrong order

2:46 &(let [bytes (range 12)] (map reverse (partition 4 bytes)))

2:46 sexpbot: ⟹ ((3 2 1 0) (7 6 5 4) (11 10 9 8))

2:47 amalloy: and if you had an unpack function, you could map (comp unpack reverse)

2:47 brehaut: if you're looking for reasons to cry, i made take-randnth actually lazy at https://gist.github.com/805546

2:48 sritchie: amalloy: ah. it's late... I was thinking that each float was reversed,

2:48 but the order of the whole thing was correct

2:48 amalloy: each byte, you mean?

2:49 sritchie: each group of four bytes

2:49 that each float, when converted to bytes, was serialized differently in java vs whatever wrote this particular binary file

2:49 amalloy: yes, that is the assumption under which we are operating

2:50 suppose that java writes its float as 0x12345678. then, if endian-ness is the only problem, numpy is probably writing it as 0x78563412

2:50 sritchie: well, my first groups of four bytes, probably the first few thousands floats, are (0 -64 121 -60)

2:51 that matches python, if I set numpy to byte format

2:51 amalloy: and what float does numpy think that represents?

2:51 sritchie: -999

2:55 might be time to sleep on this one

2:55 I feel like that's NaN

2:55 amalloy: sritchie: well first of all you want to stop dealing with negative numbers. -64 is, i think, 0xC0, or 192

2:55 sritchie: java's reading it as 1.7676097E-38

2:56 amalloy: but i could def be wrong there. it's been a long time since i looked at how two's complement works :P

2:57 sritchie: just (Integer/toHexString (.readInt datainput))

2:58 that will show you what order it's reading the bytes in

2:58 then you will know how to reorder them

3:00 sritchie: c079c4

3:00 amalloy: hey, i was right about 0xc0, at least

3:00 sritchie: yup!

3:01 might be time to sleep on this

3:02 amalloy: yeah, i've got to sleep too

3:02 sritchie: thanks for your help -- this seems simple, I'm just exhausted

3:02 I'll play with the numpy representation tomorrow and this, and see what I find

3:02 amalloy: good luck

3:02 sritchie: thanks, man

3:24 brehaut: amalloy: belated :'(

3:24 amalloy: brehaut: yeah, i'm really trying hard to find a non-awful way to write this

3:25 brehaut: a real unfoldl might help a bunch i think

3:25 amalloy: brehaut: yeah, i'm writing it with unfold as we speak

3:25 it's shorter but arguably more complicated

3:25 brehaut: why isnt unfold in the core?

3:26 amalloy: brehaut: beats me

3:27 brehaut: im sure theres a good reason though

3:28 amalloy: brehaut: https://gist.github.com/805583v with unfold

3:28 brehaut: huh. github is 404ing on that

3:28 amalloy: oh

3:28 https://gist.github.com/805583

3:28 i accidentally pasted a v at the end there

3:29 brehaut: huh. done? makes a bunch of sense in the absense of proper maybe

3:29 amalloy: brehaut: what?

3:30 brehaut: oh sorry. in unfold

3:30 im more familiar with the haskell version, where the next fn returns a maybe

3:30 amalloy: right, i know what done? you're referring to, but i don't see the point youo're making

3:31 brehaut: i implemented http://en.wikipedia.org/wiki/Unfold_%28higher-order_function%29#Anamorphisms_on_lists

3:31 i'm not very familiar with haskell, but it looks like that's basically (defn ana [unspool finished x])

3:32 brehaut: amalloy: http://hackage.haskell.org/packages/archive/containers/latest/doc/html/Data-Sequence.html#v:unfoldl thats the one in haskell

3:33 sorry that was an epic sidetrack

3:34 amalloy: brehaut: ugh, i can't read these curried type definitions

3:34 it's worse than lisp's dang parentheses :)

3:34 brehaut: haha

3:35 * amalloy chooses to acknowledge his prejudices but embrace them anyway

3:35 brehaut: haskells' precedence rules and ops are a head trip to start with

3:38 amalloy: anyway i'm not sure unfold makes the whole thing that much nicer

3:40 brehaut: yeah apparently not

5:25 clgv: I try to compile my clojure library (code without a main method) with leiningen but it does not include any implementation file. what might I do wrong?

6:20 fliebel: morning

6:20 ejackson: wotcha

6:23 clgv: morning

6:24 fliebel: clgv: Hi, I just read your message… I really thought I got it, with 4 and 6

6:25 clgv: fliebel: you can try to improve it by knowing the solution. as soon as it drops out, your criterion has an error ;)

6:26 fliebel: maybe I try a clojure solution next weekend ;)

6:27 fliebel: Well, I would rather like to know *what* makes my solution incorrect. In my opinion, it fits the constraints and the conversation perfectly.

6:29 clgv: hmm that's not easy since I have to go throught the argumentation and have a look when it drops out ;)

6:30 fliebel: clgv: Good, I'll try to find a way to figure out your solution, and then verify both min and the 'official' solution.

6:31 clgv: ah I got the problem

6:31 4+6=10=2*5

6:32 uhm wait, I might have to reconsider.

6:40 fliebel: amalloy_: ping

6:43 why doesn't rand-int take a start? ##(doc rand-int)

6:43 sexpbot: ⟹ "([n]); Returns a random integer between 0 (inclusive) and n (exclusive)."

6:52 gfrlog: ,(let [fliebels-rand-int (fn [a b] (+ a (rand-int (- b a))))] (fliebels-rand-int 10 12))

6:52 clojurebot: 11

6:54 fliebel: gfrlog: I figured that out already, but I wonder why something that useful and simple is not in core.

6:54 &(source rand-int)

6:54 sexpbot: java.lang.Exception: Unable to resolve symbol: source in this context

6:56 raek: this is bad: http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/

6:56 affects clojure too

6:57 fliebel: raek: I figured that… I was about to try some other runtimes…

7:15 clgv: raek: oh thats suprising and will punch all those guys gloating about php in the face. bad incident for java ;)

7:22 r0man: technomancy: ping!

7:39 gfrlog: fliebel: Yeah, I agree.

7:42 ,(let [map-from-fn (fn [f ks] (into {} (map (juxt identity f) ks)))] (map-from-fn inc [7 9 12]))

7:42 clojurebot: {7 8, 9 10, 12 13}

7:42 Licenser: aloa

7:43 fliebel: Licenser: hi

7:49 gfrlog: What about functions taking multiple arguments?

8:51 chouser: Yet another reason to use rationals instead of floating points

8:58 gfrlog: fliebel: to be the keys of a map, they'd have to be wrapped in a vector anyhow. So I think that would still work.

9:06 robzor: have you guy seen this? works in clojure as well

9:06 http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/

9:07 (Double/parseDouble "2.2250738585072012e-308") goes in to an infinite loop

9:07 clgv: did you try that one on sexpbot already? ;)

9:08 robzor: uhm

9:08 ok

9:08 ,(Double/parseDouble "2.2250738585072012e-308")

9:08 clojurebot: Execution Timed Out

9:08 chouser: you don't even have to work that hard. what do you thing the reader does?

9:08 robzor: hurray for sandboxing

9:08 clgv: ok safe programmed ;)

9:08 chouser: ,2.2250738585072012e-308

9:08 clojurebot: Execution Timed Out

9:08 clgv: ,2.2250738585072011e-308

9:08 clojurebot: 2.225073858507201E-308

9:09 clgv: ,2.2250738585072013e-308

9:09 clojurebot: 2.2250738585072014E-308

9:09 robzor: if you look in the addendum of the blog i just linked, there's some other numbers

9:09 cemerick: Those evaluations are timing out from being reported, but I suspect the relevant worker threads in the execution pool will spin until hiredman bounces the bot.

9:09 chouser: you don't think he kills the thread?

9:09 cemerick: (unless they're being .stop'ped)

9:10 chouser: *dangerous* ;-)

9:10 chouser: yep

9:10 clgv: would be really bad style if he reports timeouts but doesnt kill the execution

9:10 cemerick: clgv: a thread's execution cannot safely be halted on the JVM

9:10 robzor: "something went wrong but i'm not going to bother you with that"

9:11 clgv: cemerick: it doesnt have to be safely if it's timeout has been reached anyway. brutal killing will suffice ;)

9:12 cemerick: clgv: that depends on what global resources the thread in question is touching at the time of the .stop

9:12 chouser: the question is, would it be desriable and possible to add a check to Clojure's reader to avoid passing strings that trigger that bug on to parseDouble

9:12 Fossi: that's just hiding the real problem

9:12 so i'd say no

9:13 chouser: But if it means Clojure programs can work more robustly until the JVM is fixed, is that not a win?

9:13 * cemerick hopes people aren't using the reader on untrusted user input just to parse numbers

9:13 robzor: would oracle fix this all the way back to 1.5?

9:13 Fossi: afaik there might also be a lot of other numbers which cause this bug

9:13 the one being published is just an example of what i guess might be a bigger problem

9:14 chouser: cemerick: if they are, we could save them. If they're using parseDouble directly, we can't help.

9:14 Fossi: then again i haven't checked the code

9:14 chouser: oh, it's already fixed in PHP.

9:15 robzor: chouser: yes, but how many servers out there are still running an ancient version?

9:16 Fossi: i wonder how often people even have input fields that get converted to a double

9:17 something like clojure might be a little more "vulnerable", if people really use the reader

9:18 then again as cemerick said it's prolly not such a good idea anyway

9:24 AWizzArd: cemerick: *lol*

9:25 cemerick: AWizzArd: ?

9:26 AWizzArd: cemerick: what you said 12 minutes ago. Just sounded funny :)

9:26 cemerick: ah. :-)

10:42 sritchie: hey all -- I've written a multimethod to convert various types of arguments into a little-endian HeapByteBuffer, which I'm using as a float array. currently, two of the defmethods change an argument slightly and call the multimethod again -- is there a more idiomatic way to do this?

10:42 https://gist.github.com/806027

10:42 there are the functions in question

10:44 nurv101: I have a question to the room

10:44 is it possible to create a lisp closure in clojure?

10:55 zvrba: are there block comments in clojure?

10:55 tonyl: (comment )

10:56 but anything inside comment has to be valid forms

10:56 zvrba: ok, that's fine

11:10 shortlord: I am using sets of size 1 and 2 to represent different kinds of things (a set with 1 element being a single node and a set with 2 elements being a line between these 2 nodes). Now I often have to implement different method behaviours for single nodes and lines. I could always pass the used set as an argument and then use (case (count my-set)) to distinguish the behaviour or even use a multimethod with count as a dispatch func

11:10 tion, but I guess it would be better to pass the elements of the sets as single argument and then use arity overloading to define the behaviour, right?

11:11 It would have the disadvantage that I'd have to convert between the set representation used in the datastructure and the call to the method which expect a different number of arguments, but that's still the more idiomatic clojure code, isn't it?

11:13 zvrba: that sounds like a lot of overhead

11:13 how do you store those sets_

11:14 shortlord: zvrba: in a map. The sets are the keys and the vals are certain attributes of these nodes and lines

11:14 zvrba: uh

11:14 shortlord: performance is not an issue, the maximum number of nodes is 54 and the maximum number of lines is 71

11:15 zvrba: but how would you have done it instead?

11:15 gfrlog: why do you have a set of 1 element instead of just the element?

11:15 zvrba: ah, ok then

11:16 gfrlog: shortlord: also why not store the nodes and lines separately?

11:16 zvrba: shortlord: or, why store nodes at all?

11:16 do you have isolated nodes?

11:17 shortlord: otherwise, depends on the size of the problem. there are many different structures to represent graphs.

11:17 shortlord: for example, use a map where a key is the node and the value is either the other node of the line, or nil if it's an isolated node.

11:17 shortlord: gfrlog: I had them separated before, I might have been quite a good idea after all ;)

11:18 gfrlog: shortlord: yeah; without knowing what you're doing, I would think it'd be easier to manually treat them the same when that comes up then to have to manually pull them apart

11:18 zvrba: on a larger scale, instantiating a set for each edge/node seems like a lot of overhead.

11:18 shortlord: zvrba: yes, true. I guess I'll have to think about my datastructure a bit more

11:18 gfrlog: if that makes sens

11:18 zvrba: (space overhead)

11:18 gfrlog: sets are nice for edges when comparing equality; but there's probably a more performant option

11:19 shortlord: gfrlog: yes, the idea was to treat them equally in a number of situations, but these situations turned out to be a bit different, I guess I might as well handle them differently again

11:20 gfrlog: (concat edges nodes) is easier than writing multimethods

11:28 ,(let [evens (iterate #(+ 2 %) 0), odds (iterate #(+ 2 %) 1)] (take 20 (concat evens odds)))

11:28 clojurebot: (0 2 4 6 8 10 12 14 16 18 ...)

11:28 gfrlog: infinite ordinals in clojure

11:43 shortlord: why is it necessary to put function definitions into parentheses when defining functions with multiple arities? It should be pretty easy for Clojure to figure out that a pair of params and body always makes one definition, similar to let, right?

11:45 pdk: you can write things like (fn [x] (form1) (form2) ...)

11:45 without parens around form1 and form2 etc

11:47 so the extra parens disambiguate when you'd be adding a do form or something like that anyway for functions that don't follow the everything-inside-a-let-form format

11:48 shortlord: pdk: ah, function definitions contain an implicit do. Why is that the case? Although clojure is supposed to be used functional, using a do implicitly nearly everywhere seems rather imperative

11:49 tonyl: I think he meant the (defn ([] (do-something)) ([x] (do-something-else)))

11:49 pdk: they have an implicit do yes

11:49 though in cases like what tonyl is showing

11:50 something like (defn x [] (do-stuff) [x] (do-other-stuff))

11:50 the lack of extra parens doesn't really help to distinguish for it whether the [x] is supposed to be a return value for the [] version or become the start of its own version of the function

11:50 so it cries

11:51 shortlord: pdk: I understand the problem, I was just surprised to find so many things in clojure having an implicit 'do', since do encourages destructive functions

11:52 pdk: hm there's something

12:05 fliebel: I love incanter :)

12:06 jweiss: ,(apply list "" "")

12:06 clojurebot: ("")

12:06 jweiss: i don't get it ^

12:07 technomancy: jweiss: apply's last arg is treated as a seq

12:07 fliebel: Some nice scatter plots :) http://yfrog.com/7228285886p http://yfrog.com/7283555419p

12:07 jweiss: technomancy: yeah i was just realizing that

12:08 so i guess i should wrap my args into a seq to begin with before calling apply

12:08 technomancy: if you don't have a seq already you don't need apply

12:08 fliebel: jweiss: Why would you call apply, if you don't have a seq of arguments?

12:09 jweiss: fliebel: well, in my code i do have a seq

12:09 fliebel: ah

12:10 jweiss: the error i'm getting is wrong # of args

12:10 the first 2 args are empty strings in this case

12:11 tonyl: &(apply list "" "" ["wer" "gdf"])

12:11 sexpbot: ⟹ ("" "" "wer" "gdf")

12:20 edoloughlin: Anyone using CounterClockwise had it go wierd for just one file? Syntax highlighting & colour parens still work but indentation, backspace, element selection are broken. Other files are unaffected.

12:34 LauJensen: &(double 2.2250738585072012e-308)

12:35 fliebel: LauJensen: Did you crash it?

12:35 LauJensen: fliebel: Yes

12:35 fliebel: clojurebot did this fine this morning...

12:35 LauJensen: ,(double 2.2250738585072012e-308)

12:35 robonobo: yeah

12:35 clojurebot: Execution Timed Out

12:35 fliebel: see...

12:35 robonobo: aha!

12:35 LauJensen: Hmm...

12:35 They both should do that. I think they use the same code almost

12:35 robonobo: would be weird if it did crash it

12:36 LauJensen: &(println "hello?")

12:36 sexpbot: ⟹ hello? nil

12:36 fliebel: huh...

12:36 oh, right, threads...

12:36 LauJensen: Maybe sexpbot kills the thread silently?

12:36 LauJensen: fliebel: yea I think so

12:36 robonobo: is there a difference beteen sexbot and clojurebot?

12:36 woops

12:36 sexpbot

12:37 LauJensen: robonobo: Yes, big differences

12:38 fliebel: &(dorun (repeat 42))

12:38 sexpbot: Execution Timed Out!

12:38 fliebel: … huh?

12:49 semperos: ^ is now preferred to #^, right?

12:51 dnolen: semperos: yup

12:51 semperos: dnolen: thx

13:06 arohner: what do I put in my project.clj to download all of contrib-1.3? I have [org.clojure.contrib/complete "1.3.0-SNAPSHOT"]. That successfully downloads complete, but I don't see the other libraries in lib, and starting up complains about not finding org.clojure.contrib.shell

13:08 mattmitchell: aravind: [org.clojure.contrib "1.3.0-SNAPSHOT"] would probably do it

13:09 aravind: sorry, this is what I have in mine: [org.clojure/clojure-contrib "1.2.0"]

13:11 raek: arohner: there's standalone too. I don't remember what the difference with complete was

13:11 arohner: well, it looks like one of my issues is that contrib.shell has disappeared

13:12 raek: now that you mention it, I think clojure.java.shell has replaced it

13:13 arohner: raek: aha! thanks

13:28 jkdufair: anyone have a setup they're happy with for developing/deploying to GAE?

13:29 fliebel: jkdufair: I heard appengine-magic is nice

13:29 amalloy: ping

13:30 amalloy: fliebel: pong

13:30 fliebel: amalloy: I wrote and benchmarked a few take-randnth functions :)

13:31 amalloy: exciting

13:31 jkdufair: ah! haven't heard of appengine-magic. will check it out. thx

13:32 fliebel: amalloy: https://gist.github.com/805747

13:33 So, there are the simple functions, which should be very bad, and then mine and yours, for the more complicated approach.

13:33 jkdufair: fliebel: wow! thank you

13:34 fliebel: amalloy: But as you can see in the graphs(linked), the first 2 do quite well.

13:34 amalloy: fliebel: neat, i'm looking now

13:35 fliebel: First graph is constant number of items from a growing vector, second is a growing number of items to take from a constant vector.

13:35 amalloy: did you check out https://gist.github.com/805546 and https://gist.github.com/805583, where i implemented it two more times myself?

13:35 fliebel: no...

13:35 amalloy: they're not that interesting really

13:36 fliebel: amalloy: Did you try them performance-wise?

13:36 amalloy: nope

13:37 i don't expect them to be any better really

13:37 one was a lazy-taking approach, and one was writing it with unfold

13:39 fliebel: the distinct one in my code is also lazy, but as you see in the second plot, it gets bad once n gets close to the length of coll.

13:43 amalloy: How do you figure out this big o thing?

13:44 amalloy: fliebel: http://en.wikipedia.org/wiki/Big_O_notation#Example is a reasonable description

13:48 ohpauleez: Is Enrico Franchi in here?

13:48 amalloy: eg for take-rand3, (count coll) takes O(coll) time, (range nr) takes O(nr) time; each step in the reduces takes constant time, and there are coll + nr reduce steps, so the total algorithmic complexity is O(coll+nr)

13:49 and the same is probably true of any similar implementation, including mine; the simple ones probably have smaller constant factors

13:50 i think the main benefit of the complicated algorithm comes when (vec coll) is already passed in to you, so that you only have to do the O(nr) steps

13:51 i'd be interested to see how that performs: create a large vector once, then call take-randnth on it many times. i dunno

13:51 fliebel: amalloy: What about nr 2? I can;t figure that one out.

13:53 amalloy: $source distinct

13:53 sexpbot: distinct is http://is.gd/9IzW0R

13:54 fliebel: amalloy: The problem is that we have to deal with the probability that rand-nth takes a duplicate.

13:54 also, count on a vector seems to be constant.

13:54 amalloy: fliebel: yes, it gets murky

13:54 and yeah, count is definitely constant there

13:54 but in take-rand3, coll isn't a vec

13:55 fliebel: I pass it a vec...

13:56 amalloy: fliebel: i don't see that happening. plot-len and plot-take both pass it a (range foo), and the very first line of take-rand3 is (count coll)

13:56 but it doesn't really matter, since there's an O(coll) step later anyway

13:57 fliebel: Oh, I didn't put that in the gist yet, but I do.

13:57 where?

13:57 clojurebot: where is your source code

13:58 amalloy: fliebel: (reduce f (vec coll))

13:58 is going to have (count coll) steps

13:59 er wait, those ->> forms confuse me

13:59 fliebel: amac: Wrong! Right!

14:00 But still, there must be something that gets worse with coll, otherwise the first graph would be constant...

14:00 amalloy: $source vec

14:00 sexpbot: vec is http://is.gd/jXPZMI

14:00 ohpauleez: Is reduce lazy, in that it'll only realize the next element of a lazySeq?

14:00 amalloy: oh, of course that doesn't say anything useful

14:00 ohpauleez: no

14:00 ohpauleez: amalloy: So it'll realize the full seq, just like apply?

14:01 fliebel: It goes down to RT, which calls LazilyPersistentVector

14:01 amalloy: fliebel: (vec coll) is O((count coll))

14:01 fliebel: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LazilyPersistentVector.java

14:01 amalloy: thanks

14:01 fliebel: … I'm trying that

14:02 amalloy: fliebel: i've often wondered why (vec [1 2 3 4]) isn't a no-op

14:02 fliebel: yea...

14:03 amalloy: but either way, (count coll) and (vec coll) are both linear-time

14:03 ohpauleez: i don't understand the question. realize which full seq?

14:03 fliebel: okay

14:03 jkdufair: is there some .emacs code i can use to start swank from within emacs (i.e. not have to launch another terminal)?

14:04 fliebel: amalloy: Bingo! removing the vec made 3 and 4 constant.

14:04 amalloy: fliebel: really? that's good, i think. can you link me to an updated gist?

14:04 technomancy: jkdufair: http://github.com/technomancy/durendal

14:05 fliebel: amalloy: You want updated plots as well?

14:05 amalloy: fliebel: if you want. i'm willing to take your word for it

14:06 jkdufair: technomancy: thank you!

14:07 fliebel: amalloy: https://gist.github.com/805747 http://yfrog.com/5r80779474p http://yfrog.com/mr42647628p

14:07 technomancy: no problem

14:08 amalloy: fliebel: excellent, just as we hoped

14:10 fliebel: amalloy: Still, picking and filtering random items, is faster for picking a small number of items from a larger vector.

14:10 amalloy: yeah

14:10 fliebel: uh, no, I mean… well

14:10 amalloy: fliebel: well, shuffling then picking

14:11 fliebel: right

14:11 amalloy: filtering is not so hot

14:11 fliebel: I was talking about the red line, which is… the shuffle one.

14:12 amalloy: as N approaches M, the filter solution is probably O(N!), but figuring out what it's like in the middle is too hard for me :P

14:13 fliebel: amalloy: I think some math person in here explained something related to me once...

14:14 Something with birthdays and pigeonholes.

14:14 amalloy: yes, probably related to the birthday problem

14:14 but more complicated i think

14:15 fliebel: So, it will be O(N!@#$%M^&)

14:16 amalloy: *laugh* indeed

14:17 fliebel: I'll update the gist to reflect that...

14:17 ejackson: fliebel: hilarious

14:19 fliebel: https://gist.github.com/805747

14:22 jkdufair: technomancy: great tools. thx a bunch.

14:32 danlarkin: $4

14:38 ieure: technomancy, What’s the accepted way of depending on a Java lib (with Leiningen) which isn’t in a public Maven repo?

14:38 I dropped it in lib/ and lein nukes it every time I run deps.

14:41 danlarkin: ieure: it has to be in a repo

14:41 your local .m2 cache is technically a repo

14:41 amalloy: ieure: you can install it to your local repo

14:41 ieure: Gross.

14:42 Okay.

14:42 Can I just cp it in there or what?

14:42 I don’t know fuck-all about the varied crazy Java build tools.

14:43 ldh: no, you've got to tell maven to install it. example: http://jeff.langcode.com/archives/27

14:45 ohpauleez: I basically have to sum a comprehension, and I've timed a few approaches, two have similar times and so I want to understand how they differ. One is doing (reduce #(+ (op-on %1)) coll), another is doing (apply + (map #(op-on %1) coll)), but the apply is going to realize the entire collection, and I have a situation where that collection could be extremely large. (amalloy)

14:47 amalloy: ohpauleez: i think you made some kind of typo with your first example, but neither one of those will realize the whole collection at once

14:47 ohpauleez: oh really? I thought apply would

14:48 amalloy: ^. Thanks though, I'll just go with which ever one is fastest then

14:48 amalloy: nah, it passes a lazy seq as the &rest arg

14:48 ohpauleez: ahh, cool

14:48 amalloy: &(apply + (range 1e6))

14:48 sexpbot: ⟹ 499999500000

14:49 ohpauleez: thanks amalloy

14:50 amalloy: &(= (doall (range 1e6)))

14:50 sexpbot: Too much is happening at once. Wait until other operations cease.

14:50 fliebel: amalloy: Why was your php code using 2 arrays?

14:50 amalloy: *blink*

14:50 Raynes: ping

14:50 fliebel: Hm, I think sexpbot is having trouble with big numbers ;)

14:50 * danlarkin gasps

14:51 amalloy: $login

14:51 sexpbot: You've been logged in.

14:51 amalloy: $reload

14:51 sexpbot: Reloaded successfully.

14:51 amalloy: $logout

14:51 sexpbot: You've been logged out.

14:51 amalloy: &1

14:51 sexpbot: ⟹ 1

14:51 amalloy: fliebel: i suppose i could have done it with a single array

14:52 use the below-i chunk of the array to store the return value, and then split it when it's time to return

14:53 fliebel: right, that is what my reduce thing is doing. made me feel real smart for a moment :)

14:54 amalloy: fliebel: ahh, is that what's going on. your reduce was too clever for me

14:54 fliebel: amalloy: Your iterate was to smart for me...

14:55 amalloy: fliebel: it's funny, because i knew the classic algorithm involved swapping a[i] with a[idx], but i couldn't remember why, so i just didn't do it

14:56 * amalloy looks back at your gist to see how it works

14:58 * fliebel looks at amalloy's gist to see how it works

14:59 amalloy: fliebel: are you sure take-rand3 selects uniformly?

14:59 (reduce #(conj %1 [%2 (rand-int %2 len)]) [] (range n)) looks like it will be biased towards higher numbers, though i still don't see how it all fits together

14:59 fliebel: uhm, no… but not less uniformly than your code I think… I just collapsed your separate vector inot the unused part of the first vector.

15:00 amalloy: oh, i think i get it

15:00 okay, clever

15:01 fliebel: amalloy: You might have trouble with my ->>, I'm having trouble with your nesting.

15:01 amalloy: lol

15:01 you create a list of swaps first, and then perform them all in a row on the coll?

15:01 * tonyl is late to the party

15:01 fliebel: yea :)

15:01 tonyl: what gist is it?

15:01 amalloy: https://gist.github.com/805747

15:02 fliebel: i like ->> as much as the next guy, it's just harder to read other people's code :)

15:03 fliebel: yea, but I think I understand your code now. *phew*

15:05 amalloy: tonyl: your turn to write one

15:05 fliebel: tonyl: I second that :)

15:05 tonyl: I am working on one

15:05 fliebel: great :)

15:05 tonyl: are we looking for O(n)

15:06 fliebel: O(lean and mean) is what we want.

15:06 tonyl: right

15:07 fliebel: tonyl: Have you seen the plots?

15:08 tonyl: fliebel: I am looking at your post for that, are those the ones?

15:08 fliebel: yes

15:10 amalloy: fliebel: i love that immutability lets you write (assoc a i (a b) b (a i)) instead of needing a temporary swap area

15:10 fliebel: :)

15:11 I wish update-in does that. or…. ##(doc update-in)

15:11 sexpbot: ⟹ "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created."

15:11 amalloy: fliebel: what for? isn't that what assoc is for?

15:12 fliebel: amalloy: Wouldn't it be great if you could update multiple nested values in one go?

15:14 But yea, I am really starting to appreciate those little features. Same thing for map, equality and math operators.

15:14 amalloy: &(update-in {:a {:b 10 :c 5}} [:a] assoc :b 1 :c 2) is an approximation

15:14 sexpbot: ⟹ {:a {:b 1, :c 2}}

15:14 mfex: hi, can anyone point me to the slides for mark mcgranaghans conj talk?

15:14 amalloy: you can't easily operate on the existing values of :b/:c, afaik

15:15 fliebel: i've wanted to be able to do that in the past, but someone convinced me it was a confused idea. if only i could remember why...

15:15 fliebel: hey, nr2 became O(M-ish) as well by removing the vec.

15:16 amalloy: fliebel: surely not if N ~= M?

15:18 fliebel: hmhm

15:18 It just that the vec does not make it increase anymore.

15:19 post updated

15:21 I cant help seeing a patter like /// in the shuffle line. GC? Chunking?

15:22 technomancy: ieure: I recommend setting up a private archiva instance for private jars if you've got a team of more than 1

15:23 ieure: if you're solo then you can add the dependency to project.clj even if it's not in any remote maven repos and run lein deps; it will give you a line you can use to put the jar in m2

15:23 amalloy: fliebel: gc i think. every one of the plots has those outliers

15:24 shuffle probably feels the most impact because it's allocating a new M-sized array every time, even if you only need N elements out of it

15:25 fliebel: that's true...

15:26 Although I would expect to see out-of-line dots, as with the others, but what I see is more like a gradual decline in speed, and then a drop again.

15:27 tonyl: How are you doing?

15:28 tonyl: can't make it any better then m+n

15:28 I need to learn more about clojure internals for this one

15:29 it's puzzling me, but good thought and clojure-training exercise

15:29 fliebel: tonyl: http://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html

15:29 (shift the headers >)

15:31 tonyl: When you're done, I'd love to see your code.

15:32 tonyl: thanks for the link, i have another idea. i will show the code for critique

15:33 bartj: I am looking for a soundex library and am thoroughly confused as to which I should pick

15:33 or even which is the most appropriate

15:33 because the soundex returned by the in-built mysql function

15:35 is different from that of Apache commons library - http://commons.apache.org/codec/apidocs/src-html/org/apache/commons/codec/language/Soundex.html#line.252

15:36 amalloy: fliebel: oh, i see, you mean in the plot-take, not plot-len

15:37 fliebel: right

15:37 amalloy: yeah, that is interesting

15:37 * tonyl needs to learn incanter and lein or cake

15:38 amalloy: tonyl: you should certainly learn lein or cake. incanter is neat but i feel like i don't have enough uses for it to spend time learning it

15:39 tonyl: i've used a personal bash script to run my clj scripts, but now projects getting bigger or managing dependecies is getting to be a problem.

15:39 fliebel: tonyl: crash course: lein/cake deps, lein/cake repl, lein/cake uberjar. incanter: (view (xy-plot xs ys))

15:39 amalloy: fliebel: don't forget lein/cake new

15:39 tonyl: so no big differences between lein and cake, besides cake having a persistent jvm?

15:39 amalloy: tonyl: mostly just different plugin frameworks

15:40 lein has optional persistent jvm too

15:40 tonyl: oh ok

15:40 raek: they are very similar for basic tasks. their plugin/task features are more different, though

15:40 tonyl: I'll try lein first since it was the first one to come out

15:40 then I'll test this code I have to see the scattering and time

15:40 fliebel: I

15:41 fliebel: I'll try not to keep you waiting to much for the code :)

15:41 shortlord: there is nothing like select-keys or find that takes a pred instead of fixed keys, is there?

15:41 tonyl: maybe some can help you there

15:41 fliebel: tonyl: I have tea :) so, if you do it within a hour, I'm fine :)

15:41 amalloy: shortlord: filter

15:41 fliebel: Otherwise I'll see you tomorrow.

15:42 shortlord: amalloy: but filter does not return a map, but a sequence, which requires some ugly stitching together afterwards

15:42 fliebel: meh, just (into {})

15:42 amalloy: &(into {} (filter (comp even? key) {1 2, 4 3, 5 6 8 7}))

15:42 sexpbot: ⟹ {4 3, 8 7}

15:43 amalloy: fliebel: http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle is apparently what the shuffle algorithm is called

15:43 jkdufair: just want to say thanks to the whole clojure community. i got a production-ready GAE/slime/swank/clojure/cygwin setup together in a matter of hours and already have a hello world app on GAE

15:48 shortlord: fliebel, amalloy: thx, into {} together with some as the pred was exactly what I needed, great :)

15:50 raek: if you want to make it map type independent, you can do it like (into (empty m) (filter pred m))

15:57 jweiss: anyone here use clojure.contrib.logging with java.util.logging? the method/line# logging doesn't work - it always prints "lojure.contrib.logging$impl_write_BANG_.invoke"

15:57 rather "clojure.contrib.logging$impl_write_BANG_.invoke"

16:06 fliebel: tonyl: Done yet? My tea is done, and I'm soon going to bed ;)

16:06 tonyl: fliebel: I guess I'll bother you tomorrow then

16:07 fliebel: tonyl: Thanks :)

16:09 semperos: &(first "/")

16:09 sexpbot: ⟹ \/

16:09 semperos: what's the right way to just have that char?

16:10 ieure: Ugh.

16:10 tonyl: semperos: it seems that you have it

16:10 ieure: What am I doing wrong here? https://gist.github.com/a9aeeb52bfe1514b7b55

16:10 "No matching ctor found for class com.google.i18n.phonenumbers.Phonenumber"

16:10 No idea what that is supposed to mean.

16:11 semperos: tonyl: I do, but it seems a bit round-about to ask (first some-string) to "get" a single char

16:11 tonyl: ieure: means there is no constructor that just takes no arguments for that class

16:11 &\/

16:11 sexpbot: ⟹ \/

16:11 semperos: tonyl: coulda sworn I tried that at the repl; thanks

16:11 tonyl: semperos: just prepend it with a \ ##\/

16:12 bartj: ieure, I can help you

16:12 as a matter of great coincidence I am using the Phonenumber lib right now :)

16:12 semperos: same as with all char's, must have mistyped originally

16:12 ieure: bartj, Awesome.

16:12 bartj: ieure, let me look at gist

16:13 ieure: bartj, I guess I’m supposed to use PhonenumberUtil.getInstance() to get an instance back.

16:13 Fuckin’ Java.

16:13 bartj: oh, that is easy

16:14 (PhoneNumberUtil/getInstance)

16:14 here is how to format phone numbers:

16:14 (.format (PhoneNumberUtil/getInstance) phone com.google.i18n.phonenumbers.PhoneNumberUtil$PhoneNumberFormat/INTERNATIONAL)

16:14 where "phone" will be a number of course

16:14 ieure: Yeah.

16:14 bartj: this will return a Phonenumber class

16:15 ieure: Throws an exception, but I think I can thrash around from here.

16:15 bartj: you would have to use (PhoneNumberUtils/getInstance)

16:16 ok

16:16 amalloy: tonyl: sexpbot only evals ##code that starts with parens, to avoid annoying people in ##java and similar channels

16:16 tonyl: I figured it might be because of that

16:16 ieure: bartj, Is there a less insane way of saying "com.google.i18n.phonenumbers.PhoneNumberUtil$PhoneNumberFormat/INTERNATIONAL"?

16:16 bartj: ieure, yeah :)

16:17 (import-static com.google.i18n.phonenumbers.PhoneNumberUtil$PhoneNumberFormat INTERNATIONAL)

16:17 tonyl: aliasing it

16:17 bartj: and then

16:17 (.format (PhoneNumberUtil/getInstance) INTERNATIONAL)

16:17 I believe raek told me this a few days back

16:17 amalloy: bartj: sweet, i always forget we have import-static

16:17 ieure: Looks like that’s not an option with the `ns' macro, though.

16:18 amalloy: ieure: no, you have to do it separately

16:18 ieure: Is that a 1.3 feature?

16:19 Unable to resolve symbol: import-static in this context

16:19 On 1.2.x.

16:19 tonyl: it is in contrib

16:19 ieure: Ah, okay.

16:19 tonyl: http://clojuredocs.org/clojure_contrib/clojure.contrib.import-static/import-static

16:19 mattmitchell: ,(doc defn)

16:19 clojurebot: "([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any do...

16:20 amalloy: &(doc defn)

16:20 sexpbot: ⟹ "Macro ([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata"

16:20 markskilbeck: Deja vu.

16:21 mattmitchell: markskilbeck: funny :)

16:25 hmm, i'm trying to add :doc and :arglists to a defn. but (doc my-func) doesn't show anything

16:25 is this correct? (defn t #^{:doc "test"} [] (prn "t"))

16:26 tonyl: i think it is (defn ^{:doc "test"} t [] (prn "t"))

16:27 mattmitchell: tonyl: there we go thanks.

16:27 technomancy: mattmitchell: (defn t "test" [] (prn "t"))

16:27 ohpauleez: mattmitchell: also what technomancy ^

16:27 I think that's more widely used

16:27 amalloy: yes, for sure that is used most, but if you want to supply arglists you have to do it tony's way

16:28 ohpauleez: ahh, yes

16:28 brehaut: mattmitchell: the #^ is old style meta (pre 1.2)

16:28 mattmitchell: ok i thought i read that somewhere.

16:32 tonyl: gotta get some things done, nice talking to you guys

16:33 ieure: Is there a CSV library (or wrapper around a Java one) which will lazily read lines from *in*?

16:34 I found clojure-csv, but it seems to want the entire CSV to be read in as a string.

16:34 I guess I could parse one line at a time and always call first, but that seems somewhat ugly.

16:34 raek: (defn t "test" {:arglists '([foo bar])} [x y] ...)

16:38 ohpauleez: ieure: http://clojuredocs.org/clojure_core/clojure.core/line-seq

16:38 &(doc line-seq)

16:38 sexpbot: ⟹ "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."

16:39 ohpauleez: not sure how you'd make sure you were processing the csv correctly

16:39 ieure: ohpauleez, So, #1, this will not with with *in*, which is a LineNumberingPushbackReader, not a BufferedReader. And #2, I can already lazily read from *in*, it’s just that the clojure-csv semantics aren’t a good match.

16:39 ohpauleez: but you might be able to write a nice small DSL, using the existing functions in the library

16:41 ieure: I was assuming you would just rebind *in*. Sorry for misunderstanding the question

16:41 ieure: No, I want to read from stdin.

16:41 ohpauleez: the answer is just see if the functions in the library are small enough for you to build up a lazy version of the DSL

16:42 and then contribute the changes back to the project

16:42 ieure: Though it seems like I might be better off using with-open and/or line-seq.

16:42 I really don’t think I need to build up a DSL here.

16:43 ohpauleez: is this because you want to pipe the csv to it?

16:43 ieure: Yes.

16:44 amalloy: ieure: i think ohpauleez is using DSL to mean "library" here

16:44 ohpauleez: yes

16:44 loosely using DSL

16:48 ieure: Well, I was hoping to avoid parsing command-line arguments, which was the main reason to use *in*

16:48 But this LineNumberingPushbackReader stuff that *in* uses seems crazy.

16:49 It’s way easier to just use (read-lines).

16:49 mattmitchell: is it common to use the :test meta key for embedding tests to your functions?

17:05 aamar: Missed connection: I saw a clojure package for couchdb, quite a bit more high-level than clojure-couchdb or clutch; more support for view handling etc. Anyone know of it?

17:05 Can't find it anymore

17:11 ohpauleez: aamar: eames, clojurize-couchdb, net.experimentalworks/couchdb ?

17:11 there's also evil-couchdb

17:12 sritchie: hey all -- I'm reading about the various matrix packages in java, and I see references to "large" matrices, or really large vectors

17:12 where would the "large" range start?

17:12 brehaut: dont forget https://github.com/mmcgrana/hammockdb

17:12 sritchie: I'd like to read in a 360x720 2d vector

17:12 of floats

17:15 aamar: ohpauleez, brehaut: I bet it's one of those, I'll take a look. Thanks!

17:15 brehaut: aamar: its not hammock ;)

17:17 Leonidas: hi. I tried `binding' a variable from another namespace but that does not seem to be possible. any ideas what I could do?

17:17 ohpauleez: sritchie: I think it depends what you're doing with that matrix, but I'm not sure what qualify as "large"

17:17 sritchie: typically in Clojure, large things are operated on lazily

17:17 if possible

17:18 Leonidas: http://clojuredocs.org/clojure_contrib/clojure.contrib.with-ns/with-ns

17:18 you can use with-ns, and rebind

17:18 sritchie: ohpauleez: yeah, I've got these as lazy vectors, as of now -- I'm working on a cascalog operation that needs to return a sequence of float arrays

17:19 Leonidas: ohpauleez: that looks nice, so with-ns and binding. cool, will try that

17:19 sritchie: cascalog builds mapreduce jobs, so presumably these are going to get serialized by hadoop --

17:19 raek: Leonidas: are you 1) using clojure 1.3 or 2) trying to rebing something in clojure.core=

17:19 ohpauleez: sritchie: and as long as it's using streaming underneath, you should be fine, right?

17:20 sritchie: ohpauleez: sounds like it

17:20 ohpauleez: great, I'll test this out, then

17:20 ohpauleez: cool

17:20 raek: you should be able to rebind vars using binding without with-ns

17:20 ohpauleez: raek: really, even in other ns's?

17:20 raek: yes

17:20 dnolen: eames, not ready nor public yet. I really should get back to that :)

17:21 raek: (dynamic rebinding using 'binding')

17:21 ohpauleez: dnolen: :)

17:21 I have a cassandra wrapper in a similar state

17:21 raek: the way you can rebing *in* and *out*, for instance

17:22 1) in clojure 1.3. only vars marked as :dynamic can be rebound, 2) some of the vars in clojure.core are special and cannot be rebindable.

17:22 ohpauleez: raek: ah yes, totally

17:23 as long as you qualify correctly, I don't know what i was thinking

17:23 raek: yes. good point. the symbol used in 'binding' must of course resolve to the var in question

17:25 Leonidas: ohpauleez: uhm, now I can't access my formal parameters from inside the with-ns body. Whats the solution to that?

17:26 ohpauleez: Leonidas: you should scroll up and read what raek and I were saying on the subject

17:26 let me know if that helps you

17:28 Leonidas: ohpauleez: oh sorry, I missed that somehow.

17:28 raek: no, I am on Clojure 1.2 and trying to rebind something that is defined in some other module of my software.

17:29 amalloy: sritchie: btw, "lazy vectors" is a contradiction. presumably you meant lazy sequences

17:30 sritchie: amalloy: yeah, sorry about that, I meant lazy sequences. I've got a byte-buffer, and I've written a function that returns a lazy sequence for a bytebuffer, by calling .getFloat

17:30 amalloy: The next step is to use this lazy seq to create an array inside of incanter

17:30 raek: Leonidas: also, watch out for combining dynamic rebinding with lazy sequences (map, for, filter and friends)

17:30 sritchie: amalloy: so I'll have to realize the sequence eventually

17:31 Leonidas: raek: I am trying to rebind a boolean value.

17:31 raek: if you return a lazy sequence out of the binding form, the binding can revert before the lazy seq is forced

17:31 Leonidas: (def force-color false)

17:31 amalloy: Leonidas: whoa, that is not rebinding

17:31 Leonidas: in the one file and in the other (binding [force-color true] body)

17:31 raek: it is a convention to name rebindable variables with *earmuffs*

17:32 (the naming shouldn't make any difference in 1.2, though)

17:32 Leonidas: oh, good point. I will adjust that.

17:32 amalloy: raek: or in 1.3, i'm pretty sure

17:32 Leonidas: I'd prefer to get this thing working first.

17:32 amalloy: Leonidas: that should work as long as force-color resolves to the same var as the one you're def-ing

17:32 ohpauleez: Leonidas: it needs to be (binding [the-ns/*force-color* true] body)

17:32 raek: ah, have they removed the automatic :dynamic on *earmuffs*=

17:32 amalloy: ie, you have a :use or :require for that ns

17:33 ohpauleez: Leonidas: what amalloy said

17:33 amalloy: raek: i'm not an authority by any means, but last i heard

17:33 raek: Leonidas: what does (resolve 'force-color) return?

17:33 if it returns #'the-ns/*force-color*, then it should work

17:34 jweiss: how do i do this in clojure: x =1; try { doStuff(); x=2; } finally { System.out.println(x); }

17:34 Leonidas: ohpauleez: I thought the same and tried to :use my.namespace :only (force-color), is that enough or do I still need to prefix my.namespace/ to *force-color*?

17:34 raek: Leonidas: also, what does (binding [*force-color* :lala] *force-color*) return?

17:34 * Leonidas tries all these hints

17:34 raek: Leonidas: the usual rules for symbol resolution applies

17:35 ,(binding [*out* :lala] *out*)

17:35 clojurebot: :lala

17:36 raek: ,(binding [*out* :lala] (lazy-seq [*out*])) ; common gotcha

17:36 clojurebot: (#<StringWriter >)

17:36 Leonidas: raek: resolve returns nil, both before and inside the binding form

17:37 mefesto: Is it possible to extend a protocol to a byte array?

17:37 ohpauleez: Leonidas: can you paste up a gist for us?

17:37 raek: ,(resolve '*out*)

17:37 clojurebot: #'clojure.core/*out*

17:37 Leonidas: ohpauleez: sure.

17:37 ohpauleez: thanks!

17:37 amalloy: jweiss: (let [x (try (dostuff) 2 (catch Exception _ 1))] (println x))

17:38 jweiss: amalloy: but i want a finally clause, not catch

17:38 raek: Leonidas: then either you should get an exception when trying to evaluate anything using *force-color*, or you have a let or function parameter shadowing it

17:38 jweiss: i want the printout whether an exception occurs or not

17:38 do i have to rethrow?

17:40 raek: no, (try ... (finally (println x))) should work

17:40 Leonidas: ohpauleez: https://gist.github.com/806871 (it isn't actually running, I hope that's enough)

17:40 amalloy: jweiss: that or use some mutable/reference variable

17:40 raek: but he needs x to be bound in the finally scope, and "changed" in the try scope

17:40 jweiss: so the finally clause can't know what the try clause returned?

17:40 i guess not since it's inside the try :)

17:40 amalloy: jweiss: i don't think so

17:41 Leonidas: raek: yeah, I'm also surprised why I get nil but inside the (binding [force-color true] force-color) is still true.

17:41 ieure: You guys have invalidated my rule about IRC.

17:41 "All channels of the form #(programming-language) are useless."

17:41 ohpauleez: ieure: Which is?

17:41 Leonidas: ieure: what rule?

17:41 ieure: You guys are really helpful, and I appreciate it more than you know.

17:41 jweiss: this channel rocks

17:41 raek: ah. change. clojure does not allow that to locals.

17:41 ohpauleez: ah, thanks ieure

17:41 amalloy: ieure: only people with lots of vowels in their name are worth listening to?

17:42 ohpauleez: haha

17:42 raek: Leonidas: can you test evaling force-color and (binding [force-color :foo] force-color) at the repl?

17:42 * Leonidas likes this channel also quite a bit

17:42 amalloy: i guess with 3.5 of each i'm on the border

17:42 arohner: is defining multi-methods with #'foo as a dispatch function fully legal?

17:43 raek: after a (in-ns 'karmawhore.parser)

17:43 amalloy: arohner: yes

17:43 arohner: amalloy: it appears to give me a syntax error in 1.3-alpha4

17:43 amalloy: gist?

17:43 arohner: one sec

17:43 Leonidas: raek: I get :foo back.

17:43 ohpauleez: Leonidas: is force-color originally bound to true?

17:44 Leonidas: ohpauleez: no, it is originally false

17:44 ohpauleez: and is it still false in that binding block?

17:44 Leonidas: raek: and (resolve 'force-color returns non-nil)

17:45 ohpauleez: no, it is true inside the block. But only to the block, the functions that I call (red) see it as false

17:45 jweiss: isn't there an alternative to swap! that just takes a value instead of a function?

17:45 raek: jweiss: reset!

17:46 jweiss: ah there you go. it's not mentioned here: http://clojure.org/atoms

17:46 Leonidas: #'karmawhore.color/force-color

17:46 jweiss: which i find strange

17:46 Leonidas: is what it resolves to. Looks fine to me

17:46 raek: Leonidas: can you paste the definition of 'red'?

17:46 Leonidas: but somehow the binding does not traverse over to inside karmawhore.color

17:47 raek: could be that you look up the value of force-color "in advance"

17:48 for instance, (def foo force-color) will deref force-color and bind foo to the value it had at that point

17:48 sritchie: quick question on lazy seqs -- if I build a lazy seq with a generator, and want to return a lazy-seq of the first 1000 elements, say, os the way to do this with (def lazy-return (take 1000 lazy-generator))

17:48 amalloy: jweiss: it's not exactly good practice. but it is mentioned in http://clojure.org/cheatsheet, at least

17:48 Leonidas: raek: the relevant bits: https://gist.github.com/806871#file_parser.clj

17:49 jweiss: amalloy: yeah, i left my paper cheatsheet copy at home :)

17:49 amalloy: sritchie: (take 1000 (lazy-generator))

17:49 Leonidas: raek: erm, I mean https://gist.github.com/806871#file_color.clj

17:49 amalloy: ie, you should never bind a variable to the entire sequence, or none of it can be freed

17:51 sritchie: amalloy: ah, got it

17:51 amalloy: how about (map %(take 1000 %) lazy-generators), where lazy-generators is a sequence of those lazy-gens?

17:52 brehaut: amalloy: caveat: the sequence is expensive to compute and you want to have it automemoized

17:52 raek: Leonidas: what does (binding [force-color true] (red "foo")) return?

17:52 amalloy: that's not lazy either

17:52 raek: I don't see any reason for why you code shouldn't work...

17:52 amalloy: because lazy-generators is itself holding the head of all the sequences

17:53 raek: Leonidas: so if force-color is true, then fill-color always returns ""?

17:55 * Leonidas punches hinself in the face

17:55 sritchie: amalloy: okay, one more try. https://gist.github.com/806902

17:56 amalloy: I've got a large ByteBuffer, containing 24 (* 360 720) sized groups of floats. Every other group corresponds to a month, so i wrote extract-month, which returns another ByteBuffer, sized (* 360 720)

17:56 Leonidas: raek, ohpauleez: thank you both for your help. The problem was caused because of my own stupidity, missing a (not ...).

17:57 sritchie: so the idea is that this returns, back to hadoop, lazy sequences of floats

17:57 amalloy: sritchie: looks good to me

17:57 sritchie: amalloy: great, thanks for taking a look

17:57 amalloy: i'm not sure you want to hint it as HeapByteBuffer, though. probably just ByteBuffer?

17:57 arohner: where did c.c.java-utils/wall-hack-method go, in contrib 1.3?

17:57 raek: Leonidas: ok. glad you found the problem... :-)

17:57 Leonidas: but while at it, I might also try to learn something. What is with-ns for? I cannot access the enclosing namespace from it, so it seems quite limiting.

17:59 arohner: aha, c.c.reflect/call-method

17:59 raek: I think it's for evaling something in another namespace. I've never needed to use it

18:00 amalloy: sritchie: and you might actually want to use Channels or Streams, java's lazy constructs, instead of Buffers

18:00 but i guess if you're returning a lazy seq of bytebuffers that's probably equivalent

18:01 * Leonidas renames force-color to *force-color* now

18:01 sritchie: amalloy: I'm reading a binary file of floats written in little endian order -- I was just using bytebuffer as it was easy to set the byte order, so channels and streams might be better

18:02 raek: Leonidas: for future compability, you might as well add the :dynamic metadata: (def ^{:dynamic true} *force-color* false)

18:02 in 1.3, only vars marked as dynamic will be reboundable

18:02 amalloy: sritchie: well, channels basically create buffers, or fill up existing buffers

18:03 mabes: If I have the string "inc" how would I get a hold of the var for that function?

18:03 amalloy: so it would reduce the amount of alloc/dealloc that needs to be done, but probably won't affect the amount of actual memory you use up

18:03 mabes: ,(symbol "inc")

18:03 clojurebot: inc

18:03 amalloy: ,(-> inc symbol resolve)

18:03 clojurebot: java.lang.ClassCastException: clojure.core$inc cannot be cast to java.lang.String

18:03 mabes: ah

18:03 sritchie: amalloy: sounds like a good way to tighten up this damned code

18:03 mabes: thanks amalloy

18:03 amalloy: ,(-> "inc" symbol resolve)

18:03 clojurebot: #'clojure.core/inc

18:04 sritchie: amalloy: once I get this working, I'll try out streams, I'm sure I'll shed a few lines

18:04 amalloy: thanks for the help

18:04 amalloy: sritchie: welcome

18:09 Leonidas: raek: ok, will do. While renaming all my rebindable stuff to have *stars*.

18:19 brehaut: has anyone got any suggestions for a deployment management tool for small scale clojure powered websites hosted on a simple linux vps?

18:20 (ie, something better than ducktape-and-string)

18:22 danlarkin: chef

18:24 zoldar: I know, that it's not clojure specific, but I have problem debugging code working in separate thread - code is ran by scheduled executor and I can see that at some moment it stops - probably due to some exception. Is there a way to get to the stacktrace when such problem occurs?

18:26 brehaut: danlarkin: cheers

18:28 danlarkin: chef definitely does have a learning curve, but I think once you "get" it then anything else seems like nonsense

18:28 technomancy: chef is probably overkill for a couple of servers

18:28 danlarkin: I disagree

18:29 brehaut: technomancy: i have one server and i doubt i'll outgrow it

18:29 technomancy: well if you are going to grow to 5+ then by all means take the time to learn it early, but if you'll never outgrow one it's a hard sell

18:29 it also depends on how much you need to install that's not in apt

18:30 danlarkin: infrastructure as code

18:30 technomancy: danlarkin: you can write a hell of a lot of perfectly serviceable bash scripts in the time it takes to learn chef.

18:30 whatever you use absolutely needs to be checked in of course

18:31 I just can't see the setup of a single server being more than a couple pages of script

18:31 danlarkin: sure, but once you know chef, you know chef. writing your own almost-chef replacement is a wasted learning opportunity

18:32 which is not to say that writing things from scratch is never good, because it certainly is

18:32 but chef's story is pretty good

18:34 brehaut: im leaning towards the couple of pages of scripts i think

18:34 ive got 1 uberjar to run and a directory of media for nginx

18:34 danlarkin: I'm going to take some artistic liberty and make this comparison, homegrown deploy script : chef :: homegrown vcs : git

18:35 why not just use a well-thought-out tool

18:36 brehaut: because i have a limited amount of spare time and i'd rather spend it learning other things?

18:36 technomancy: that is a pretty apt comparison because they both have huge learning curves and they both have small-scale situations where they're not appropriate

18:36 I wouldn't tell my cousin to use git for his term papers, etc.

18:38 danlarkin: brehaut: I see why you would make that trade off, though I do not think it is correct

18:39 brehaut: there is no correct answer with a tradeoff; it wouldnt be a tradeoff otherwise

18:40 danlarkin: yes that's true

18:40 I'll rephrase then and just say I wouldn't make the same decision

18:40 brehaut: fair nuff

18:41 ieure: How do I figure out what index an elt exists at in a vector?

18:44 technomancy: ,(keep-indexed #(if (= :x %2) %1) [:w :x :y :z])

18:44 clojurebot: (1)

18:44 technomancy: probably something better in contrib?

18:46 ieure: Hm… Maybe there’s a better approach to this.

18:46 technomancy: ieure: clojure.contrib.seq/positions, which is essentially what I have above packaged up nicer

18:47 nicer but slightly slower

18:47 ieure: Given a strong "foo", can I generate a :foo symbol from that somehow?

18:47 brehaut: ,(keyword "foo")

18:47 clojurebot: :foo

18:47 hiredman: :foo is a keyword, not a symbol

18:47 ieure: brehaut, Perfect, thank you.

18:48 hiredman, Yeah, I don’t quite have the Clojure lingo down.

18:50 mefesto: is there a way to run clojure scripts using leiningen? something like: lein scripts/clean-db.clj ?

18:50 technomancy: mefesto: leiningen is for projects, so it only runs namespaces that are part of your project (using the run task)

18:51 ieure: technomancy, For whatever it’s worth, Python’s setuptools lets you define arbitrary entrypoints and creates wrapper scripts to invoke those.

18:51 I’ve found it useful.

18:51 brehaut: ieure: lets not use pythons package management as something to emulate

18:51 technomancy: ieure: yeah, I think that makes sense in Ruby too, but the JVM's limitations on the classpath call for different customs, I think.

18:51 ieure: brehaut, Tall words.

18:52 mefesto: technomancy: i see. these scripts are useful to the project while developing but aren't part of the end product... so do these go in test/ ?

18:52 technomancy: mefesto: sure.

18:52 mefesto: I'm think along the lines of: lein run -m test.namespace

18:52 technomancy: really simple stuff can just be new tasks in project.clj too

18:54 brehaut: ieure: why? i think most python programmers are willing to concede that package management is a weakpoint for the platform

18:55 technomancy: mefesto: if it's something that would be useful to multiple projects it should be a leiningen plugin though

18:55 mefesto: looks like there is one called lein-run

18:56 technomancy: I mean like a lein-db plugin

18:56 ieure: brehaut, Package management universally sucks, in my experience. But god knows the Java community has some seriously fucked up build/pakaging shit.

18:56 technomancy: surely your project is not the only one that would benefit from a task for cleaning the db =)

18:57 mefesto: technomancy: :)

18:57 technomancy: ieure: http://twitter.com/#!/derarthur/status/30434562785939456 =)

18:58 ieure: technomancy, Yeah. Leiningen is literally the only reason I try to hack Clojure.

18:58 technomancy: heh; nice

19:02 brehaut: technomancy: lein (sensibly) tells you off for trying to make a release that depends on a snapshot. is there a way to disable that? (eg because you depend on a project that only has snapshots on clojars)

19:03 technomancy: brehaut: depending on a numbered snapshot should do it

19:03 foo/bar "1.0.0-20110128" instead of "1.0.0-SNAPSHOT"

19:03 but also don't forget to get on their case about not doing proper releases!

19:03 brehaut: ah right. that makes sense

19:03 :)

19:04 technomancy: *cough*enlive*cough*

19:04 brehaut: moustache too?

19:07 technomancy: let's all just stare at cgrand intently until we see stable releases

19:07 brehaut: excellent

19:07 i'll just get my own crap in order first

19:11 technomancy: if im browsing clojars, would i expect to see the date stamped snapshots there (eg in http://clojars.org/repo/clj-time/clj-time/), or would i need to work out the datestamp from the metadata?

19:11 technomancy: brehaut: they're in here http://clojars.org/repo/clj-time/clj-time/0.1.0-SNAPSHOT/ or you can look at the filename in lib

19:12 ugh; wtf. all snapshots an no releases?

19:12 bradfooooooooooord!

19:12 brehaut: yeah

19:12 me thinks there needs to be some yelling and shouting to get this ship in order

19:13 hiredman: mutiny then

19:13 technomancy: this is spartaaaaaaaa

19:15 dysinger is in SF right now, we should get him to do it.

20:21 jkdufair: which is more idiomatic? (defrecord inventory-log [foo bar]) or (defrecord InventoryLog [foo bar])?

20:21 brehaut: later; it creates a class

20:22 pdk: java conventions for class names capitalize each word

20:22 records are effectively creating classes

20:23 jkdufair: ok thx. wasn't sure in which Rome I was with defrecord

20:25 amalloy: jkdufair: though it is also idiomatic to (defn make-inventory-log [whatever args] (InventoryLog. some args))

20:32 jkdufair: thx!

20:46 i'm a bit confused about namespaces. if have data.clj with (ns foo.data) at the top and i have core.clj with (ns foo.core (:use foo.data)) at the top. i can't seem to refer to foo.data.SomeRecord in core.clj

20:47 i can't refer to it as SomeRecord. but I *can* refer to it if i qualify it

20:47 brehaut: jkdufair thats correct

20:47 because its a class, you need to import it

20:47 (:import 'foo.data.SomeRecord)

20:47 jkdufair: ah! thank you

20:47 brehaut: approximately

20:48 jkdufair: its common for people to write a constructor function (eg some-record) for consumers

20:49 jkdufair: ah ok. so you typically don't refer directly to the class defined in a defrecord?

20:49 if i do that, do i still need to import it?

20:50 brehaut: nope

20:50 jkdufair: super. thx so much

20:51 amalloy: brehaut: you don't need to quote imports

20:51 (in or outside of the ns macro)

20:51 brehaut: oh. huh.

20:51 mattmitchell: if anyone knows the enlive html library -- is there any way to have classic template tags embedded in the html template?

20:52 brehaut: mattmitchell: you mean jamming clojure code into your markup?

20:52 mattmitchell: brehaut: well, i not necessarily. I'd be happy with simple placeholders like @title etc..

20:53 brehaut: mattmitchell: place holders is done with elements

20:53 mattmitchell: trying to find a way to allow a cms user embed pre defined tags

20:53 brehaut: say you have a blog snippet, you might have <section class="blog"><h2>title</h2></section>

20:55 you could then have a defsnippet with [:.blog :h2] (content title)

20:56 and [:.blog :h2] (after content)

20:56 (flying by memory there with after)

20:56 (you might be better off with [:.blog] (append content)

20:57 mattmitchell: the result is that instead of having magic text in your structured markup, you are using the classnames and whatever to achieve similar results.

20:57 mattmitchell: brehaut: yeah totally, that makes a lot of sense. your example looks nice. i think i'll just have to spend the night reading the enlive docs!

20:58 brehaut: mattmitchell: have you followed dnolen's tutorial?

20:58 mattmitchell: brehaut: not completely! maybe i'll finish that up first.

20:59 brehaut: its worth the effort IMO

21:31 mattmitchell: what is the main diff between an array map and a hash set?

21:31 brehaut: appart from one being a map and the other a set?

21:33 ,[(hash-set :a 1 :b 2) (array-map :a 1 :b 2)]

21:33 clojurebot: [#{1 2 :a :b} {:a 1, :b 2}]

21:34 mattmitchell: brehaut: thanks. interesting. I think i'm confused because a hash in languages i've worked with are maps, so mixing hash and set together caused a little confusion.

21:34 brehaut: if that doesnt answer the question: a map is a mapping from keys to values, where a set is a group of things. the keys of a map form a set for instance

21:35 the prefix tells you the implementation choice

21:35 you dont need to care most of the time

21:35 clojure also has ##(hash-map 1 2 3 4)

21:35 sexpbot: ⟹ {1 2, 3 4}

21:35 brehaut: both array-maps and hash-maps are persistentmaps

21:36 and the system choses the implement based on the number of items and will change implementation silently as dictated by usage

21:37 mattmitchell: brehaut: that's really nice. good to know!

21:46 ieure: Aaaaaargh. Is there some non-horrible way to line-seq to read from *in* or System/in ?

21:47 This should be simple, but Java’s type system is fucking me in the ear.

21:47 Cannot create a BufferedReader from System/in.

21:47 Calling (reader System/in) returns an empty seq even when there’s stuff sent to sedin.

21:47 amalloy: &(class *in*)

21:47 sexpbot: ⟹ clojure.lang.LineNumberingPushbackReader

21:48 ieure: Er, (line-seq (reader System/in))

21:48 amalloy: &(supers (class *in*))

21:48 sexpbot: ⟹ #{java.lang.Readable java.lang.Object java.io.FilterReader java.io.PushbackReader java.io.Closeable java.io.Reader}

21:48 amalloy: ieure: it's a reader, so wrapping it in bufferedreader should work. are you trying to do this from slime?

21:49 ieure: amalloy, No, I can’t send anything to stdin there. It’s in my -main method in a Leiningen project.

21:49 brehaut: amalloy: line-seq *in* throws a classcastexception

21:50 (use '[clojure.java.io :only [reader]]) (line-seq (io/reader *in*))

21:50 ieure: (line-seq (reader *in*)) just gives me an empty list.

21:50 I wonder if this is a leiningen thing.

21:50 I’m using `lein run' and piping stuff to it.

21:51 Ugh, fuck. It is.

21:51 Works fine with `java -jar'.

21:51 devn: my coworker described namespaces as "state" -- what say you?

21:52 ieure: devn, Seems incorrect on its face.

21:52 pdk: that's

21:52 um

21:52 a unique way to interpret them

21:53 devn: i know it's ridiculous, but he makes an argument which i've never heard, which is that if you define the ns at the top of a file, it is ieffectively setting the context in which functions will be defined

21:53 and therefore qualifies as state

21:53 i dont agree with it, but im curious what other people have to say about it

21:53 brehaut: devn in the exact same way that any lexical scope is defined though surely?

21:54 eg (let [foo 1] (defn add-foo [x] (+ x foo))

21:54 you wouldnt call foo state, but that seems to me to be no different than defining the namespace

21:57 devn: brehaut: he's never used clojure, so my assumption is that he saw that (ns ...) didn't wrap the (defn) that came later in the file and so on

21:57 so he saw it as being a stateful thing

21:57 brehaut: would he agree that (def foo 1) (defn add-foo [x] (+ x foo)) is not state?

21:58 devn: i can ask him when he's done playing guitar hero

21:58 brehaut: state is context but not all context is state right?

21:59 phenom_: what's the easiest way to run some defntest's I've got in a clj file ?

21:59 brehaut: phenom_: is it a lein (or presumably cake) project?

22:01 devn: brehaut: he has conceeded

22:01 brehaut: woo :)

22:01 devn: conceded*

22:01 phenom_: brehaut: why do you presume cake? :P

22:02 devn: brehaut: it took me by surprise at first because yes, as you say, context is not state -- it depends on how you wish to define statefulness

22:02 brehaut: phenom_: im presuming cake behaves the same as lein in this instance

22:02 devn: you might say that a (let ...) is a state, but that would incorrect for most intents and purposes

22:02 ieure: Can someone point me to a clear example of how -> and ->> work? The documentation is completely inscrutable. I have no idea what they do or why I’d want to use them.

22:03 brehaut: ieure: they rewrite your forms. (-> a (b) (c)) becomes (c (b (a)))

22:03 thats a terrible example

22:03 seancorfield: they are convenient when you want to apply a sequence of operations to the same thing, one after the other

22:03 amalloy: &(macroexpand-all '(->> (range) (filter even?) (take 100) (reduce +)))

22:03 sexpbot: java.lang.Exception: Unable to resolve symbol: macroexpand-all in this context

22:03 amalloy: &(use 'clojure.walk)

22:03 sexpbot: ⟹ nil

22:03 amalloy: &(macroexpand-all '(->> (range) (filter even?) (take 100) (reduce +)))

22:03 sexpbot: ⟹ (reduce + (take 100 (filter even? (range))))

22:03 amalloy: ieure: ^

22:04 brehaut: devn: i think if you are unfamiliar with pervasive immutability its reasonable to make that assumption i think

22:04 seancorfield: the difference is that -> puts the 'thing' as the first argument in each call and ->> puts the 'thing' as the last argument in each call

22:05 &(macroexpand-all '(-> x f g h))

22:05 sexpbot: ⟹ (h (g (f x)))

22:06 ieure: Is macroexpand-all in -contrib somewhere?

22:06 seancorfield: &(macroexpand-all '(-> x (f a b) (g c d) (h e f)))

22:06 sexpbot: ⟹ (h (g (f x a b) c d) e f)

22:06 amalloy: ieure: you just saw me (use 'clojure.walk), right?

22:06 * devn is sad trying to explain clojure to his coworkers

22:06 seancorfield: &(macroexpand-all '(->> x (f a b) (g c d) (h e f)))

22:06 sexpbot: ⟹ (h e f (g c d (f a b x)))

22:07 brehaut: devn my solution to that problem was to stop having coworkers

22:07 ieure: amalloy, I didn’t realize that the bot had persistent state like that.

22:07 devn: i think one unfortunate thing we need to really approach as a community is how we mention immutability in passing

22:07 people hearing immutability and have no idea how to approach a world that looks like that

22:07 * seancorfield is lucky that his coworkers trust him (and sort of get clojure a little bit)

22:07 ieure: devn, It is incredibly daunting at first.

22:08 Then you play with it and realize that you don’t need nearly as much as you thought.

22:08 devn: ieure: it's taken me 2 years from 0 to lisp to "get" what was going on here

22:08 i dont blame anyone

22:08 seancorfield: devn: true, when folks are used to writing for (x = 1; x < 10; ++x) doSomething(x);

22:08 ieure: devn, I make zero claims that I know what is going on here. :)

22:08 devn: it's just something that is so undervalued and misunderstood

22:08 brehaut: seancorfield: at my last job i wrote a nice little F# program. i had to rewrite it in VBS.

22:08 devn: ieure: i think that's funny

22:08 seancorfield: brehaut: my sympathies

22:08 devn: ieure: it's scary, but we're smart

22:09 brehaut: seancorfield: its not all bad. i got to write it in F# first ;)

22:09 devn: ieure: btw, thank you for your php-repl

22:09 :X i hate to admit i used that at one time

22:09 ieure: devn, Ha, you’re welcome.

22:09 devn: but thank you :)

22:09 amalloy: ieure: oh, is that yours? i was using it just today

22:09 mattmitchell: php-repl?

22:09 devn: it's a repl, but you know, for a shitty language

22:09 ieure: mattmitchell, An attempt to make a REPL for PHP that wasn’t horrible.

22:10 mattmitchell: haha :)

22:10 why not?

22:10 devn: either way, ieure is awesome

22:10 everyone should remind him of how awesome he is more often

22:10 IMO

22:10 ieure: Jesus, I had no idea I had a fan club.

22:10 devn: ieure: it's not a fan club *yet* :)

22:11 im just happy to see you around these parts -- i hope you'll stick around

22:11 ieure: Oh, I’ve been meaning to get serious about Clojure for a long time. Still haven’t had much reason to do that, though.

22:11 seancorfield: brehaut: i often prototype something in clojure to make sure i understand the problem and have then been coding it in "language X" for production use

22:11 ieure: But I’ve been screwing around with it the last couple weeks when I felt like it.

22:11 seancorfield: but that will change... clojure is coming to production soon :)

22:11 mattmitchell: ieure is awesome. brehaut is too. i'm amazed at how i can ask dumb questions and get a serious answer here. very helpful.

22:12 devn: the thing that's missing big time in clojure ATM is a CRUD-like setup for web development

22:12 seancorfield: ieure: btw, did amalloy and i help answer the -> / ->> question?

22:12 brehaut: mattmitchell: i wouldnt say im awesome. ive just made the dumb mistakes before you did ;)

22:12 mattmitchell: brehaut: :)

22:12 devn: ieure: can i make a suggestion on -> and ->>?

22:12 ieure: devn, of course.

22:12 devn: ieure: https://github.com/tcrayford/clojure-refactoring

22:12 ieure: seancorfield, I do not fully understand it yet. But I don’t know if anyone can help me with that just yet.

22:12 seancorfield: devn: well, i plan to use clojure for the Model portion of an MVC web app with the VC portion written in CFML :)

22:13 ieure: I learn by doing.

22:13 devn: get that. play with thread-first and thread-last

22:13 you can write some code and automatically refactor to -> and ->>

22:13 it helps you see how it works and gives you insight into when to use it

22:13 also ieure, another link:

22:14 brehaut: seancorfield: wait. cold fusion?!

22:14 seancorfield: yup, although it's been one word not two for a decade or so

22:14 devn: ieure: https://github.com/raganwald/homoiconic/blob/master/2008-10-30/thrush.markdown

22:14 seancorfield: i use the railo open source cfml engine (it's a jboss project)

22:15 ieure: Okay, I think I see what -> is doing now.

22:15 devn: ieure: -> and ->> are simply ways of reversing the order of computation

22:15 so it reads left to right

22:15 brehaut: devn: ieure http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/

22:16 devn: brehaut: great link

22:16 ieure: Yeah. So if I understand, I can use that to create with partial to create a nested function to map across a seq.

22:16 devn: ieure: id need a repl to test that because im not a magician or a god or anything when it comes to programming

22:16 brehaut: ieure: with thrush yeah; its a point-free operator

22:17 devn: but the basic idea if you get to switch up the order and read left to right

22:17 i have a much more abstract idea of how it works i guess

22:17 *shrug*

22:18 btw, On explaining clojure to coworkers in an OOP mindset: Practical Clojure does an excellent job of covering the how and why

22:19 ieure: devn, I also found the introduction to Programming Clojure to be a good introduction.

22:19 devn: modularity, polymorphism, encapsulation, reusability

22:20 "objects everywhere" really screws up the implementation of these ideas on their own

22:20 brehaut: devn Stuart Halloway's Clojure Conj presentation might also be good

22:20 devn: brehaut: i was there :)

22:20 brehaut: is that online yet?

22:20 brehaut: lucky bastard :)

22:20 it is

22:20 devn: link please!

22:21 stuart -> pure awesome

22:21 such a gracious host with a wonderful family and what i could only characterize as a heartfelt commitment to the community writ-large

22:22 brehaut: … taking longer to find this than i thought

22:23 * devn has probably said too much at this point

22:23 seancorfield: http://clojure.blip.tv/?sort=custom;date=;view=archive;user=clojure;nsfw=dc;s=posts;page=1 is it here?

22:23 brehaut: not that i could see

22:24 devn: yeah i dont see it

22:24 bummer -- i loved that talk

22:24 perhaps he's witholding it given the beer that was involved

22:25 probably need to edit out the label or something :D

22:25 brehaut: i know its on the web somewhere

22:25 try http://www.infoq.com/presentations/Clojure-Java-Interop ?

22:25 seancorfield: stuart's talk... simplicity ain't easy?

22:26 devn: that's the topic

22:26 brehaut: sorry, ive got extrodinarily slow internet

22:26 devn: but i dont know of any video on it yet

22:26 seancorfield: i don't see it on blip.tv so it may not have been released yet

22:27 but these two talks might be useful for OO folks: http://clojure.blip.tv/file/982823/ and http://clojure.blip.tv/file/982957/ - clojure for java programmers parts 1 & 2

22:27 * devn nods

22:27 devn: ive seen those

22:27 id really like to see stuart's talk again, though

22:27 seancorfield: rich's preso to the NYC java study group

22:27 brehaut: https://github.com/downloads/stuarthalloway/clojure-presentations/Clojure-Simplicity.pdf thats the slides anyway

22:27 seancorfield: i had to miss the first conj but i am _not_ missing the second one!!

22:28 devn: :)

22:28 Scriptor: it's in NC, right?

22:28 devn: i refused to miss the first one

22:28 seancorfield: i may even bring one of my coworkers since he'll have had to learn clojure by then :)

22:28 brehaut: id like to not miss any of them, but unfortunately its the wrong hemisphere entirely

22:28 seancorfield: i was already committed to being in albuquerque and los angeles when the dates for the conj were announced :(

22:29 this year i'm keeping september and october free until the conj dates are finalized!

22:29 well, strangeloop is mid-september and javaone is early october... but other than that, i'm free...

22:29 Scriptor: wait, does anyone know where the 2nd conj will take place?

22:29 seancorfield: i expect it'll be the same place...?

22:30 Scriptor: so Durham again?

22:30 argh, I'll stick to the meetups here :)

22:30 seancorfield: according to alan dipert "Conj 2011 will most likely be in either Raleigh or Durham, North Carolina, and probably will happen around the same time of year as the

22:30 last Conj."

22:31 that's from his post to the clojure list on 12/27/10

22:31 at least scala days is close to home for me :)

22:32 but i'm doing conferences in dallas, edinburgh (UK) and minneapolis in february, march, may so this year has a lot of travel in store

22:32 maybe one in kansas city, mo too in july

22:33 scala days in june (locally), strange loop in mid-september in st louis, javaone locally... and clojure conj :D

22:55 ieure: If someone feels like reviewing this code I wrote, I would greatly appreciate being told all the things I did wrong: https://gist.github.com/05f59e7b01f5b0d260f1

23:01 brehaut: nothing obvious jumps out at me

23:02 amalloy: ieure: (apply hash-map (interleave foo bar)) is (zipmap foo bar)

23:03 (partial get some-map) is the same as some-map

23:04 #(first (parse-csv %)) is equivalent to (comp first parse-csv), which imo is more readable but tastes vary

23:06 (. util format ...) is weird to read because it violates the usual "function first" style - i'd write (.format util ...) unless there's some reason you can't

23:07 ieure: amalloy, I have no major reason for doing most stuff there, except that it seems to mostly work.

23:07 I really appreciate the input.

23:07 amalloy: welcome

23:10 oh, and (conj m {:k v}) is (assoc m :k v)

23:10 brehaut: amalloy wins

23:11 amalloy: i should get you to pick apart my code some time ;P

23:12 amalloy: brehaut: do it. i generally enjoy review/editing

23:13 brehaut: amalloy: how about https://github.com/brehaut/clj-pingback/blob/master/src/clj_pingback/client.clj

23:14 ieure: amalloy, Excellent, this is significantly clearer. Thank you very much.

23:14 Any idea why if I change the (println …) to (print …), I get no output whatsoever?

23:14 amalloy: ieure: you need to flush the output stream

23:15 \n automatically flushes by default

23:15 ieure: amalloy, Awesome, thank you. I’m used to Python, where it gets flushed on close/exit.

23:16 amalloy: ieure: i'd sorta expect it to get flushed on close too

23:16 but if it doesn't, that's why :P

23:16 brehaut: (when-let [[_ url] (...)] url) sounds a lot like (second (...))

23:17 brehaut: huh so it is

23:17 amalloy: (fn [t] [t (foo t)]) == (juxt identity foo)

23:19 brehaut: true

23:19 cheers :)

23:20 and more point free :D

23:20 amalloy: hah, and you're importing your necessary-evil project as xml-rpc. i like it

23:20 brehaut: :)

23:21 its the best name ive ever come up with for a project; pitty its wasted on such a lame protocol

23:21 amalloy: brehaut: what about using clojure.contrib.-?>> to replace the when-let/if-let construct?

23:22 brehaut: sorry, which function?

23:22 amalloy: that is, c.c.core/-?>>

23:22 brehaut: sorry, in the pingback code

23:22 amalloy: in discover-pingback-endpoint

23:22 brehaut: oh right

23:23 i think i could replace it with or actually

23:24 amalloy: brehaut: i don't think so, cause you reuse url

23:24 brehaut: im not though, i accidentally masked it in the when-let

23:25 which was replaced with (second ...) anyway

23:25 amalloy: ah

23:27 brehaut: so that if-let is now (or (get-in response [:headers "x-pingback"])

23:27 (second (re-find link-pattern (:body response))))

23:29 amalloy: i just pushed the changed code

Logging service provided by n01se.net