#clojure log - Dec 10 2009

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

0:00 hiredman: maybe the equiv of java blocks, whatever those are at the bytecode level

0:00 alexyk: the outer map is guaranteed to contain inner maps which have only one key-value pair

0:01 um, or not

0:03 hiredman: ,(.replace #"\." "foo.bar" "/")

0:03 clojurebot: java.lang.IllegalArgumentException: No matching method found: replace for class java.util.regex.Pattern

0:04 twbray: Hey, is there a Gary W. Johnson around here? He submitted a cool comment on my blog but I tried to get too cute and b0rked it.

0:04 cp2: ,(.replaceAll "foo.bar" "\\." "/")

0:04 clojurebot: "foo/bar"

0:05 hiredman: cp2: I know

0:06 I just checking Pattern

0:07 cp2: i figured, but im just in such a helpful mood

0:07 hiredman: :)

0:07 cp2: well thats a lie, its more of im bored

0:09 arohner: if I have a map, and I want to swap the keys and values, that's called the inverse, right?

0:09 mathematically speaking

0:10 hiredman: ,(doc clojure.set/map-invert)

0:10 clojurebot: "([m]); Returns the map with the vals mapped to the keys."

0:10 arohner: oh, nice

0:10 I searched for inverse, not invert

0:10 thanks

0:10 hiredman: weird that it's over in set

0:10 arohner: incremental search++

0:11 arohner: incremental search on the API page?

0:11 I just did (find-doc "inverse")

0:12 hiredman: ah

0:12 yeah, I was on the api page in firefox

0:12 typing incremental very slowly

0:12 er

0:13 inverse

0:14 defn: crap -- i accidentally committed all of my damn .jar files, is there any way to get rid of them in the current commit so i dont have to push them?

0:14 arohner: make your changes, then git commit --amend

0:15 it will squash the new commit into the old commit

0:15 but it's not a good idea to do that if you've already pushed

0:17 defn: wow wtf, .gitignore is not properly ignoring my .jar files

0:18 i have *.jar ..jar and lib/*.jar in .gitignore

0:18 dakrone: hmm..is there a repository for misc clojure libraries anywhere?

0:18 defn: github

0:18 dakrone: besides clojars, I mean something sort of like 'gem search <foo>'

0:19 defn: nah, nothing besides that that i'm aware of

0:19 but that's a cool idea

0:19 dakrone: I wrote a library and published it on clojars, but other than that is there anywhere else new libraries are announced?

0:19 defn: disclojure

0:19 twitter #clojure

0:20 dakrone: okay, did that also

0:20 defn: as long as you're talking about it

0:20 what's your library? :)

0:21 dakrone: http://writequit.org/blog/?p=332

0:23 hiredman: goto's and labels in a stack language is just weird

0:24 cp2: not to mention ugly

0:24 and potentially hazardous :)

0:25 hiredman: I am adding stack comments so I can keep track of what is on there, this could get complicated

0:28 defn: dakrone: cool

0:29 im working on http://github.com/defn/cljex right now

0:30 dakrone: defn: looks very useful, looking forward to it

0:30 defn: nothing fancy, it's just going to be a simple compojure + markdown w/ pygments syntax hilighting

0:30 cp2: interesting

0:30 defn: no need to drag your feet, fork it and start writing examples :)

0:31 dakrone: heh

0:31 defn: lots of low hanging fruit yet :)

0:31 dakrone: have you thought about copying some of the examples from http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples ?

0:31 defn: yep, i talked to timothypratley1 about it

0:31 that's in the plan

0:32 dakrone: cool, I find that very useful

0:32 defn: eventually id like to make the examples tagged

0:32 so you can click on something like "bit-twiddling" and get a list of all the forms that involve bit-* etc.

0:33 it's really nice for new people to the language to have some sort of real world example of how to use a form, especially for non lispers

0:33 dakrone: yea, it'd be nice to have multiple examples for each API function, a simply one leading up to a more complex one

0:33 defn: i found a lot of the terse API documentation where it says something like ([s idx coll]) to be daunting

0:34 yeah exactly, i was thinking something along those lines, but i mean, as it stands right now, it's just a markdown document with syntax hilighting builtin

0:34 so you can add whatever you want for the form, link to stuff, etc.

0:34 technomancy: chouser: did I hear you decided on a title?

0:35 defn: i just put up that example form as a rough guide to how they should in their most basic form be setup

0:42 alexyk: how do I turn a map, {:a {:b [1 2 3] :c [5 6]} :b {:c [7] :d [9 10]}} into a seq: [[[:a :b] [1 2 3]] [[:a :c] [5 6]] [[:b :c] [7]] [[:b :d] [9 10]]] ?

0:43 i.e. path to leaves becomes the first element of the tuple, leaf the second, the whole map unrolled into a seq

0:43 hiredman: very carefully

0:44 alexyk: hiredman: what's the basic zipper function?

0:44 somnium: ,(use 'clojure.walk)

0:44 clojurebot: nil

0:44 hiredman: clojure.zip has the zipper stuff

0:45 alexyk: how do I see what's in clojure.zip or clojure.walk?

0:47 replaca: alexyk: look at the clojure API docs

0:47 alexyk: kk

0:48 replaca: you might want to look at heut's "functional pearl" about zippers too, to see what they are cause the doc strings aren't too helpful.

0:49 hiredman: you can always take a look at the source

1:13 replaca: with the huet paper in hand, the source is really clear

1:16 hiredman: if you can read haskell

1:16 defn: hey hiredman i think i asked this earlier maybe, but how do you get emacs to auto-indent on return in clojure-mode?

1:17 technomancy: defn: (define-key lisp-mode-shared-map (kbd "RET") 'reindent-then-newline-and-indent)

1:17 bonus: works in elisp, scheme, etc

1:17 defn: awesome, thanks

1:19 technomancy: defn: tempted to make that the default binding in clojure-mode actually

1:20 defn: technomancy: that makes good sense to me

1:20 technomancy: it's unconventional, but there are times to break the mold. =)

1:21 defn: if anyone gets upset about it, politely remind them there are comments, and that they can comment that piece out

1:21 btw i think it was one of your repos that linked to the lisp style guide

1:22 i was going to ask you about compojure, specifically using html and html-tree

1:23 replaca: hiredman: the huet paper is actually OCaml (which I don't know), but when I combined it with Rich's implementation it all seemed pretty clear

1:23 defn: in some cases you wind up with code like: [:html [:head [:title "foo"]] [:body [:h1 "bar"] [:p "Hello baz."]]]

1:23 hiredman: replaca: really, I could have sworn

1:23 replaca: technomancy: I would vote yes to that

1:24 defn: what's weird is that we're representing this DSL with clojure, so it seems like indenting and treating closing ]'s as we would XHTML makes sense

1:24 but i wonder what the lisp style guide's view on such a thing would be

1:24 technomancy: replaca: that makes three of us. done.

1:25 replaca: three stooges carry the day :-)

1:25 technomancy: defn: well in HTML it's more than a single char

1:25 so grouping them together is hard to read

1:25 replaca: (or maybe three musketeers)

1:25 technomancy: plus there's no paredit for html

1:25 (yet... I guess. (!))

1:25 defn: haha you love your paredit

1:25 replaca: +1e9 for paredit

1:26 technomancy: defn: well, that is to say it's far easier to make your editor smart about parens than about closing XML tags

1:26 defn: i was editing for awhile without paredit, i actually am kind of freaked out now when i get an automatic paren, or i have to type the close paren to move forward

1:26 technomancy: i think HTML5 will make it easier to do things like that

1:26 (maybe)

1:27 some of the new tags seem like you'd be able to infer at which point it ought to close based on the structure of the document

1:27 (assuming it's good valid html5)

1:27 tomoj: that's still harder than parens

1:27 defn: heh, no argument from me there

1:27 just thinking out loud

1:27 tomoj: I don't like the indenting you get with that style html

1:28 technomancy: considering nxml is a full XML parser, I think someone will eventually implement it, but that's beside the point. =)

1:28 tomoj: [:html

1:28 [:head

1:28 [:title "Foo"]]]

1:28 replaca: tomoj: that's how i'd do it

1:28 tomoj: guess it's not so bad, but I'd prefer the two spaces you get with (

1:29 defn: what about

1:29 [:title "Foo"]

1:29 ]

1:29 ]

1:29 replaca: defn: ugh!

1:29 technomancy: defn: since each closing bracket is interchangable with another it's very different from closing XML

1:29 defn: i cringe a little bit, but i also see that being a more manageable syntax for larger nested stretches

1:30 mee: am I the only one that thinks building html like this is a terrible idea? What happens when you need actually complicated html?

1:30 defn: technomancy: that's a fair argument

1:30 tomoj: mee: I don't like it much either

1:30 defn: but at a certain point i think you hit a maximum # of ['s and ]'s where it becomes not just preferred, but advantageous to the way i demonstrated above

1:31 advantageous to use the way*

1:31 replaca: mee: in general I prefer doing things with a templating engine (like enlive) that lets you write HTML directly and just inject the dynamic parts

1:31 technomancy: defn: you'll have to explain the advantages in more detail; I don't think anyone else is seeing it. =)

1:31 replaca: but I think that's a matter of taste

1:32 defn: technomancy: let's assume you have a deeply nested structure of ['s and ]'s

1:32 let's say, a 150 line def x, which is some massive (html [:html...) structure

1:33 i think at a certain point, even with paredit, just the way you can scan chunks more efficiently if you have the lone ]'s to give you some sort of idea of where contexts switch at a glance

1:35 replaca: defn: you sound like a C guy basing python :-)

1:35 *bashin

1:35 *bashing

1:35 defn: i guess i just believe that when it comes to HTML, as far as how ive always read and understood it, i always tended to see it as a sort of structure, like a real physical structure, rather than an abstract machine

1:37 i always sort of saw the levels as being like floating planes, one above another, floating on the same layer, etc. to me the sort of structure that XHTML always seemed pretty spot on

1:38 bleh, the structure of XHTML always seemed spot on

1:39 i hate the <a></a> stuff, but for the thing it is describing, namely a web page, it always seemed like the right way to go, so i struggle a little bit with that decision in compojure

1:40 tomoj: well, no need to struggle

1:40 you can write your html in html if you like :)

1:47 somnium: ,(-> [:p "foo" :p] butlast vec)

1:47 clojurebot: [:p "foo"]

1:48 somnium: defn: you could always write a macro that lets you close the tags :P

1:52 alexyk: how do you join two seqs?

1:52 hiredman: clojurebot: how do you join two seqs?

1:52 clojurebot: You will not become skynet

1:52 hiredman: bah

1:52 clojurebot: how do I join two seqs?

1:52 clojurebot: with style and grace

1:52 hiredman: concat

1:52 ,(concat [1] [2])

1:52 clojurebot: (1 2)

1:53 alexyk: thx!

1:53 defn: tomoj: sure i can, what im trying to explain and/or see if there is any sympathy for, is whether or not when writing code in any language that will in the end behave like a different language, it is acceptable to break convention for readability

1:53 it seems like a fuzzy topic

1:54 if it is acceptable*

1:54 tomoj: I have no sympathy

1:55 but I won't come arrest you

1:55 defn: in other words, does it make more sense to write html using clojure that looks like html, or should it look like clojure

1:56 alexyk: btw, here's the transform I needed: (reduce (fn [r0 [from repliers]] (concat r0 (reduce (fn [r1 [to dates]] (conj r1 [[from to] dates])) [] repliers))) [] {:a {:b [1 2 3], :c [5 6]}, :b {:c [7], :d [9 10]}})) => ([[:a :b] [1 2 3]] [[:a :c] [5 6]] [[:b :c] [7]] [[:b :d] [9 10]]); improvements welcome!

1:58 btw compared to scala, almost gibberish. Scala looks like: coll.foldLeft(init)(fun)

1:58 defn: {:a {:b [1 2 3] :c [5 6]} :b {:c [7] :d [9 10]}} into a seq: [[[:a :b] [1 2 3]] [[:a :c] [5 6]] [[:b :c] [7]] [[:b :d] [9 10]]] was what you started with, yes?

1:59 alexyk: I need that transform, yes

1:59 tomoj: is it always two levels?

1:59 alexyk: nested map with leaves into path and leaf tuple. always two levels, yes

2:00 replaca: alexyk: why can't you write it the same in Clojure? Can't you just write foldLeft?

2:00 alexyk: replaca: foldLeft is called reduce in Clojure

2:00 defn: :)

2:01 clojure is missing the foldr iirc

2:01 but it's easy to write

2:02 somnium: alexyk: what is 'fun in your scala example?

2:02 alexyk: somnium: fun is the nested foldLeft. I'm just saying it's visually shifted into suffix positions and easier to parse. I had a bitch of a time with ))) [] in the middle

2:02 counting blinkin' )'s

2:04 replaca: alexyk: that's right -> I'm tired and forgetting my haskell :-)

2:05 alexyk: yeah, I'd break up something that complex

2:05 alexyk: newlines are for babies

2:05 replaca: waah!

2:06 alexyk: one-liners can be pasted into IRC easiy :)

2:06 that's why we have sexps in the first place -- to avoid paste

2:09 defn: alexyk: did you think about using (get-in)?

2:09 alexyk: defn: first time hearing of it!

2:10 defn: i think it might save you some space

2:10 tomoj: alexyk: (apply concat (for [[k1 v1] m] (for [[k2 v2] v1] [[k1 k2] v2])))

2:10 defn: ,(def k {:a {:b [1 2 3] :c [5 6]} :b {:c [7] :d [9 10]}}

2:10 clojurebot: EOF while reading

2:10 defn: ,(def k {:a {:b [1 2 3] :c [5 6]} :b {:c [7] :d [9 10]}})

2:10 clojurebot: DENIED

2:10 defn: damn

2:11 alexyk: clojurebot: why can't we def globals?

2:11 clojurebot: http://clojure.org/rationale

2:11 alexyk: ,ohshutup

2:11 clojurebot: java.lang.Exception: Unable to resolve symbol: ohshutup in this context

2:11 defn: (get-in k [:a :b]) => [1 2 3]

2:12 alexyk: defn: looks like useful for random access, but for a whole sweep less efficient (descends all over)

2:13 defn: yeah, i thought it might work if you were always going like [:a :b] [:a c] [:b :c] [:b :d]

2:13 alexyk: tomoj: what do I do with the (apply concat...) form above?

2:13 defn: err rather, that's kind of a pattern i saw by using (get-in)

2:13 which seemed curious

2:13 tomoj: alexyk: (def alex [m] (apply concat ...))

2:13 (alex {:a {:b ...]])

2:14 alexyk: hmm...

2:15 you mean defn. wow!

2:15 tomoj: oh, yeah

2:15 alexyk: Palm d'Or goes to tomoj! nice

2:16 tomoj: 'course naming the variables sensibly might help its readability

2:16 alexyk: yeah, clearer than the reduces

2:18 defn: (def alex [m] (apply concat (for [[k1 v1] m] (for [[k2 v2] v1] [[k1 k2] v2]))))

2:18 is that what you're saying?

2:19 alexyk: defn: s/def/yournick/ :)

2:19 defn: oh the irony

2:19 alexyk: sorry couldn't help it

2:19 defn: damn that is nice tomoj

2:19 alexyk: btw this is a graph transform, from adjacency lists to triples

2:19 defn: what are adjacency lists and triples?

2:19 *(wikipedia articles graciously accepted)

2:20 alexyk: graph representations

2:20 http://en.wikipedia.org/wiki/Adjacency_list

2:20 defn: ahhhh

2:20 * alexyk is sure clojurebot has a better way to invoke wikipedia

2:21 defn: so that's where i was getting the a ajd b,c -- b ajd a,c -- c adj a,c

2:21 c ajd a,b

2:22 alexyk: yep. And for triples we just zip followers with head into pairs. If edges are labeled, then it's triples, with the edge weight.

2:23 defn: what is the edge weight?

2:24 alexyk: it's any label on an edge. E.g. bandwidth, timestamp -- whatever your relationship represents in the graph by an edge, if it's quantitative.

2:24 defn: ah ok

2:25 alexyk: ok, sleepy time... cya'll tmrw!

2:26 ordnungswidrig: aloha

2:32 does anybody know of work on the topic of update of persistent data structures? especially for business models in pers. ds?

2:40 tomoj: huh?

2:40 defn: could you be more specific about "business models" and "update of persistent data structures"

2:41 ?

2:44 adityo: ~max people

2:44 clojurebot: max people is 240

2:44 twbray: I hear persistent data structures were up on Wall St. today.

2:44 adityo: any links

2:48 AndChat|: most work i found is about simple ds like tries, hashtables etc. the update semantic for them is clear to me: you get a updated 'copy' of the hashtable.

2:51 ordnungswidrig: brb: have to switch trains

2:54 re

2:55 if you model some business objects with persistent ds then the deep update of an object has no clear semantic to me.

2:57 say, you have customer->order->shippingaddress and you do an update on the address. what will the update return? a shippingadress, an order, a customer or a some reference to a 'world' object?

3:00 somnium: ,(update-in {:a {:b {:c 1}}} [:a :b :c] inc)

3:00 clojurebot: {:a {:b {:c 2}}}

3:01 somnium: if its in a ref/atom/agent then its also persistent

3:02 ordnungswidrig: somnium: so you basically treat the whole world as an opaque ds which is updated.

3:02 i wonder how that can scale regard model size and concurrent modifiers

3:03 cp2: zzzz

3:04 somnium: not the whole world, however you choose to make it discrete

3:06 tomoj: if you have the whole world in a single reference type concurrent writers that might not really conflict with each other (i.e. they're working on separate unrelated parts of the world) will have to fight

3:19 mcodik:  /quit

3:24 ordnungswidrig: re

3:25 so, finished juggling with the clients

3:36 tomoj`: does this sound evil to you? a macro unhygienically defonce's a var holding an atom into the using namespace and each use of the macro swap!s the atom. later, another macro is called from the using namespace which takes the value of the atom and sends it off to the internets

3:36 sounds evil to me :(

3:38 tomoj: now that I say this out loud the solution is obvious.. just let the users pick what atom to use

3:38 ordnungswidrig: somnium: still there?

3:42 somnium: ordnungswidrig: pong

3:43 ordnungswidrig: somnium: we left at the question what is the "scope" of an update in a persistent datastructur.

3:45 somnium: ordnungswidrig: have you watched rich's talks on state and identity?

3:46 ordnungswidrig: somnium: yes, and I think I understand it.

3:48 however in a business object model I find the concept of identify not clear for a business model. at last it is not unambigous.

3:50 Say, you have customer1->order1->item and customer2->order2->item now what shall be semantic when I change item? Item has in a sense two identities which can be told apart by the path it it.

3:50 s/it it/to it/

3:50 hiredman: why does a customer contain an order?

3:50 cark: wouldn't your object reside in a database in a business setting ?

3:51 ordnungswidrig: hiredman: just an example

3:51 hiredman: well, for example, stop nesting stuff

3:51 ordnungswidrig: cark: can be

3:51 hiredman: but the stuff in the world is nested, isn't it?

3:51 hiredman: nope

3:52 ordnungswidrig: hiredman: so you would cut the graph and reference by an uri?

3:52 hiredman: sure

3:52 cark: i used to think hard about this, but for real programs it never bit me

3:52 hiredman: if you have ever looked at a customer order, they don't come with customers

3:52 they come with customer ids

3:52 which is an account number

3:53 a reference to a customer

3:53 ordnungswidrig: hiredman: sure, so you say the scope of an update would be a single "entity"?

3:53 hiredman: I really don't understand what the big deal is

3:54 I mean, the "scope" of an update is what it updates

3:54 ordnungswidrig: I see, so the modeling problem is to define the sope of the updates and make every scope identifiable by an URI

3:55 hiredman: an "update" on an immutable object doesn't update anything

3:55 since an update implies change and immutable objects don't

3:55 ordnungswidrig: I know, tell it "derive"

3:56 I was toying around with the ideas of persistent datastructures and business object modeling. I wonder how they would go togehter.

3:56 somnium: ordnungswidrig: the modeling could just resemble a relational id

3:56 hiredman: exactly

3:56 somnium: relational db I mean

3:56 hiredman: it's just like a db

3:56 have you seen any of the papers on whats it called, functional relational programming

3:57 cark: that all fine for business modeling, how about simulation modeling, when you want to have "objects" ?

3:57 hiredman: http://lambda-the-ultimate.org/node/1446

3:57 ordnungswidrig: cark: that's a good point!

3:58 cark: in simulations you'd expect to have a well defined "world state", wouldn't you?

3:58 _ato: hmmm my naive Clojure atoms + hashmaps + pmap implementation of twbray's widefinder 2 performs roughly the same as WideFinder2d.scala on a quad core xeon with a several gb log file. Probably need a gruntier box to experience the gc hell he's talking about, we only seem to be losing 5-10% to the GC on the quad core. _mst adjusted it to use ConcurrentHashMap (which the Scala version uses) and it seems slightly faster than the Scala

3:58 version

3:58 cark: right

3:58 ordnungswidrig: hiredman: thanks for the link. I suppose this is what I was looking for

3:59 twbray: _ato: Have found a much better set of JVM options, things are improving. I shouldn't write when I'm discouraged.

3:59 _ato: post your code, I'll run it on the big data

3:59 hiredman: cark: you've seen ants.clj, yes?

3:59 cark: yes

4:00 though it has been a year at least

4:00 hiredman: it's essentially oop - mutability

4:00 if I recall

4:00 cark: right, but it's very non-functional

4:00 hiredman: each ant object as map

4:00 ordnungswidrig: cark: assume we have a large model for a simulation, say a mmorpg. there will be a lot if stuff that can change

4:01 _mst: twbray: I'd be interested to know your jvm options. I don't think any of the JVM knobs we twiddle made a huge impact (right, _ato?)

4:01 hiredman: cark: the state updates are all functions, and the state is always an immutable value

4:01 that is kind of the whole point

4:01 cark: that's a matter of deciding at which granularity we cease being functional and start being statefull

4:01 ordnungswidrig: hiredman: for a deep model, every update will lead to a now "root" state reference, right?

4:01 _ato: _mst: yeah, mark and sweep concurrent gc just slowed it down a bit

4:02 twbray: _mst: Will publish. Turned out I get better results by letting JVM choose its own GC strategy, just fiddling with -Xmx and -Xms.

4:02 cark: ordnungswidrig : that's not the case in the ants simulation

4:02 _mst: ah yeah, that's consistent with what we saw too

4:02 defn: ,*feeling lucky*

4:02 clojurebot: java.lang.Exception: Unable to resolve symbol: *feeling in this context

4:02 ordnungswidrig: cark: can we be function in the whole and still manage the hot "root" reference?

4:02 _ato: twbray: okay, I'll post it shortly, just gotta change the regexes back to match your data

4:02 hiredman: cark: I think ordnungswidrig would call ants a shallow model

4:02 ordnungswidrig: hiredman: yes

4:02 defn: ,*feeling-lucky*

4:02 clojurebot: java.lang.Exception: Unable to resolve symbol: *feeling-lucky* in this context

4:02 twbray: _ato: Or if you'd rather, you can have an account on the big machine

4:03 hiredman: clojurebot: click

4:03 clojurebot: Pardon?

4:03 hiredman: clojurebot: *click*

4:03 clojurebot: It's greek to me.

4:03 hiredman: hmmm

4:03 cark: i'd be interested to see a deep purely functional model with errr tengential references

4:03 hiredman: clojurebot: roulette

4:03 clojurebot: click

4:03 hiredman: clojurebot: roulette

4:03 clojurebot: click

4:03 hiredman: clojurebot: roulette

4:03 clojurebot: bang

4:03 ordnungswidrig: cark: tangential?

4:04 cark: say customer->orders->order->items->item and stock->items->item

4:04 defn: how do you find out where (which namespace) a *blah* is defined?

4:04 cark: items are in two places

4:04 defn: *feeling-lucky* appeared to me in my REPL and im curious where it came from

4:04 cark: how to do this without a whole lot of code to ensure everything is in sync

4:04 _ato: twbray: that would make testing easier :)

4:04 hiredman: defn: do `*feeling-luck*

4:05 ` fully qualifies symbols

4:05 `+

4:05 ,`+

4:05 twbray: _ato: email me, tim dot bray at sun

4:05 clojurebot: clojure.core/+

4:05 ordnungswidrig: cark: yes, that's one the of issues that I see! you must define an update function to decide wheter to branch the identity of item or it must update all references to the updated item

4:05 somnium: cant you have a map of all customers, and a map of all items, and a map of all orders

4:05 each has a primary key of some sort

4:05 ordnungswidrig: somnium: that would be more like a loose model not what I consider a pure functional model

4:05 somnium: and you query it

4:05 defn: *feeling-lucky*/*feeling-lucky*

4:05 that's not very helpful, heh

4:06 cark: right, then you bneed to maintain keys

4:06 ordnungswidrig: somnium: and you'd decide on the update boundaries in advance

4:06 hiredman: defn: you made a namespace *feeling-lucky* and interned a var there

4:06 defn: yeah, i just cant figure out where *feeling-lucky* came from

4:07 ordnungswidrig: somnium: who know wheter you must to keep the shipping address as a separate address instance with its own key, or wheter you better handle the shipping address as a component of the ordeR?

4:07 somnium: ordnungswidrig: that is up to your model

4:07 hiredman: defn: grep your code

4:07 somnium: same question as when you design a database

4:08 cark: my final thought on the subject was this : if i need to emulate a database with the whole key thing, then i should really use a database instead of rewriting this

4:08 tomoj: yeah..

4:08 hiredman: sure

4:08 tomoj: we need the D in ACID anyway so...

4:08 cark: but then i loose the nice properties of a purely functional model

4:08 esj: good morning, House of Clojure.

4:09 cark: for ionstance i'm back at using the mementop pattern for undo =)

4:09 ordnungswidrig: cark: not necesserily. if you can define a patch algebra on the update function then you can do undo/branch/merge in a distributed fashion, like darcs does

4:09 hiredman: cark: STM has ACI alreadying, just need that D

4:09 ordnungswidrig: cark: I was refering to the conclusion to use a rdb

4:10 cark: hiredman : but stm won't allow for easy undo

4:10 i mean with refs for each objects

4:10 hiredman: using datastore with gae I just shove stuff in and pop it out

4:10 cark: datastore with gae ?

4:11 hiredman: google appegine's object store thing

4:11 ordnungswidrig: to be honest, this was the beginning of my thoughts. How would one define a patch algebra on somewhat generic pure functional datastructures. And can one use them to build business object model and work on them in a DVCS style.

4:11 hiredman: it is basically a bag store

4:12 you store bags of properties that have a Kind but can have any key value fields

4:12 cark: i see

4:12 you're using appengine with clojure ?

4:12 hiredman: you can run very simple queries against it

4:12 sure

4:12 (very small facebook apps)

4:13 tomoj: what's the Kind for?

4:13 hiredman: it's like a type tag

4:13 tomoj: ah, but everything's got it?

4:13 hiredman: yeah

4:14 you can query for all the entities of a Kind that have a field with key X set to value Y

4:14 ordnungswidrig: hiredman: the entry on LTU about FRP link to ben moseley's frp page which somewhow morphed into an aikido dojo's website?!

4:14 hiredman: ordnungswidrig: wha?!

4:15 ordnungswidrig: http://ben.moseley.name/frp/paper-v1_01.pdf

4:15 * ordnungswidrig likes aikido

4:15 ordnungswidrig: but I'd rather like to read the paper, atm.

4:16 hiredman: the problem frp is googling you get all the functional reactive stuff

4:16 _ato: twbray: here's what my version looks like: http://gist.github.com/253226

4:16 tomoj: ordnungswidrig: http://web.mac.com/ben_moseley/frp/paper-v1_01.pdf

4:16 ordnungswidrig: re

4:17 tomoj: thanks

4:17 lpetit: yea, aikido rocks

4:18 ordnungswidrig: I see a strong statistical correlation between people doing aikido and functional programming

4:18 lpetit: oh really?

4:18 hiredman: well

4:18 esj: I'm one such

4:18 ordnungswidrig: lpetit: just my personal impression.

4:18 hiredman: I can image a strong correlation between aikido and functional reactive programming

4:19 esj: of course, I do both badly...

4:19 ordnungswidrig: hiredman: *lol*

4:19 lpetit: I used to (for 6 years), but not quite now

4:19 * hiredman is so punny

4:19 lpetit: presumably hiredman is more a tae kwondo fan ? :-)

4:20 hiredman: I did tae kwondo for a year or two

4:20 I know a guy (not well) that ref'ed in the last olympics

4:21 ordnungswidrig: hiredman: there are olympics in functional programming?

4:21 hiredman: :P

4:21 tae kwon do

4:22 aikido does seem interesting, or krav maga

4:23 ordnungswidrig: hiredman: I like aikido because it is in some way a pure concept

4:24 hiredman: mmm

4:25 TheBusby: how do I call merge-with on a list like, ({5 a 6 b} {5 c 7 r} {8 d 9 e}) ?

4:25 hiredman: the sport aspect of tae kwon do bother me the second time I picked it up, because where I was training really emphasised it

4:25 TheBusby: apply

4:26 ordnungswidrig: hiredman: aikido is more like ballroom dancing. you compete with the others but you don't really fight them.

4:27 back to deep functional models and the problem of update scope...

4:27 TheBusby: hiredman: thanks

4:32 twbray: _ato: You'll save a bit of time by doing all those (report) calls with send, they're single-threaded and some of the maps have tens of thousands of keys.

4:34 lpetit: one last word: aikido resembles functional programming, in that in order to really have results with it, you really have to "get it", and it takes more time than other martial arts where some visible side effects are there at the end of the first year.

4:35 ordnungswidrig: lpetit: amen.

4:36 _ato: twbray: ah, cool. I think your logs are probably pretty different to what we were testing with, I'll probably need to tweak things a bit to suit. With ours the report phase was really fast

4:36 twbray: _ato: Well, 245M records :)

4:47 piccolino: Does clojure optimize away something like (if true (something)) to just (something)?

4:55 tomoj: piccolino: why?

4:55 piccolino: I'm writing a macro, and I know the value of the boolean, and I want to know if I should double the length of my code by testing it and writing the output code twice, or if I can trust that clojure will simplify that code.

4:57 tomoj: well, I doubt clojure will simplify it

4:57 perhaps hotspot will

4:58 piccolino: Hm.

4:59 tomoj: is this in the inner loop or something?

5:00 I would be surprised if an extra (if true ..) mattered at all for performance

5:00 piccolino: Yeah, maybe it matters, maybe it doesn't. I'd rather not do an if true every time if I can help it.

5:00 I'm just gonna leave it.

5:03 hiredman: uh, you can have the macro emit one thing for true, and one for false

5:04 you don't have to emit both in an if

5:04 piccolino: I know, that's what I meant above.

5:05 hiredman: ok

5:59 angerman: does anyone know how to tell emacs not to fontify the slime compilation? I'm getting "Fontifying *SLIME Compilation*... (regexps..." and that regexps takes quite some time ...

6:00 tomoj: never seen that :/

6:00 angerman: ok, answereing my own queystion: (setq font-lock-verbose nil)

6:01 at least this way it's in the logs ;)

6:02 tomoj: well it occured since I started using lein swank

6:02 when ever I send something from the buffer to the repl via C-c C-c or C-c C-e i get that line and the regepxs thing goes for nealy a whole screen with dots.

6:03 tomoj: oh, haven't played with lein yet

6:03 I guess I probably should one of these days...

6:04 angerman: I'm really starting to like it. I only need to mod the lein binary to use -server and -Xmx512M ... I guess I'm doing to big problems on the repl ;)

6:05 tomoj: you run lein swank in your project and then M-x slime-connect?

6:05 angerman: exactly

6:05 tomoj: that sounds awesome

6:06 currently with swank-clojure-project every project is forced to act the same way

6:06 somnium: how is it different than swank-clojure-project?

6:07 tomoj: well, I'm not sure that it is, but the fact that you're running it from within the project gives you at least the opportunity to customize per-project

6:08 also, 'sudo -u ... lein swank'

6:08 angerman: yep it automatically sets the correct classpath according to project.clj etc.

6:08 somnium: hmm, I havent figured out how to put new branch in project.clj yet

6:08 clojure-new I mean

6:08 tomoj: for my project that needs to run as a different user I've been starting swank manually with some nasty code

6:09 somnium: ah

6:09 that will come in handy

6:11 liwp: does anyone have any elisp code that will allow you to start a lein project in slime from emacs? I.e. emacs does 'lein swank' for you

6:13 angerman: liwp: M-! lein swank?

6:14 you might want to add & to the end

6:14 liwp: angerman: that won't work since I'm not in the right directory

6:14 ordnungswidrig: angerman: can't "lein swank" be used as inferior-lisp-command or like that in slime?

6:15 liwp: so you'd first have figure out the project root and then start lein swank in that dir

6:15 did technomancy have some swank project elisp function?

6:15 angerman: my elisp-fu isn't that good.

6:16 but yes, best place would be to look around at technomancys website and github repo

6:17 tomoj: the swank project elisp function I know of and associate with technomancy is swank-clojure-project

6:18 liwp: tomoj: yeah, I think that's the same thing. I've copied it to my .emacs and renamed it to clojure-project, but I think it's the same thing

6:18 it looks for pom.xml in the directory tree and uses that as the project root dir

6:19 I guess using lein would allow one to skip all the classpath setup stuff that swank-clojure-project does...

6:19 tomoj: mine doesn't care about pom.xml

6:19 liwp: maybe it's a different function after all

6:19 tomoj: well maybe it cares, but it still works without any xml

6:20 liwp: does it ask for the project root when you run it?

6:20 tomoj: yep

6:20 angerman: I guess you would just have to go up the directory structure and look for project.clj

6:20 tomoj: I'm thinking one could write a function which asks for a project root, sets default-directory to that, and then runs "lein swank" as an async process

6:21 angerman: hmm...

6:21 liwp: tomoj: yep, something like that, but I'm not sure my elisp-fu is strong enough

6:21 tomoj: mine neither

6:21 somnium: you could copy-paste the frst few lines from swank-clojure-project to det started

6:22 http://www.gnu.org/software/emacs/elisp/html_node/Asynchronous-Processes.html then one of these?

6:23 (my elisp is horrible, but its just lisp after all)

6:23 tomoj: I assume/hope that those functions respect default-directory

6:24 somnium: start-process appears to

6:24 tomoj: how does lein avoid the terribly long jvm startup time?

6:46 angerman: http://gist.github.com/253288

6:46 elisp-fu

6:46 lol

6:47 pretty certain it's not perfect but could work.

6:47 tomoj: have you tried it?

6:48 angerman: yes.

6:48 tomoj: cool

6:48 will save for later when I learn lein

6:48 angerman: it seems I can start multiple different jvms on the same swank port

6:48 liwp: angerman: nice!

6:48 * angerman is confused

6:48 angerman: if you kill the *lein-swank* buffer, the process should die

6:50 adityo: i am trying to compile a file and i got the following error

6:50 error: java.lang.UnsupportedClassVersionError: Bad version number in .class file

6:50 seen this for the first time

6:51 any help?

6:51 Chousuke: it may be compiler for a newer version of Java?

6:51 compiled*

6:52 adityo: ohh!! i just copied those files from my linux box and i am running it on a Mac now

6:54 liwp: adityo: the platform shouldn't matter, but the java version certainly will

6:54 adityo: okie

6:55 i think i am running sun java 1.6 on my Ubuntu but here on the mac its 1.5

6:56 liwp: adityo: yeah, that way will break. Were you to copy files from the Mac (1.5) to linux (1.6) you should be fine

6:57 adityo: liwp: okie, so does the jvm check for java versions or something?

6:57 liwp: adityo: the class files have a version number in them that specifies which class file format the file is in and I think they upped that in 1.6 IIRC

6:58 adityo: the jvm versions are always backwards compatible so the 1.6 jvm will be able to read whatever the 1.5 version can read

6:59 the class file version doesn't really have that much to do with the java version in the sense that a newer java version can also generate files in the older class file format, I think you might just lose some of the newer java features that way

7:00 adityo: okie

7:05 have to keep this in mind when deploying to other machines

7:24 angerman: how do I unbind a variable in the current ns?

7:25 tomoj: angerman: ns-unmap ?

7:26 angerman: hmm lets see

7:27 tomoj: ,(ns-unmap *ns* 'ns-unmap)

7:27 clojurebot: nil

7:27 tomoj: ,(ns-unmap *ns* 'ns-unmap)

7:27 clojurebot: java.lang.Exception: Unable to resolve symbol: ns-unmap in this context

7:27 tomoj: oh shit

7:27 sorry hiredman, didn't think that would work :)

7:28 angerman: ,(use '(clojure core))

7:28 clojurebot: nil

7:28 angerman: ,(ns-unmap)

7:28 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$ns-unmap

7:28 angerman: :)

7:29 * tomoj is tempted to ns-unmap 'ns

7:29 tomoj: er, 'ns-unmap, 'use, 'refer, etc

7:29 well, even so you could (clojure.core/use ..) :/

7:30 is there no way to stop people from ns-unmaping ?

7:30 angerman: (defn ns-unmap [ & args ] (println "nice try...")) ?

7:30 tomoj: ok, but clojurebot won't let us defn

7:31 angerman: probably doing that (in-ns clojure.core)

7:31 tomoj: I could sneak in here when no one's paying attention and ns-unmap 'map and 'for and whatever else

7:32 actually we can talk to clojurebot through jabber, I guess, so I don't even have to do it in here :O

7:32 angerman: the question would be where clojure bot prevents the defining. on a clojure level or on a lower level

7:32 tomoj: ,(defn foo [] )

7:32 clojurebot: DENIED

7:32 tomoj: heh

7:32 clojurebot: <3

7:32 clojurebot:

7:32 tomoj: aww

7:32 angerman: ,(def *m* "no")

7:32 clojurebot: DENIED

7:33 tomoj: fuck you clojurebot

7:33 angerman: ~source def

7:33 clojurebot: Titim gan éirí ort.

7:37 tomoj: (refer 'clojure.core :only '(defn) :rename '{defn foobar})

7:37 ,(refer 'clojure.core :only '(defn) :rename '{defn foobar})

7:37 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: core$defn

7:37 tomoj: wat

7:38 why does clojurebot think I tried to call defn?

7:38 ,(refer 'clojure.core :only '[defn] :rename '{defn foobar})

7:38 clojurebot: nil

7:39 tomoj: ,(foobar baz [])

7:39 clojurebot: DENIED

7:39 tomoj: damn, smarter than I thought :)

7:39 angerman: [...]

7:41 lpetit: ~source repl-caught

7:41 clojurebot: Titim gan éirí ort.

7:41 tomoj: ,(ns-unmap *ns* 'foobar)

7:41 clojurebot: nil

7:42 lpetit: ~source repl

7:47 ~source read

8:06 cark: what is a good, preferably free, ofuscator that will work with clojure AOT compiled jars ?

8:06 *obfuscator

8:08 cemerick: cark: proguard has worked well for us

8:08 cark: thank you

8:10 ordnungswidrig: what charset is use in #clojure?

8:13 Chousuke: UTF-8, please :P

8:14 Using anything else is just silly.

8:14 though most of the time it doesn't matter, since everyone speaks English.

8:19 esj: except clojurebot, when its gets frisky

8:34 Chousuke: ,(update-in {:a 1} [:b] (fn [x] (print x) 3))

8:34 clojurebot: {:b 3, :a 1}

8:34 nil

9:50 bjorkintosh: is 'programming clojure' a good book?

9:53 esj: yes

9:55 bjorkintosh: is it the only decent guide available?

9:56 esj: its currently the only book, but there are others to be released soon

9:56 chouser: bjorkintosh: so far it's the only complete book available. lots of people get by (with various levels of success) with free online resources.

9:58 bjorkintosh: how much do i need to know of java/jvm to take full advantage of it through clojure?

9:59 ohpauleez: bjorkintosh: http://java.ociweb.com/mark/clojure/article.html http://en.wikibooks.org/wiki/Clojure_Programming are both great

9:59 chouser: bjorkintosh: not much. basic knowledge of "normal" object-oriented concepts will take you a very long way.

10:00 ohpauleez: After reading the guides on the wikibooks link, and the article, I was able to make my way through developing comfortable and enjoyable in clojure

10:00 bjorkintosh: cool.

10:01 ohpauleez: bjorkintosh: You might want to bookmark the link to the Java docs online, in case you need some library

10:01 but that's all you need to really know about java

10:04 bjorkintosh: okay.

10:12 Licenser_: hrm I've a odd problem I use create-server to create a server, and pass messages to it via a Socket connection I opened - which is working fine, but no matter what I do the server won't send anything back to the client (or the client ignores it :/)

10:12 any obviouse things I could do wrong here?

10:14 esj: firewall ?

10:15 Licenser_: Nah, the connection is established, meaning packets can flow forth and back

10:17 esj: perhaps Wireshark or such would help you determine whether the server or client is at fault.

10:18 Licenser_: A very good idea, sadly it seems very hard to capture local traffic under windows

10:20 esj: indeed, everything under Windows is hard.

10:21 Licenser_: I know it's not my OS of choice

10:22 tomoj: have you tried on a server you know will work?

10:22 windows shouldn't be a problem I'd think

10:22 certainly the windows java socket api should work fine

10:23 Licenser_: tomoj: hmm good idea, I'll see if I can telnet to the box

10:24 tomoj: :D okay the server isn't the problem it's the cleiunt

10:24 thanks!

10:25 * angerman in his leg

10:25 tomoj: I've never used create-server before

10:25 the fn you pass is supposed to do whatever reading/writing to the input/output streams and then return when it's finished?

10:25 Licenser_: me neither

10:26 yap that is about it

10:26 and it works really great

10:26 I found the best way top parse incoming messages is to reduce over the line-seq from the input stream

10:26 that way the state of teh connection isn't really a state but a argument to the reduce function

10:27 once I'll get this wokring I'll write an article ;)

10:35 chouser: I can never remember. Is java.util.Timer good or bad?

10:35 I think it's bad, but I can't remember the good one's name.

10:38 esj: what is the approved technique for returning results out of a resource enclosing form like with-connection in clojure.contrib.sql ? I can successfully execute my query but I need to return it. I thought dorun / doseq would be it, but they return nil.

10:39 chouser: ah, perhaps java.util.concurrent.Executors/newSingleThreadScheduledExecutor

10:39 esj: doall or vec

10:39 esj: chouser: magic, thanks.

10:40 fliebel: Does anyone know how I can run a REPL in a Vim buffer with VimClojure?

10:43 tomoj: fliebel: the fact that it's not obvious saddens me

10:44 fliebel: tomoj: VimClojure does not come with an awful lot of documentation…

10:44 karmazilla: chouser: the reason Timer is bad is because the thread will die if an exception bubbles up

10:44 chouser: karmazilla: ooh, ouch.

10:44 tomoj: what I mean is, the fact the repl is not the central feature saddens me

10:46 I guess we already have a repl and so vimclojure doesn't need to provide one in a prominent way

10:46 (I'm brainwashed by emacs :()

10:48 chouser: tomoj: it's just a keystroke

10:48 fliebel: tomoj: Maybe the repl is just below the surface, but the fact that it does not open the moment vim starts makes I can't find it.

10:49 chouser: I don't use vimclojure's integration, but I'll see if I can find the keybinding.

10:49 fliebel: chouser: thanks, what are you using?

10:49 chouser: I just use a plain terminal repl with rlwrap around it.

10:50 tomoj: so you edit your source files and then go into the repl and load them?

10:50 chouser: I'm hoping any inconvenience involved in that setup will be motivation to complete texture. Hasn't worked yet. :-/

10:51 tomoj: that's one way, or I have window-manager-level keybindings to send form over with a couple keystrokes.

10:52 not beautiful, but also very straightforward. Nothing much there to break, even when using odd branches of clojure, or untested patches, etc. Things that seem likely to break more complex setups like slime.

10:52 tomoj: the form you're sending over is the code in your source file or some code that loads the source file?

10:53 chouser: the code in my source file (or "scratch buffer")

10:53 tomoj: ah

10:53 then you don't get line numbers on errors, though, right?

10:53 fliebel: chouser: I found it should be /sr, but I'm not sure how I'm supposed to enter that.

10:54 chouser: tomoj: right, when done that way.

10:54 tomoj: using window-manager-level stuff sounds awesome to me, but as long as technomancy et al keep slime working.. :)

10:55 esj: fliebel: you've used VI before ? If not press <esc> first maybe ?

10:56 chouser: tomoj: yeah, active support from People Who Know for your particular use cases makes a huge difference.

10:56 fliebel: I press escape, the \sr but I get all sorts of regex tings

10:56 tomoj: I vaguely wish my window manager was in clojure :/

10:56 esj: fliebel: sorry never used it, so no other guesses

10:57 chouser: tomoj: last time I tried emacs I got pretty far, pretty comfortable. But ended up ditching it because there were one or two vimmers working hard to make our development environment excellent in vim, and I just couldn't keep emacs up to snuff.

10:57 fliebel: esj: s seems some delete key, s it goes back to —insert-- when i do that

10:57 tomoj: I wonder if I should give vim a shot.. I've never really tried it

10:57 chouser: fliebel: it can't be \sr ... hang on, still looking.

10:58 fliebel: you got vimclojure installed and nailgun running?

10:58 fliebel: chouser: yes

10:58 chouser: at least I have syntaxt coloring and a terminal window saying NGServer started on, port 2113.

10:59 chouser: fliebel: you found the .vim/doc/clojure.txt help file? I don't know why it isn't found via :help

11:00 karmazilla: I have yet to figure out the keybindings part of vimclojure, but I'm guessing that maybe you are expected to configure them yourself in .vimrc?

11:00 fliebel: I was just about to search for it it…

11:01 chouser: sorry, it can't be /sr it should be \sr but it's not working for me at the moment.

11:01 fliebel: chouser: the file is called clojure.txt

11:01 chouser: unless you remapped your localleader

11:03 fliebel: what is my localoader?

11:04 chouser: your localleader is \ unless you remapped it

11:04 fliebel: ok… then it should be \sr...

11:04 chouser: right.

11:05 Licenser_: anything I'm doing wrong here: (let [in (new BufferedReader (new InputStreamReader (.getInputStream socket)))]?

11:05 * Licenser_ hates when it gets so javaisch ...

11:06 fliebel: so I go to normal mode by pressing escape, then I press \ … nothing then I press s and go back to —insert—

11:06 chouser: fliebel: if you get fed up with vimclojure, here's an alternate solution I've been meaning to try: http://agriffis.n01se.net/skel.hg/index.cgi/file/fe1c0bdb217b/vim/plugin/ScreenRepl.vim#l1

11:06 angerman: Licenser_: s/new (.[^ ])/\1./g ?

11:07 Licenser_: s/new ([^ ]+)/\1./g ?

11:07 fliebel: chouser: might try that… but I'd rather get vimclojure working first

11:08 chouser: fliebel: that's the behavior I's seeing for \sr as well. Which is what I'd expect if \sr weren't bound at all.

11:08 Chousuke: Licenser_: looks fine to me.

11:09 Licenser_: angerman, thanks

11:09 Chousuke: darn, I hoped I had an mistake :P

11:12 ohpauleez: just out of curiosity, does anyone know of a project/package targeting distributed computing with clojure

11:13 I'm currently working to port and enhance my autonomic lib, and have a loose wrapper tying enlive and htmlunit together on the back burner

11:13 esj: Terracotta is all i know, Paul Stadig posted on this on the google group today / yesterday

11:14 ohpauleez: thanks esj, I'll check it out

11:14 ordnungswidrig: hi all

11:14 esj: depending on what you are doing FlightCaster did a lot of batch stuff in Hadoop/Cascading and released lots of the code into Incanter... dunno how much, or if its what you're after.

11:14 ohpauleez: I figured terracotta was a good platform to do it, but I didn't know if someone was looking to make a distributed backend for parallel ops

11:15 fliebel: chouser: omnicompletion is not working for me as well, so it might be a nailgun issue.

11:15 ohpauleez: I'm looking more to make a new package that redefines pmap/preduce, etc, that has distibution under it. But I haven't thought through it yet

11:15 just was curious

11:16 fliebel chouser: is vimclojure broken with the latest stuff for you?

11:16 ordnungswidrig: am i right that equality comparision on persistent datastructures makes no sense on the instance level? at last most of the time.

11:16 tomoj: huh?

11:16 ordnungswidrig: i mean equality based on identity

11:17 chouser: ohpauleez: oh, I didn't even think about the version. Indeed, I'm trying to use it with 'new'.

11:17 ordnungswidrig: java == vs. Object#equal

11:17 tomoj: ah

11:17 yes == is not right

11:17 ohpauleez: chouser: it works for me right now, but there have been times where I've had to rebuild vim clojure with new versions of clojure

11:17 Chousuke: well, if they're identical then they're equal

11:17 tomoj: ,(identical? [1] [1])

11:17 clojurebot: false

11:18 Chousuke: but I think that's the first thing checked by equas anyway :P

11:18 ordnungswidrig: so if i want to tell one instace from another I need sth. acting as a natural key.

11:18 chouser: but, I don't use vimclojure regularly, so I don't know when what might have broken.

11:18 Chousuke: tomoj: I didn't say the reverse was true :)

11:18 tomoj: I didn't say you did say, just respondin to ordnungswidrig

11:19 you are right though, clearly if they're identical then they're equal

11:20 ordnungswidrig: if multiple orders would reference the 'same' shipping adress you'd need an address key to be able identif| a certain one...

11:23 tomoj: regular equality won't work?

11:25 Licenser_: is there something like ===?

11:25 ordnungswidrig: tomoj: no, say order1 and order2 reference shipping adresses which are equals. now, you want to update order1 with a new shipping address

11:25 Licenser_: no there sems not to be

11:26 ordnungswidrig: wouldn't you change it by refferencing the order which you want to cahnge?

11:26 ordnungswidrig: licenser: hm, that is true.

11:26 fliebel: chouser: I got into the REPL!!!!! just after trying over and over to type \sr

11:26 chouser: wow

11:27 ordnungswidrig: opposire case: i want to change an item referenced by both orders.

11:27 and the change should appear in both orders

11:28 somnium: ordnungswidrig: you can alter the value pointed to by @address

11:28 tomoj: so then either both orders are in a ref and we can modify them both atomically, or each order holds a ref/atom/etc to an item

11:28 ordnungswidrig: @address? that sounds scary, like peek and poke

11:29 ah i see, a ref

11:29 fliebel: chouser: I can even send functions for the buffer over to the repl!

11:29 somnium: in one case you alter the identity (address :a1 to :a2) in the other the value referenced by :a1

11:29 ordnungswidrig: yes by this you define the borders of indipendently updatable parts of you model, right?

11:29 tomoj: if we alter the ref, both orders will "see" the change

11:31 ordnungswidrig: if i want to stay purely functional then I would have to make the adresses identifiable with a synthetic id.

11:31 tomoj: if you want to stay purely functional you aren't going to make any money

11:32 ordnungswidrig: and do some ref bookkeeping to find all 'instances' with a certain id.

11:32 esj: tomoj: making money is a side effect ?

11:32 tomoj: rather, side effects make money

11:32 ordnungswidrig: tomoj: because of me, or because of pure fp? galois does, e.g.

11:33 somnium: is that why haskell is sponsored by M$?

11:33 ordnungswidrig: and they're lazy, too!

11:33 tomoj: galois makes money?

11:34 Licenser_: Hmm is there any problem in calling line-seq on the InputStream of a socket? It should just wait untill the socket is closed and untill that is done spit out the lines when they come right?

11:34 tomoj: he's dead?

11:34 the-kenny: Licenser_: I think there's something for this in contrib (fill-queue)

11:35 Licenser_: the-kenny: thanks I'll read up on that

11:35 ordnungswidrig: if you see every update on your business model as a function, then you're in pure fp, right? haskell does it, as well as stm

11:35 the-kenny: Licenser_: It's basically a background-thread which fills a queue and you can remove items from that queue etc etc.

11:35 Licenser_: hmm but I don't think that is waht I'm looking at

11:36 I want it to be foreground at the moment, problem is that the line-seq does not block but just tosses up it arms and screams I'm empty!

11:36 tomoj: maybe I misunderstand what "pure fp" means

11:37 to me anything which is "pure fp" is totally useless

11:38 ordnungswidrig: i mean an update of a business model is a function that returns a new, updated instance of the model

11:38 pure in a sense of no mutable state, no side effects

11:38 Licenser_: odd, very odd

11:39 tomoj: I guess you do your side effects in between these updates?

11:39 Licenser_: reader (fron c.c.duc-streams refuses to open my socket too -.-

11:39 ordnungswidrig: tomoj: if they are necessary, yes.

11:40 tomoj: certainly they are necessary...

11:40 otherwise the program is useless

11:40 ordnungswidrig: tomoj: of course

11:41 devlinsf: Licenser: What version of contrib are you using

11:41 Licenser_: 1.0.0

11:41 devlinsf: Licenser_: The duck streams upgrade is recent

11:41 ordnungswidrig: imagine that you hold your model in clojure maps and vectors. no vars, refs or agents. then every update on you model returns a new revision of your model.

11:41 Licenser_: ah okay

11:42 devlinsf: Try this (reader (.getOpenStream my-socket))

11:42 ordnungswidrig: i.e. update is a function update Model -> Params... -> Model

11:42 tomoj: I don't understand why you eschew refs

11:43 ordnungswidrig: tomoej: academic research?

11:43 tomoj: eh

11:43 Licenser_: does not know getOpenStream but with getInputStream works (as in no crash) but gives no results

11:44 tomoj: I mean, even with refs, if the functions which update the refs are pure, can't we regard the whole thing as a function from total state to next total state?

11:44 ordnungswidrig: tomoj: i see the necessarity of refs to define the boundaries of a updates. ids for every independently updatable object should work, too

11:44 somnium: ordnungswidrig: are you reducing across an infinite sequence of updates?

11:45 Licenser_: Do I miss something that is wrong with this: (map (fn [x] println "-" x "-") (line-seq (reader (.getInputStream socket))))

11:45 somnium: then the global state is always an argument and a new global state is always returned

11:45 tomoj: ordnungswidrig: should work, but with concurrency?

11:45 ordnungswidrig: somnium: nope, still thinking on making a patch algebra of the business model update functions and getting, undo/branch/merge for free

11:45 somnium: ah

11:45 ordnungswidrig: tomoj: yes, that makes sense

11:45 devlinsf: Lincenser_ :Yep. Map is lazy, println is a side effect

11:46 ordnungswidrig: tomoj: concurreny can be enabled by comapre-and-set or automativ merge

11:46 devlinsf: Try this (println (apply str (map #(str "-" % "-") ...)))

11:46 ordnungswidrig: tomoj: and manual conflict resolution

11:46 tomoj: ok

11:46 devlinsf: Or use doseq, not map

11:46 tomoj: personally I don't want to do any manual conflict resolution

11:47 I'd rather let clojure's stm take care of the problem :)

11:47 ordnungswidrig: tomoj: in a eventual consitent world, this is an option.

11:47 tomoj: stm does cas

11:47 somnium: yes, I like the 'someone else's problem' approach to reducing complexity

11:48 Licenser_: devlinsf: argh I think I know what is the problem, you're totally right

11:48 devlinsf: Licenser_: I've made that exact mistake before

11:48 Licenser_: what freaks me out so is that it works for the server o.O

11:49 tomoj: ordnungswidrig: I've concluded I really have no idea what you're talking about, good luck

11:49 ordnungswidrig: tomoj: if two user update the same customer record, you can either try to merge and (probably conflict) or do a CAS and ask thew loosing user whether to try again

11:51 devlinsf: Laziness can be a pain

11:51 Licenser_: devlinsf: yes :(

11:51 but thanks a lot!

11:51 devlinsf: N/p

11:51 * the-kenny has learned this the hard way

11:51 the-kenny: After some hours running without problems, my code just crashed

11:52 With a very very long stacktrace which didn't help

11:52 Licenser_: hmm hmmm

11:53 jasapp: the-kenny: what are you doing if you don't mind me asking?

11:53 Licenser_: ah I know why it's working on the server, reduce makes it execute ^^

11:53 the-kenny: jasapp: Something with twitter and youtube ;) Nothing very big yet

11:54 jasapp: gotcha

11:54 the-kenny: jasapp: basically, I'm reading the stream of tweets continously and doing some data-crunching on the numbers.

11:54 jasapp: cool

11:55 are you storing the tweets, or just tossing them?

11:55 the-kenny: jasapp: CouchDB.

11:55 ordnungswidrig: me wonders if one can predictinfluence pandemies with twitter like google does with search requests

11:55 the-kenny: jasapp: But I'm refactoring it at the moment.

11:55 jasapp: interesting

11:55 ordnungswidrig: ...influenca...

11:56 jasapp: I'm doing something similar with ebay and mongo

11:56 the-kenny: ordnungswidrig: I'm sure it'll - at least when everyone uses geolocation

11:56 defn: the-kenny: hehe, im doing something like that too

11:56 the-kenny: defn: You stole the idea of a friend of me! :p

11:56 ordnungswidrig: clojure seems to have a good standing in data mining...

11:56 defn: you gave me some boilerplate for reading the firehose

11:57 tomoj: the-kenny: what are you using to interface with couchdb?

11:57 defn: i didnt know about that new firehose thing

11:57 the-kenny: defn: I know ;) I'm just joking

11:57 tomoj: clojure-couchdb with some modifications

11:57 tomoj: ah

11:57 ordnungswidrig: firehose?

11:57 defn: twitter's constant stream of tweets

11:57 you just keep downloading tweets as they're posted

11:57 jasapp: don't you have to be special to get a firehose?

11:57 defn: in json format

11:57 nope

11:58 ordnungswidrig: me forked the-kenny's clojure-couchdb and put some lucene it...

11:58 the-kenny: tomoj: I think I'll drop the exception-throwing parts from my fork and use return-codes for error messages It starts to annoy me.

11:58 ordnungswidrig: the-kenny: I'd appreciate dropping the exceptions

11:58 the-kenny: jasapp: You have to be special to get a stream of *all* tweets.

11:58 defn: yeah

11:59 jasapp: ahh, ok

11:59 the-kenny: jasapp: But you can define "filters" and get everything which passes them.

11:59 ordnungswidrig: the-kenny: that'd be a rather big stream, right? do you have numbers?

11:59 defn: i downloaded 1,000,000 tweets the other night

11:59 the-kenny: ordnungswidrig: Not really. I'm reading everything with "http" in it.

11:59 defn: pretty fun to play with them

12:00 jasapp: I've been saving iphone auctions

12:00 the-kenny: It like 500kb/s or so.

12:00 s/It/It's/

12:00 defn: there are about 27million tweets per day

12:00 the-kenny: I'm not sure, but my macbook can even handle to resolve all these urls without using more than 6% of my processor

12:01 dnolen: the-kenny: any opinion about clojure-couchdb over clutch? clutch seemed further along at one point...

12:01 the-kenny: dnolen: Never tried clutch. I was searching for a simple interface without things like a custom view-server and such goodies

12:01 esj: help ! how does one pass arguments into java calls and multiple depths like: formatter.withZone(DateTimeZone.UTC).print(dt)

12:01 ordnungswidrig: the-kenny: resolve? you mean un-tinyurl?

12:01 the-kenny: ordnungswidrig: Yes

12:01 esj: exhausting the combinatorics here is getting me nowhere ;)

12:02 the-kenny: ordnungswidrig: It's a 4 line function in clojure using java.net.HttpUrlConnection

12:02 defn: hehe try to do a permutation of i believe it's 9 integers

12:02 devlinsf: (. print (. withZone formatter DateTimeZone/UTC) dt)

12:02 esj: try that

12:03 esj: devlinsf: much oblidged !

12:03 ordnungswidrig: dnolen: i liked clutch for not throwing exceptions. but i had to drop it because the db was passe along in a binding

12:03 devlinsf: Eh, try this first

12:03 the-kenny: ,(doc ..)

12:03 clojurebot: "([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."

12:03 devlinsf: (class (. withZone formatter DateTimeZone/UTC))

12:03 that should be a sanity check

12:03 the-kenny: esj: I think you want .. :)

12:03 tomoj: ordnungswidrig: would you rather pass the db/host in as the first param to every function?

12:03 (I'm working on my own couchdb clojure library at the moment)

12:04 ordnungswidrig: tomoj: i'd like the choice

12:04 danlarkin: One Of These Days™ I'll get around to updating clojure-couchdb, and doing it a little better, not throwing exceptions etc

12:04 esj: thanks guys... will check it out

12:04 devlinsf: np

12:04 the-kenny: tomoj: I managed my fork of clojure-couchdb to do this

12:04 tomoj: passing it with a binding is a big pain if you use threading

12:04 dnolen: the-kenny: ordnungsmidri: good to know.

12:04 tomoj: ah, I see

12:04 ordnungswidrig: optionally a (with-db ) macro is nice

12:04 tomoj: I have a binding now for host config and first param as the db name

12:05 well.. providing your own with-db macro shouldn't be too hard, no?

12:05 ordnungswidrig: tomoj: you could fall back to the binding if no param was given

12:05 tomoj: yeah that's what chous* recommended when I asked earlier

12:05 ordnungswidrig: leaving the train... cu all

12:06 the-kenny: Shouldn't be hard to (partial) all functions in a macro

12:06 I want to do this for clojure-couchdb :)

12:06 1. Refactoring my project, 2. removing exceptions from my fork of clojure-couchdb and 3. adding a with-server/with-db macro :)

12:07 tomoj: I wonder how common it would be to need multiple host configs

12:07 for my uses I don't need that at all, so a binding doesn't seem bad

12:08 the-kenny: tomoj: I liked bindings until I started working with threads

12:08 ordnungswidrig: tomoj: my problem was that a binding cannot be captured by a (fn ) form

12:08 the-kenny: ordnungswidrig: And any binding will dropped in a new thread

12:08 fliebel: How can I get the index of an item in a vector? I'm trying to do some sort of lazy slice thing, like Python. I'm doing this now, but that obviously only works for numbers: (def a (filter odd? (cycle [:a :b :c :d])))

12:08 the-kenny: +be

12:08 tomoj: maybe I will discover these problems when I actually start using my library

12:09 the-kenny: tomoj: Try it with a remote server

12:09 tomoj: eh?

12:09 the-kenny: Authentication is also a problem which clojure-couchdb doesn't handle

12:10 tomoj: Play around with your lib, think about use-cases and test them :)

12:10 tomoj: even in my wildest imaginations where I have a whole cluster of couches, they're all accessible from one host config

12:10 jasapp: so who is going to write a query engine for couch in clojure?

12:10 tomoj: it's already been done

12:10 jasapp: has it?

12:10 tomoj: I also did it myself recently, it's easy

12:10 the-kenny: jasapp: clutch has a view-server

12:11 jasapp: sweet, I had no idea

12:12 tomoj: all you really have to do is parse json and use read-string :)

12:12 jasapp: I didn't realize it was that easy

12:12 Licenser_: time to go home, see you all later!

12:13 tomoj: making clojure tools to define design documents is what I'm working on now, not sure how best to do that

12:13 but implementing the basic map/reduce/rereduce is simple

12:13 jasapp: do you have any good ideas for defining documents?

12:14 I'd like to do something similar for mongo

12:14 the-kenny: jasapp: How does mongo handle documents etc.?

12:14 (I'm only familiar with couchdb)

12:15 jasapp: I think in a similar manner to couchdb, they're stored in binary json

12:15 bson they like to call it

12:15 tomoj: I don't think I have good ideas

12:15 jasapp: mongo doesn't have the nice versioning like couch

12:15 fliebel: How would I get 2 lazy infinite seq with the odd and even indexes form a vector? I'm currently doing: (def a (filter odd? (cycle [1 2 3 4])))

12:16 Chousuke: fliebel: don't def infinite sequences

12:16 fliebel: they will never get garbage collected

12:17 fliebel: chousuke: hmmmm, so what should I do?

12:17 tomoj: currently I'm thinking just like (def *my-design-doc* (couch-view design-name/doc-name (view1-name {:map (fn [doc] ..)}) (view2-name {:map...}))

12:17 Chousuke: fliebel: just make the seq where you need it, or make a function that returns one

12:17 tomoj: and then some function to create

12:17 create or update, I mean

12:18 jasapp: have you run into any mapping issues between clojure types and couch types?

12:19 tomoj: though I really like the idea of doing (defdesign db-name/doc-name ...) and having some evilness to automatically sync them..

12:19 nope it's just json

12:19 fliebel: chousuke: That is fine for the final thing, but for testing I did this… But I might as well use take 10 or something like that. The main problem is that I want it to work with strings, not numbers, so I'd need the index rather than the value. This would be quite easy with Python slices…

12:19 defn: Chousuke: so instead of def a, defn a [] gets collected?

12:19 tomoj: the only issue I've run into is whether to allow users of my library to use string keys, and I say '

12:19 "no, use keyword keys"

12:20 jasapp: hmm

12:20 tomoj: otherwise c.c.json takes care of everything

12:20 Chousuke: defn: if the result of the function is not bound to a permanent reference it can be collected

12:20 jasapp: at one point in time, I was trying to save xml zippers in mongo

12:20 defn: tomoj: i found that weird that the keys are "strings"

12:20 like ("text" tweet)

12:20 jasapp: that was giving me some trouble

12:21 Chousuke: defn: if you (def x (make-lazy-seq)) then that lazy seq will never be collected, of course.

12:21 tomoj: rather (tweet "text") no?

12:21 Chousuke: defn: because x is a reference to it

12:21 defn: err yeah sorry

12:21 tomoj: but I use the settings in c.c.json to make it (:text tweet)

12:21 defn: Chousuke: ah-ha i see

12:21 that's good thinking

12:21 @tomoj

12:21 tomoj: and if you make a doc with a key like "_id" you're just screwed

12:21 defn: yeah, that's annoying -- i was frankly surprised that the keys from twitter were strings like that

12:22 why wouldnt they use symbols or something?

12:22 tomoj: is it json?

12:22 defn: keywords,symbols

12:22 yeah

12:22 tomoj: in json object keys are always strings

12:22 defn: huh, i didnt know anything about json

12:22 it just seemed wasteful :\

12:22 tomoj: but c.c.json can autoconvert them into keywords

12:32 the-kenny: Is there a function to check if all values in a struct are valid (e.g. not-nil)

12:35 gregoryg: macs

12:35 the-kenny: hm.. clojure-mode needs a special face for (comment ...)

12:40 stuartsierra: the-kenny: (every? identity things)

12:55 technomancy: the-kenny: actually I like that stuff in (comment) gets fontified normally since it's usually example code.

12:55 the-kenny: technomancy: hm.. yeah, but I would like to see something like a small shade to show it's commented out.

12:55 I don't know if this is possible with emacs, but it would be cool.

12:56 technomancy: oh maybe a different background? that's not hard.

12:56 the-kenny: a slight-gray background would be fine

12:57 just to distinguish the code from the "active" code

12:58 defn: is there an easy way to comment a region in clojure-mode?

12:58 the-kenny: defn: Yes, (comment ...)

12:58 technomancy: defn: M-; (not just for clojure)

12:58 defn: thanks for both of those :)

12:58 technomancy: problem is custom backgrounds are not very composable with color themes

12:59 the-kenny: hm.. maybe a customizable face for the background?

13:00 technomancy: the-kenny: I mean it works, it just requires everyone using a different color theme to also specify that one

13:00 most color themes only specify new values for built-in faces

13:00 the-kenny: technomancy: ah ok

13:00 I understand..

13:00 tomoj: color themes seem pretty broken to me

13:01 technomancy: it's a hack job, no question

13:01 defn: yeah tomoj -- sometimes ill try to switch color themes mid-emacs-session

13:01 apparently that is a bad idea

13:02 tomoj: heh

13:02 defn: all sorts of colors hang around and mash with eachother

13:02 tomoj: yup

13:02 and resetting doesn't seem to work

13:11 defn: wow -- guy steele lobbied sun to have tail calls in java in 1996

13:19 kylesmith_: Has anyone tried out the debug-repl?

13:19 defn: with (ns myns [:use...]), i can list multiple namespaces right?

13:19 the-kenny: defn: yes

13:19 defn: like [:use clojure.core clojure.contrib.seq-utils ]

13:20 the-kenny: cool thanks

13:20 if i have (ns foo.core [:use compojure]), and in another file I do (ns foo.extra [:use foo.core])

13:21 does that inherit compojure?

13:21 the-kenny: defn: I think so.

13:21 defn: But I'm not sure

13:21 stuartsierra: defn: no, it does not

13:21 defn: is there a way to inherit?

13:22 the-kenny: Learned again..

13:22 stuartsierra: 'use' only refers symbols interned in the namespace you are 'use'ing.

13:22 defn: not in core

13:22 defn: k

13:22 stuartsierra: Compojure tries to do inherited namespaces, and it causes some problems.

13:23 See http://groups.google.com/group/compojure/browse_frm/thread/400aac94e536e633

13:23 defn: ty

13:45 Drakeson: do you know of an example of using dbus in clojure?

13:49 Licenser: aloaeh!

13:51 chouser: Drakeson: I wrote some code that acts as a client for dbus, but it was horrible.

13:51 Drakeson: I was using some java dbus lib that really didn't help. I think I'd try with jna and the normal dbus C library.

13:52 can't imagine it'd be any worse at least.

13:52 technomancy: has there been any talk of expanding the regex reader macro to support creating case-insensitive regexes?

13:52 chouser: #"(?i)foo"

13:52 technomancy: #"foo"i would be closer to other notations

13:53 * chouser shrugs.

13:53 hiredman: (?i)foo is java notation

13:53 technomancy: but I guess that's not bad

13:54 chouser: I don't love the extra "(?)" noise, but I actually like having it up front.

13:54 those flags do change the way all the rest of the regex is compiled, so it's nice to see it early.

13:56 ,(let [x "foo boo FOO Boo"] (re-seq #"(?i)f\w*"x))

13:56 clojurebot: ("foo" "FOO")

13:59 angerman: incanter.stats/histogram is quite slow. which is very weird.

14:01 Drakeson: chouser: were you using libdbus-java by any chance? (I am on debian)

14:02 chouser: Drakeson: that looks right.

14:03 Drakeson: I don't remember the specifics of my pain, I'm afraid, but jna is quite pleasant considering the problem space it addresses.

14:05 Drakeson: chouser: I like jna, (and your clojure-jna), I am even increasingly finding myself using it to debug some C programs. I am not familiar with the regular (C) dbus libraries, so I thought a java one might be of some help

14:05 alexyk: the-kenny: where do you set those filters to get all twitter's URLs?

14:06 Drakeson: I'll try to see where http://dbus.freedesktop.org/doc/dbus-java/api/ breaks ...

14:06 chouser: Drakeson: I was using it to talk to Pidgin (libpurple)

14:07 Drakeson: oh! that's precisely what I am trying to do

14:07 chouser: so painful

14:07 the-kenny: alexyk: At the end of the url

14:07 alexyk: Just look at the doc

14:07 chouser: you have to generate an interface to hand off to dbus-java

14:08 alexyk: the-kenny: What URL? Are you using the gardenhose/Streaming API?

14:08 Drakeson: chouser: I am not sure of that

14:08 the-kenny: alexyk: Yes, the streaming-api

14:08 alexyk: Wait

14:08 alexyk: "http://stream.twitter.com/1/statuses/filter.json?track=http"

14:09 Drakeson: chouser: well, I have made a MethodCall without generating the interface

14:09 lisppaste8: Chouser pasted "dbus + pidgin = pain" at http://paste.lisp.org/display/91889

14:09 Drakeson: but it looks like crap

14:09 chouser: Drakeson: perhaps you found a better way, then.

14:09 alexyk: the-kenny: do you have any permissions on your twitter account to access that?

14:09 the-kenny: alexyk: No

14:10 alexyk: Filters doesn't require additional rights

14:10 alexyk: interesting! we used to have to click on some EULA to get a slice

14:10 the-kenny: I wonder if you can get retweets this way...

14:11 the-kenny: alexyk: hm.. Not sure if the rt-api is in this stream

14:11 alexyk: http://apiwiki.twitter.com/Streaming-API-Documentation#statuses/retweet

14:12 hm sorry, not generally available

14:14 chouser: Drakeson: also, setting up shared-native-library stuff is easier for jna than for libunix-java

14:15 which can matter a lot for desktop-deployment of the sort you'd expect with dbus and libpurple.

14:15 Drakeson: chouser: now that I look at it, mine is equally painful because I have to indicate the type on every object I pass to MethodCall.

14:17 chouser: Drakeson: macros might help yours, while mine requires AOT compilation regardless.

14:19 Drakeson: chouser: I took some parts of the examples in dbus-java-bin (e.g. it installs /usr/bin/DBusCall)

14:37 lpetit: _ato: hello

14:43 rhickey: thanks again for having reminded me of the SchemeScript project. There's definitely tons of good things to read there, if not to copy, if not to share.

14:43 rhickey: BTW, do you know to which extent EPL (under which CCW is released) and CPL (under which SchemeScript is released) are compatible ?

14:44 rhickey: lpetit: EPL is the successor to CPL, very compatible

14:44 alexyk: how do you instatntiate Java generics, e.g., what's the equivalent of this Java: Graph<String, MyLink> gr = new SparseGraph<String,

14:44 MyLink>();

14:44 lpetit: rhickey: I mean, I could grab some general info about EPL / CPL license compatibility by googling, but maybe you have the short answer (by having, I don't doubt it, thoroughly studied this at some point)

14:45 alexyk: you just instanciate it like any other class

14:45 ,(java.util.ArrayList.)

14:45 clojurebot: #<ArrayList []>

14:46 alexyk: lpetit: it takes other classes as parameters... what's the Clojure sugaring syntax for that?

14:47 the-kenny: alexyk: No, it's not a paramter. It's just a nicely wrapped type-annotation.

14:47 alexyk: You don't have to use Generics, you can just drop them and the collections work too.

14:47 alexyk: the-kenny: right. so how does Clojure do it? :)

14:47 lpetit: alexyk: anyway, parametric information (generics) are a java compiler trick, they are erased at runtime

14:47 the-kenny: alexyk: It doesn't

14:48 lpetit: alexyk: it doesn't do it differently than everywhere else: no static type checking

14:48 the-kenny: alexyk: The annotation are just there to help the compiler keep up the type safety

14:48 alexyk: the-kenny: so what would I do to achieve the above in Clojure? Just (SparseGraph.) ?

14:48 the-kenny: alexyk: Yes

14:48 Same for ArrayList and any other generic

14:49 alexyk: the-kenny: so how will it know it's a <String,MyLink> kind? I.e. it won't check types in Clojure at all?

14:49 the-kenny: alexyk: It doesn't know it.

14:49 lpetit: alexyk: clojure does type inference to some extent, but that's with the goal of performance: finding at compile time as much as possible concerning the real type (class, interface) of called objects so that it avoids compiling reflexion but rather compiles direct method access

14:50 the-kenny: alexyk: As lpetit said: All these informations are dropped by the compiler in java, so they are just a small hack to keep type safety up. Everything works the same without generics.

14:51 alexyk: After compiling, all generics are gone. All collection work with java.lang.Object, the superclass of all classes in java.

14:51 alexyk: interesting... so now I understand clojure/java/scala differences better, or it seems so. Java and scala retain all this type info during compile time, but if clojure doesn't check it during compile time, then it's truly less strictly typed. Which is not a bad thing per se.

14:51 lpetit: alexyk: you should not be more or less annoyed by not being able to specify generic types than not being able to speficy e.g. function formal arguments types

14:52 alexyk: well you can't call it dynamic and still strictly typed -- it's loosely typed w.r.t. generics...

14:52 I c an stick random things into my graph

14:53 the-kenny: alexyk: Yes, and your graph sees nothing but "Object"

14:53 alexyk: This works in Java too, just drop the generic-instanciation and turn off warnings for that.

14:54 lpetit: alexyk: for a profound understanding of what really makes clojure different (and not just "surface" things such as syntax, strong typing, ...), viewing http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey is highly recommended

14:54 the-kenny: alexyk: That's also the cause why you can't stick a basic int or float into a collection - it isn't a subclass of Object

14:56 alexyk: ok! cool

14:56 lpetit: alexyk: watching this will be like Alice entering the world of wonders. At first it looks amazing and a little strange, but at the end of the journey, you're enlightened :-)

14:57 alexyk: lpetit: after such ad, I can't help watching it :)

14:57 lpetit: alexyk: and you observe that you're not continuing to use clojure for the same reasons you came to it :)

14:57 alexyk: to some extent, of course

14:58 alexyk: you may be surprised, though. The link I provided will not talk a lot about clojure. But it's intentional. It justifies by itself clojure's existence.

15:00 alexyk: once you're watched the first one, you'll be ready to watch this one, which will detail how the mechanisms and principles explained in the first video are implemented in clojure, straight into the language: http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey

15:00 alexyk: enough for today, good watch :-)

15:00 alexyk: thx :)

15:09 mabes: how do you get the index of an element in a vector? find-doc is failing me...

15:10 * alexyk wonders which country is rhickey from

15:10 hiredman: (.indexOf [1 2 3 4] 2)

15:10 ,(.indexOf [1 2 3 4] 2)

15:10 clojurebot: 1

15:10 alexyk: watching the video, but my accent-placing skills are not definitive

15:11 (unless related to Russian)

15:11 hiredman: uh

15:11 karmazilla: is there a continuous test runner for lein?

15:11 mabes: hiredman: oh, yeah, forgot about the java layer :) thakns

15:11 er.. thanks

15:12 hiredman: alexyk: it's like newyorkish

15:12 the state not the city

15:13 alexyk: hiredman: really? sounded a bit British to me at first, or Aussie/NZ

15:13 less so than Peyton-Jones' though

15:14 ...then again we had tons of snow and it may have gotten into my ears...

15:14 saml: hey, how can I get a type of something in repl?

15:14 (doc x) is only way?

15:14 clojurebot: It's greek to me.

15:15 alexyk: saml: (class x)

15:15 hiredman: ,(type :x)

15:15 clojurebot: clojure.lang.Keyword

15:15 saml: i mean arguments it takes and return value

15:15 hiredman: saml: dynamic language

15:15 saml: yah but it says keywords are also a function that takes map

15:15 oh i see

15:15 hiredman: ,(:x {:x 1})

15:15 clojurebot: 1

15:16 hiredman: ,(ifn? :x)

15:16 clojurebot: true

15:17 saml: IFn is interface function, right?

15:18 hiredman: IFn is the function interface

15:19 ,(fn? :x)

15:19 clojurebot: false

15:19 hiredman: ,(fn? (fn [] ))

15:19 clojurebot: true

15:23 angerman: erm, how about incorporating something like http://gist.github.com/253288 into the emacs/clojure/lein support?

15:23 * angerman appologizes upfront for his non-existent elisp-fu

15:24 the-kenny: angerman: There's swank-clojure-project which does almost the same

15:24 (Just without the leiningen dependency :))

15:25 angerman: or integration.

15:28 rullie: what's lein

15:29 angerman: leiningen build tool for clojure

15:29 the-kenny: angerman: lein swank does the same like swank-clojure-project, as far as I know. The biggest difference is, that swank-clojure-project starts the repl inside emacs. I don't see why that should be replicated.

15:29 rullie: angerman: thanks

15:30 angerman: the-kenny: that's the exact point. You need someone to maintain both and make sure they do the same.

15:31 hiredman: fyi, depending on /bin/bash limits the range of systems you can run on, unless you use bash features go with /bin/sh

15:33 angerman: hiredman: thats right

15:33 the-kenny: angerman: Iirc, both was written by technomancy :)

15:33 angerman: the-kenny: I think you get my point.

15:57 neilmock: if anyone's interested in the quartz scheduler and clojure i've got an example here http://github.com/neilmock/clojure-quartz-example

15:57 and if anyone knows a way to get the job class going with out AOT compile that would be great :)

16:09 arohner_: neilmock: I've been looking at using some kind cron/scheduling thing for my own app. Why did you choose quartz over the other options (built-in, jcron, etc)?

16:09 chouser: neilmock: looks like you could probably use proxy to implement an org.quartz.Job so you wouldn't have to AOT

16:17 neilmock: arohner_: i needed possibly thousands of jobs to run at fine-grained timestamps and quartz seemed to be the most suited to that, although i haven't done an exhaustive search for other options

16:18 chouser: i tried proxy, but i don't know enough to get the proper class object out of it

16:18 technomancy: karmazilla: if you check in the pom that lein generates, you can use hudson on the project

16:18 we do that at work; it's not too hard to set up, plus you get a snapshot repository out of the deal for free

16:18 chouser: oh, I couldn't tell. The "job" you pass in is a class, not an instance?

16:19 neilmock: yes

16:19 hiredman: weird

16:19 arohner_: reify might work for that

16:19 hiredman: or just fn

16:19 karmazilla: technomancy: what I mean by continuous test runner is something that runs my unit tests every time I save a file

16:20 not just every time I commit/push

16:20 chouser: bleh. proxy won't be reliable there.

16:20 technomancy: karmazilla: oh, locally? yeah, someone wrote autotest integration, but it starts a new JVM every time IIRC, which is really slow

16:20 karmazilla: you really need to build that into your editor

16:20 it's pretty easy to do in Emacs with clojure-test-mode

16:22 drewr: neilmock: I've wrapped cron4j in a reporting utility I'm working on

16:22 I need to generalize it a bit and release it

16:22 karmazilla: I forked lein and have written a test+cc function in src/test.clj that runs the tests at an interval. Now trying to figure out how I use it from the command line

16:22 chouser: I think reify would work -- you still don't get to specify a classname, but you do get a new class for each usage of (though not each call to) reify.

16:22 neilmock: reading about reify on assembla, looks like it would work if you could get a class out of it instead of an instance

16:23 or maybe that's how it works and i'm misreading

16:23 rhickey: neilmock: when do you need a classname for quartz?

16:23 chouser: (class (reify Job ...))

16:25 neilmock: rhickey: at schedule time, i think it stores the name and optionally parameters and instantiates and executes later

16:26 drewr: fwiw, I extended the cron4j Task class (similar behavior) with proxy and it works fine

16:26 actually, it instantiates immediately but executes later

16:27 technomancy: karmazilla: you could tie into some kind of inotify or similar layer from within a lein-auto plugin

16:27 drewr: the closed over methods keep their env

16:27 technomancy: but I prefer editor integration myself

16:27 then you can get the results displayed overlaid on top of the tests themselves

16:29 neilmock: there's an approach out there of a quartz java job that allows invocation of clojure functions, probably a preferable strategy but i was just exploring the options

16:29 http://asymmetrical-view.com/2009/05/19/quartz-and-clojure.html

16:30 hiredman: does quartz scheduler execute in the same vm?

16:31 chouser: ,(str (proxy [Object] [] (toString [] "foo")))

16:31 clojurebot: java.lang.IllegalStateException: Var null/null is unbound.

16:31 chouser: ooops

16:31 anyway, that returns "foo", but...

16:32 (str (.newInstance (class (proxy [Object] [] (toString [] "foo")))))

16:32 hiredman: a newInstannce of a proxyied class will be missing the fn map

16:32 I believe

16:32 chouser: ...does not. Because the methods aren't held in the class, when you just use the class of what 'proxy' produces, you get only default implementations.

16:32 hiredman: right.

16:39 hiredman: gah, checked exceptions are so horrible

16:43 it seems there is no way to get an element an element from a List that does throw some checked exception

16:43 maybe just call toArray and operate on that

16:45 drewr: http://gist.github.com/253711

16:46 chouser: ^ works for me

16:47 chouser: drewr: make-task is returning a instance there. As long as that's what you need, proxy is perfect.

16:47 drewr: yeah, I see what you were talking about now

16:48 you wanted to create a true subclass that could then be instantiated

16:48 chouser: right.

16:48 well, apparently that's what some java libs, unfortunately, require. :-/

16:49 drewr: then I recommend cron4j :-)

16:51 chouser: ,(str (.newInstance (class (reify Object (toString [] "foo")))))

16:51 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IPersistentVector

16:52 chouser: anyway, that seems to work ok as long as you don't close over anything.

16:54 neilmock: drewr: i was needing to possibly get down to the millisecond if necessary (extreme case) but normally right at a second mark, doesn't seem like cron4j is suited for that but i could be missing something

16:56 drewr: neilmock: no, cron4j wakes up every minute

17:06 polypus: you guys know if this code has been released yet, and what it's called:

17:06 http://vimeo.com/7722342

17:08 alexyk: how do I define a Clojure proxy equivalent to http://paste.pocoo.org/show/156231/ ?

17:10 specifically, how do I define the constructor & weight and id members?

17:10 hiredman: polypus: they repo urls in the video

17:10 alexyk: you don't

17:11 polypus: hiredman: thx, i must have scrubbed by it

17:11 dabd: hi I'm using enclojure and I'm trying to call some clojure code from java and I'm getting this error 'Could not locate Clojure resource on classpath'

17:11 the clj files are not included automatically in the classpath?

17:11 alexyk: hiredman: hmm... but I need weight in there

17:11 hiredman: proxy a. doesn't let you create a new interface (no new members) and b. proxy does not let you create constructors

17:12 proxy is not for creating classes, it is an interop construct

17:13 alexyk: so I have to do it in Java?... unless there's an interface? this class is a parameter to a graph library

17:14 hiredman: or use gen-class

17:14 you can also proxy a class, not just interfaces

17:14 proxy "methods" are fns so they close over locals

17:15 and you can pass arguments through to an existing constructor

17:16 alexyk: ah, prolly gen-class then

17:16 hiredman: I doubt it

17:17 if you are passing to an existing java library then that existing java lib expects something of a certain class and you can just proxy that

17:46 danlarkin: What's the reasoning behind (not= #{1} '(1))?

17:47 stuartsierra: danlarkin: different types

17:47 danlarkin: Since = check value, and their values are the same

17:47 but (= 1 1.0), those are different types too

17:48 stuartsierra: = tests arithmetical equality, then Java .equals()

17:48 danlarkin: and (= [1] '(1))

17:48 KirinDave_: ,(not= #{1} '(1))

17:48 clojurebot: true

17:48 KirinDave_: That seems intuitive.

17:48 stuartsierra: ,(= [1] '(1))

17:48 clojurebot: true

17:49 stuartsierra: That doesn't.

17:49 KirinDave_: Yeah

17:49 chouser: danlarkin: should (= #{1 2} '(1 2)) ? what about (= #{1 2} '(2 1)) ?

17:49 KirinDave_: That's a little weirder.

17:49 danlarkin: = is value based, not order, not type

17:49 hiredman: KirinDave_: a set is an unordered thing, and a list is ordered

17:49 ,(= [1] '(1))

17:49 clojurebot: true

17:49 KirinDave_: hiredman: Don't have to argue with me.

17:50 hiredman: er

17:50 danlarkin:

17:50 whoever

17:50 KirinDave_: lol

17:51 devlinsf: Here's an interesting one

17:51 ,(= (sorted-map "a" 1 "b" 2) {"a" 1 "b" 2})

17:51 clojurebot: true

17:51 hiredman: should #{1 2} = '(1 1 2) then?

17:52 technomancy: it is a bit weird that comparing vectors and lists ignores type

17:52 devlinsf: ,(= (sorted-map "a" 1 "b" 2) {""b" 2 a" 1})

17:52 clojurebot: java.lang.Exception: Unable to resolve symbol: b in this context

17:52 technomancy: but I can see how orderedness could be considered part of the value of a list in some way

17:52 *some way that doesn't apply to sets

17:52 devlinsf: ,(= (sorted-map "a" 1 "b" 2) {"b" 2 "a" 1})

17:52 clojurebot: true

17:53 devlinsf: technomancy: Thought on my map examples?

17:54 technomancy: devlinsf: I'm puzzling over whether these are inconsistencies

17:54 hiredman: a sorted map is a map

17:54 devlinsf: but a hash-map isn't sorted

17:54 Suppose I provide a different comparator to a sorted map

17:54 Simple as increasing & decreasing

17:55 hiredman: but the sort or not doesn't come into play when comparing maps to maps

17:55 a set is not a list, so when comparing various other attributes are taken into account

17:56 devlinsf: Well, the problem is that I can't use the maps interchangably

17:56 hiredman: so?

17:56 danlarkin: so maybe = takes into account value and ordering properties

17:56 devlinsf: Right.

17:56 danlarkin: but not type in and of itself

17:56 devlinsf: Or is hiredman right and it doesn't matter

17:56 ?

17:57 This question hit me on the way home from work

18:00 ,(= (sorted-map-by compare "a" 1 "b" 2) (sorted-map-by (comp - compare) "a" 1 "b" 2))

18:00 clojurebot: true

18:01 hiredman: both maps, and for maps the value comparison has great presedence than order

18:02 would you rather sorted and unsorted maps with the same content be considered unequal?

18:02 devlinsf: I'm not sure

18:02 What is "content" in this case?

18:02 hiredman: the keys and the values

18:02 are you kidding?

18:02 devlinsf: Nope

18:03 Is the comparator part of the value?

18:03 The issue is I'm talking about a more specific map

18:04 hiredman: sorry, "what is content" tripped my bikeshed-o-meter so I am no longer part of this

18:04 LauJensen: New blogpost, explaining where ClojureQL is now and our recent move to a new build system: http://www.bestinclass.dk/index.php/2009/12/clojureql-where-are-we-going/

18:05 devlinsf: hiredman: okay, fine

18:06 hiredman: It's an academic discussion anyways

18:07 replaca: Q: I have a def with metadata: (def #^{...} sym val). I want to create a new root binding (i.e. a new def) and attach the same metadata, but I don't know how

18:07 Something that feels like (def #^(meta #'sym) val), but that's not right

18:08 anyone know how to do that?

18:08 hiredman: .alterRoot

18:08 (.alterRoot #'foo whatever)

18:09 replaca: ahh, thanks. Does that just not touch the metadata?

18:09 stuartsierra: or (def thing) followed by (alter-meta! thing (meta #'foo))

18:09 hiredman: I'm not sure. but I doubt it

18:10 ,(doc alter-var-root)

18:10 clojurebot: DENIED

18:10 hiredman: :|

18:10 replaca: stuartsierra: cool, though I've obviously got to grab (meta #'foo) before the def

18:11 hiredman: hmmm

18:11 alter-var-root does nuke the metadata

18:12 replaca: ok. It would be nice in general if metadata were retained in all these situations if we didn't explicitly create new metadata

18:13 for example, (declare foo) nukes the metadata on foo

18:13 which is bad if you've got a system that wants to not care about definition order

18:13 (like autogenerated code, sometimes)

18:16 hiredman: replaca: all declares should go at the top in that case regardless

18:18 replaca: hiredman: yeah, but if you have separate components generating fragments, that might be a burden

18:19 hiredman: generally, it feels like declare should be a no-op relative to value and metadata, just a statement about the fact that the symbol is a valid var

18:19 (or it does to me)

18:26 hiredman: replaca: a "metadata policy" compliance audit might be in order

18:27 it can be easy to overlook what happens to metadata when you write a new macro or whatever

18:28 and people use with-meta instead of vary-meta

18:31 replaca: hiredman: good points - metadata in Clojure reminds me a little bit of locking in Java programs: programmers have a tendency to forget about it

18:32 hiredman: well, it is only metadata :P

18:35 replaca: yeah, depends how real we want it to be

18:35 so far it's mostly a concept thing with a few hard uses (func info, :tag,...?)

18:35 qed: anyone here have some yasnippets made up already for clojure?

18:37 skybound: i'd appreciate a hint on howto restructure a flat sequence to a nested one; for example given: '(1 :o 2 :c 3 :o 4 :o 5 :c 6 :c 7) how could i get this: '(1 (2) 3 (4 (5) 6) 7) ? my best guess is something using core.walk, but i don't get anywhere.

18:40 technomancy: qed: hopefully you don't need snippets for writing clojure since there isn't much boilerplate

18:41 qed: i dont really, but im mucking around learning yas, so im making a few

18:41 just made a simple little defn

19:14 hiredman: hmmm

19:14 doing the quoting in macros that write macros

19:15 :|

19:15 _ato: twbray: it's surprisingly hard to fully utilize the niagra isn't it? my first version maxed out at 900% CPU. I think it was bottlenecking because one thread was doing IO and passing chunks of lines to the other threads. I'm working on a version that has each thread doing its own IO

19:16 twbray: _ato: It's really easy to max the sucker out with a well-configured Apache + PHP or Rails or EE or whatever.

19:16 So for Web serving, we don't have a concurrency problem. For lots of other stuff, though, it's way too hard.

19:17 _ato: yeah, if you can do more or less share-nothing it's no problem of course, but it's when you need communication between threads that concurrency gets hard

19:22 twbray: _ato: my code is up on http://kenai.com/projects/divide-and-conquer - you might want to look at read_lines.clj Another version at paralines.clj uses java NIO mapping, but its performance is weirdly variable.

19:23 _ato: 14163 ato 65 0 0 2083M 799M cpu 9:17 2736% java

19:24 yay! that's more like it :)

19:25 _mst: hah :)

19:25 twbray: In fact there are only 8 cores...

19:25 ... each of which has two integer threads ...

19:26 ... oops, eachof which *can run* two integer threads ...

19:26 ... but has 4 thread caches which can switch in in 1 cycle ...

19:26 ... and the OS can't tell whether a thread in one of the caches in runnable state is actually running ...

19:27 ... which is to say, CPU reports up to 1600% or sort of believable. Above that it's sci-fi.

19:28 It will sometimes report up to 3200%, e.g. on a heavily loaded web server. But only 16* the clock rate is actually happening. Worse if there's floating point.

19:28 still, 16 * 1.4GHz is a *lot* of computing.

19:29 _ato: ah that's right. I think I attended a talk on the niagra. It picks whichever instruction it can execute from the 4 threads instead of doing reordering of the one thread like a typical x86 would

19:30 twbray: It has massive memory controllers, memory bandwidth is fantatic. This one has rather ordinary disks though.

19:30 cp2: interesting

19:31 twbray: Should be a good machine to run clojure on :)

19:31 cp2: i feel this is required...

19:31 imagine a beowulf cluster of those!

19:32 twbray: Dmitriy V'yukov is getting fantastic numbers < 4 min on the whole 45G. But he's using C and going obscenely close to the metal.

19:32 _ato: wow

19:33 twbray: Dmitriy says: real 3m12.941s

19:34 also: I use things like "probing" data as to whether it's cached or not, switching between multithreaded read-based reading and single-threaded aio-based reading, dynamic thread count tuning, etc. Dirty...

19:34 technomancy: amazing speed, but at what cost? will he be sane a week from now? =)

19:35 twbray: technomancy: not clear to me that this community is 100% sane either. Look at you guys...

19:35 technomancy: touché

19:35 twbray: I am deeply appreciative of this kind of insanity.

19:38 * technomancy covers the "my other car is a cdr" sticker on his laptop discreetly

19:42 devlinsf: http://www.zazzle.com/my_other_car_is_a_cdr_bumper_sticker-128776132386843273

19:45 technomancy: yeah, that one. =)

19:56 qed: haha that's a great bumper sticker

20:32 chouser: "my other first is a next" just doesn't have the same ring.

20:34 mee: some folks in here might find this interesting (or perhaps painful) http://chuck.cs.princeton.edu/

20:41 chouser: the time it takes for me to understand a new language well enough to make any kind of judgement about it, or learn anything useful from it is still prohibitively high.

20:42 it's much easier to take shortcuts. "it has mutable locals? well, nevermind then..."

21:03 devlinsf: Yo, when did flatten change

21:03 ?

21:04 Okay... fixed.

21:10 lghtng: ,(+ 2 2)

21:10 clojurebot: 4

21:11 lghtng: there was a guy in efnet #ai who made a prolog bot that did all kinds of amazing things

21:11 devlinsf: chouser: Hey, I left you with a riddle for using take-while with a map

21:11 chouser: Any ideas of a use case? :)

21:12 dmiles_afk: lghtng: like what?

21:12 lghtng: it could run alot of prolog code

21:12 as well as all the infobot stuff

21:13 i dont know that it was a hacked eggdrop but i want to say it was

21:13 hiredman: "import infobot fact packs" has been in clojurebot's TODO forever

21:14 as in, add support for importing

21:15 dmiles_afk: yes it used an eggdrop as an outer skin

21:15 lghtng: was that your bot?

21:16 dmiles_afk: but underneath it was SWI-Prolog

21:16 it might have been

21:16 * dmiles_afk is still working on it :)

21:16 lghtng: i used to go in there once in awhile and goof around with it, this was in, like 98

21:16 dmiles_afk: but havent ran it on irc for a while

21:17 now i am working a more complete Lisp+Prolog+CLojure+CYC version ;)

21:17 lghtng: hiredman: do you have an idea about what kind of format you want the data stored in?

21:17 hiredman: uh

21:18 clojurebot stores stuff in triples

21:18 subject | predicate/verb | object

21:18 lghtng: like allegrograph?

21:18 hiredman: no idea

21:18 I just know clojurebot does it that way

21:18 if I recall infobot just keeps two dictionaries

21:19 are and is

21:19 lghtng: 'howto Multi-Disk => <reply> $who, http://metalab.unc.edu/pub/Linux/docs/HOWTO/Multi-Disk-HOWTO'


21:19 hiredman: yeah

21:19 and that would be in the is or the are dictionary

21:20 lghtng: should it parse the file into its own db then discard it from memory? in other words can the import just be a read from the infobot site url holding the directory?

21:21 dmiles_afk: might even be litterally a java.util.Hashmap by the time you get down to it

21:21 hiredman: dmiles_afk: infobot is perl

21:21 dmiles_afk: well at least provides a java.util.Map interface to satisfy cojures want for a disctioary

21:21 oh i was fantisizing it was purely clojure

21:22 hiredman: lghtng: easiest would be just to dump it in the existing db

21:22 clojurebot stores the tripples in derby

21:22 (for some reason)

21:22 lghtng: so you really just need a function that will parse http://www.infobot.org/factpacks/ into derby

21:23 hiredman: meh

21:23 just feed it through clojurebot's function for writing factiods

21:24 lghtng: or even query http://www.infobot.org/factpacks/ on the fly from the search term

21:24 hiredman: anyway, have fun

21:25 lghtng: ok, it's now on my someday/maybe list :D

21:32 interferon: update-in can take an array of keys and update the array; is there a function that takes a map and an array of keys and returns the value there?

21:33 hiredman: not an array

21:33 vectors are not arrays

21:33 interferon: you're right

21:33 i guess it's probably actually a seq

21:33 hiredman: ,(doc get-in)

21:33 clojurebot: "([m ks]); returns the value in a nested associative structure, where ks is a sequence of keys"

21:33 interferon: but is there a function that does that?

21:34 thanks

21:35 dmiles_afk: lghtng: i am working on a more advanced factio system: http://logicmoo.ath.cx/manual/root/home/kifbot/testE2C

21:36 the idea is it parses facts and queries into predicate logic

21:38 betyter formated version http://opensim4opencog.googlecode.com/files/E2C.htm

21:39 opensim4opencog is a bot that is programmed in clojure for SecondLife

21:39 but gotta get the bots brain caught up to understanding english again at that level

21:42 alexyk: how do you filter a map by deleting a set of keys?

21:42 lghtng: http://www.franz.com/agraph/support/documentation/current/agraph-introduction.html#header3-20

21:42 devlinsf: alexyk: What do you mean?

21:43 alexyk: devlinsf: I have a seq of maps and need to filter each by removing a set of keys

21:43 hiredman: ,(reduce dissoc {:a 1 :b 2 :c 3} [:b :c])

21:43 clojurebot: {:a 1}

21:43 hiredman: actually

21:43 arbscht_: ,(doc dissoc)

21:43 clojurebot: "([map] [map key] [map key & ks]); dissoc[iate]. Returns a new map of the same (hashed/sorted) type, that does not contain a mapping for key(s)."

21:43 hiredman: ,(apply dissoc {:a 1 :b 2 :c 3} [:b :c])

21:43 clojurebot: {:a 1}

21:45 dmiles_afk: lghtng: i keep trying to decide if Allegro Graph store is faster than a native prolog store.. almost tempted at some point to prsent a prolog store as a AllegroGraph store to lisp ;)

21:47 lghtng: franz makes some pretty outrageous claims about its speed

21:47 dmiles_afk: the arg indexing of AG though i think gets it fast as heck

21:47 alexyk: hiredman: (apply dissoc m [keys]) is the same as (dissoc m k1 k2 ...) -- does apply do it slower?

21:48 hiredman: alexyk: I doubt it

21:48 dmiles_afk: lghtngL in a few days i should have SWI-Prolog vs "using prolog with AG"

21:48 alexyk: hiredman: does apply create intermediate maps?

21:49 hiredman: nope

21:49 reduce does

21:49 alexyk: cool

21:49 dmiles_afk: lghtng: (i keep meaning to benchmark)

21:50 alexyk: rhickey: great talk "are we there yet"! the only glitch is a bald pate in the center bottom of the frame :)

21:51 but that's the cameraman's problem

21:53 lghtng: the first hit on google for 'java rdf' is http://jrdf.sourceforge.net/

21:53 but jena might have more tools

21:54 alexyk: lghtng: neo4j is good, too

21:54 I store triples in MongoDB via congomongo

21:55 and adjacency lists and anything else. I doubt you can go much faster...

21:58 lghtng: but really, it might be more lispy to just worry about a clojure-sparkl library and let the chips fall where they may :D

21:59 clorqle

21:59 * lghtng chuckles

21:59 lghtng: clojkle

21:59 polypus: there's also sesame and mulgara

21:59 alexyk: I like clorqle. It's like gurgle.

22:01 hiredman: http://github.com/richhickey/rdfm

22:03 polypus: alexyk: do you have the congomongo set up in production?

22:03 alexyk: polypus: I have no production. :)

22:04 academic research...

22:04 polypus: just curious cuz i'm now evaluating various rdf backends for a production app.

22:04 alexyk: mongo is good for general DB

22:04 polypus: i don't even know if anybody in the real world is using anything other than rdf ontop of sql

22:05 alexyk: JSON-like

22:06 polypus: not that academic research aint real :)

22:06 alexyk: how do I pass functions in general? trying: (defn applyf [f s] (map f s)); (applyf #(print %) (1 2 3)) ; error

22:07 polypus: alexyk: your last list is not quoted

22:07 hiredman: error is the least informative possible desciption of an error

22:08 alexyk: hiredman: the assumption it's obvious :)

22:08 polypus: thx

22:08 hiredman: ,(applyf #(print %) (1 2 3))

22:08 clojurebot: java.lang.Exception: Unable to resolve symbol: applyf in this context

22:09 alexyk: ,(member:defn applyf [f s] (map f s))

22:09 clojurebot: java.lang.Exception: Unable to resolve symbol: member:defn in this context

22:09 alexyk: it stuck 'member' in somehow

22:21 lghtng: lol, i found your nyc lisp page

22:24 defn: hey all

22:24 devlinsf: Yo

22:24 defn: what's up

22:25 devlinsf: Eh, writing code :)

22:26 defn: I wonder if clojure could be a part of the GSoC next year...

22:26 that'd be fun

22:36 alexyk: are there ways to shorten this: (let [a (:a m) b (:b m)] ...) ?

22:37 hiredman: ~destructuring

22:37 clojurebot: destructuring is http://clojure.org/special_forms#let

22:38 alexyk: cute!

22:40 * alexyk likes Clojure

22:49 alexyk: how do you convert :a to "a" ?

22:49 chouser: ,(name :a)

22:49 clojurebot: "a"

22:50 alexyk: thx

22:54 ,(doseq [x '({:user "a" :reps {:a 1 :b 2}})] (let [{ a :user rs :reps} x] (for [to (keys rs)] (print to))))

22:54 clojurebot: nil

22:54 alexyk: why nil?

22:55 lghtng: lovely inspiration for me here tonight, im diving into the sparql tr

22:55 defn: so im in my REPL, and im interested in taking all of the forms in compojure/*, and printing their (doc *) for all of the possible completions, to a text file

22:55 how would i do that?

22:55 alexyk: compare:

22:55 ,(doseq [x '({:user "a" :reps {:a 1 :b 2}})] (let [{ a :user rs :reps} x] (print (keys rs))))

22:55 clojurebot: (:a :b)

22:56 chouser: defn: ns-publics gets you the vars of a namespace, (:doc (meta a-var)) gets you the docs, duckstream can write to a file easily.

22:56 defn: go!

22:56 defn: lol thanks :)

22:56 chouser: :-)

22:57 alexyk: map is lazy

22:57 alexyk: so why above, (for [to (keys rs)] (print to)) prints nothing? is it map inside?

22:58 chouser: oh, sorry.

22:58 alexyk: for is lazy

22:58 alexyk: :)

22:58 should I whip it with doall?

22:58 chouser: (for ....) returns a lazy seq, ready to print as soon as anything forces it.

22:59 but doseq doesn't force it and always returns nil.

22:59 alexyk: why not another doseq?

22:59 alexyk: chouser: print is for testing, I'll add edges to a Java graph. So should I doseq it too? without bindings?

23:00 ah, doseq instead of for, ok.

23:00 chouser: if you're mutating things, doseq is good.

23:00 alexyk: yep, works.

23:00 chouser: better would be of course to write it functionally, take input, return a graph. In that case, you'll want something other than doseq for the outer loop too.

23:01 alexyk: well, my graph is tens of millions of nodes...

23:04 technomancy: chouser: I heard you decided on a name for the book?

23:05 chouser: technomancy: that's what I heard too

23:05 defn: did someone say book?

23:05 chouser: clojure book?

23:07 interferon: i have a map like this {:a {:b [1, 2, 3, 4], :b {:c [5, 6, 7]}} i'd like to apply a function to the map that transforms the vectors inside, so the result might be something like {:a {:b 10}, :b {:c 18}}

23:07 devender: hi what does xrel mean ?

23:08 it is referred to a lot in the api

23:08 http://richhickey.github.com/clojure/clojure.set-api.html#clojure.set/index

23:08 chouser: devender: just for clojure.set fns, right?

23:08 devender: yeah

23:08 is it just a map ?

23:09 chouser: set of maps

23:09 devender: oh ok thanks

23:09 interferon: in general, i have a hard time transforming arbitrary parts of a data structure like the one above

23:10 chouser: interferon: update-in

23:10 interferon: hmm

23:10 that would do it

23:11 chouser: hm, though if you're mapping...

23:12 interferon: is there a better way?

23:12 i should mention that i don't know the keys in advance

23:13 i'm manipulating a structure i created elsewhere that looks like {2009 {34 [ .... ] 45 [ ....]} 2008 {4 [ ...] }}

23:17 defn: hmm, chouser: (defn sort-ns [nspace] (sort (keys (ns-publics nspace)))) (defn emit-docs [file-name, nspace] (append-spit (file-str "~/path/to/" file-name) (map #(doc %) (sort-ns nspace))))

23:17 something is funky there with the map #(doc %) im guessing

23:17 Unable to resolve var: p1__2355 in this context

23:18 interferon: chouser: any other approaches? i could loop through each level of keys and then do an update-in

23:18 chouser: it is a bit tricky to think about. I don't think update-in gets you much closer.

23:19 you want more of a map-in, if there were such a thing.

23:19 maybe devlinsf's visitor fns would help, but I haven't wrapped my head around them yet.

23:19 devlinsf: Hey

23:20 Gimme a sec...

23:21 (map-vals map #(map-vals map vec %) interferon-map)

23:22 That should do the trick

23:22 chouser: see, that's much better than what I've got going here.

23:22 devlinsf: I'll post my stuff to github... gimme a sec

23:22 chouser: wait, that can't be right

23:23 he wants to sum the vectors

23:23 devlinsf: Hmmm

23:23 Okay....

23:23 interferon: sorry, i got dropped

23:24 devlinsf: (map-vals map #(map-vals map (partial reduce +) %) interferon-map)

23:24 That should do it

23:24 interferon: is map-vals built-in?

23:25 and what is in interferon-map? :)

23:25 oh it's the variable?

23:25 got it

23:25 devlinsf: Your map

23:25 map-vals is a visitor I wrote

23:25 defn: (map #(doc %) (sort (keys (ns-publics 'compojure))))

23:25 => Unable to resolve var: p1__2742 in this context

23:25 chouser: ,(let [m {:a {:b [1, 2, 3, 4]}, :b {:c [5, 6, 7]}}] (into {} (map (fn [[k m2]] [k (zipmap (keys m2) (map #(apply + %) (vals m2)))]) m)))

23:25 clojurebot: {:a {:b 10}, :b {:c 18}}

23:26 devlinsf: http://github.com/francoisdevlin/devlinsf-clojure-utils

23:26 chouser: I'll be back a bit later

23:26 devlinsf: My repo

23:26 Check lib.sfd.map-utils

23:26 docs are in process

23:26 alexyk: does doseq take many forms or needs a do for many?

23:26 defn: Can anyone illuminate what the error I'm getting is caused by?

23:27 It seems rather natural to map #(doc %) across a collection of forms

23:27 err the form names

23:30 interferon: devlinsf: looks like map-vals is (map-vals f coll)

23:30 technomancy: replaca: is there any way to indicate to pprint that values in a list should be lined up as key/value pairs like when pprinting a hash?

23:30 devlinsf: No

23:30 technomancy: *a map

23:31 devlinsf: It's a visitor. It modifies a higher order fn

23:31 Like I said, the docs are in process

23:31 It's (map-val mappping-hof f coll)

23:31 defn: ,(map #(doc %) (sort (keys (ns-publics 'compojure))))

23:31 clojurebot: java.lang.Exception: No namespace: compojure found

23:32 devlinsf: Oh, wait....

23:32 Wrong fn!!!

23:32 interferon: :)

23:32 defn: woops on the ',' -- just trying to figure out why I can't map #(doc %) across the collection of keys from ns-publics to get documentation for all of the elements in the list

23:32 devlinsf: (Work in progess, sorry)

23:32 interferon: np appreciate the help

23:32 devlinsf: You want vals-entry

23:33 defn: i tried quoting '%, but no such luck

23:33 devlinsf: Start with this post

23:33 http://groups.google.com/group/clojure/browse_thread/thread/7bb01c23596f6636

23:34 It explains the visitor hof I wrote

23:34 Then read this

23:34 http://groups.google.com/group/clojure-dev/msg/6c1bbce17cafdf52

23:35 I'll try to get some docs on github in the next 24-36 hours

23:35 interferon: thanks

23:36 devlinsf: No problem

23:36 The interesting fns are vals-entry, keys-entry, vals-pred & key-pred

23:39 alexyk: technomancy: why run repl as -client, not always -server?

23:39 (in lein)

23:39 technomancy: alexyk: java -server has a really rotten VM boot delay

23:40 alexyk: technomancy: ah! then it may be an option, like, "script kiddie=>client, dataminer => server" :)

23:40 defn: hmm, what is this (:doc (meta %)) stuff

23:40 how do i find out more about :doc?

23:40 technomancy: alexyk: well it's unlikely to matter for the repl, but I suppose it could for other tasks

23:40 defn: docstrings are syntax sugar for adding a :doc key to an object's metadata map

23:41 alexyk: most lein tasks are meant to be run interactively though, which is what -client is meant for

23:42 defn: technomancy: im not sure i follow

23:42 alexyk: technomancy: I run long jobs in repl, is it sinful?

23:43 technomancy: alexyk: the general consensus is that you will need to say seven hail marys to atone.

23:43 alexyk: technomancy: will the said marys run my code as fast as from a stand-alone jar?

23:44 technomancy: defn: (def #^{:doc "a function I wrote"} my-fn (fn [x] (+ x x))) => (defn my-fn "a function I wrote" [x] (+ x x))

23:44 * technomancy loves having paren matching in IRC

23:44 defn: ahh thanks technomancy

23:45 technomancy: alexyk: heh. the only reason I'm reluctant is that you'd have to add logic to the shell script to do that, and I hate maintaining shell code. but you may have a point.

23:46 alexyk: but maybe honoring $JAVA_OPTS would be enough?

23:46 KirinDave1: technomancy: You have paren matching in irc?

23:47 technomancy: KirinDave1: natch, M-x erc

23:47 KirinDave1: lol lol lol

23:47 I gotta say, I just can't get into emacs coding on a large scale

23:47 I can do small things

23:48 But I am amazed at people who go to great lengths to make things like irc clients. I think it's brutal

23:48 alexyk: technomancy: let's start with $JAVA_OPTS and ramp up slowly :)

23:49 BTW: -client or -server can go into JAVA_OPTS.

23:49 so you may stick it there unless there's a -server or a -client there already

23:51 technomancy: alexyk: I checked; you can have -client and -server both; whichever is last wins. =)

23:51 KirinDave1: the lack of lexical scoping is annoying, but hardly crippling. but UI work is always challenging.

23:51 hiredman: technomancy: while you are at it /bash/sh/s :P

23:52 technomancy: hiredman: I'm reluctant to do so since from what I understand Linux systems usually don't have sh; they just symlink bash to sh. so I don't have a way to make sure I don't accidentally rely on some bash-specific functionality

23:52 though I could be misremembering

23:53 hiredman: technomancy: you dev on macosx right?

23:53 technomancy: hiredman: no, ubuntu

23:54 hiredman: you could install dash

23:54 technomancy: hiredman: is bash a problem on some systems?

23:54 (systems people actually use, I should say)

23:54 hiredman: https://wiki.ubuntu.com/DashAsBinSh

23:55 technomancy: it's not always in /bin

23:55 looks like since 6.10 ubuntu's /bin/sh is not bash

23:56 technomancy: hiredman: ah; I am woefully out of date

23:59 KirinDave1: technomancy: It's also annoying how everything needs to be so buffer centric

Logging service provided by n01se.net