#clojure log - Apr 15 2011

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

0:00 livingston: but all keywords are? (makes sense just checking)

0:00 amalloy: livingston: i stand by "all keywords are". refuse to make myself an idiot by asserting something i'm not sure of re: symbols

0:00 livingston: and what happens if I scan through a 100,000,000 of these things ? how bad to I permanently crud up my symbol table?

0:01 cemerick: symbols are not interned, but their components are

0:01 ,(identical? (name 'f) (name 'f))

0:01 clojurebot: true

0:02 livingston: amalloy: that's actually a really nice example a potentially good argument (square brackets just seem more "angry" to me)

0:02 amalloy: &(name 'f)

0:02 sexpbot: ⟹ "f"

0:02 technomancy: chewbran1a: heya

0:02 amalloy: if you have a hundred million variations on foo1234, don't make them into keywords

0:02 because you won't be typing them literally

0:02 technomancy: cemerick: "interned" means something different in CL-land IIRC

0:02 livingston: the names have to be identical, because they are java strings and thats the rule for the java string table, right?

0:03 amalloy: livingston: i don't believe so

0:03 cemerick: java string table?

0:03 amalloy: &(identical? "a" (apply str (rest "ba")))

0:03 sexpbot: ⟹ false

0:03 amalloy: &(= "a" (apply str (rest "ba")))

0:03 sexpbot: ⟹ true

0:03 cemerick: technomancy: Yeah, I've successfully forgotten all that.

0:03 livingston: technomancy: cemerick: in CL interned means in the namespaces symbol table (you can have symbols that aren't internned and thus not in the symbol table)

0:03 chewbran1a: technomancy: hey how's it going? got a silly leiningen question for ya

0:04 technomancy: chewbran1a: sure; go for it

0:04 cemerick: livingston: there is a keyword "table"; there is no such thing for symbols (they intern their string components in the JVM).

0:05 livingston: cemerick: that makes sense, thanks

0:05 cemerick: amalloy: The keyword churn thing is apparently fixed in 1.3 head IIRC

0:05 livingston: churn thing?

0:05 amalloy: cemerick: do keywords that nobody has a reference to anymore actually get un-interned?

0:06 cemerick: amalloy: AFAIK, yes

0:06 amalloy: cool

0:06 chewbran1a: technomancy: bah... like I said it was silly, was trying to add another dependency but forgot to restart my nailgun server

0:06 cemerick: That was actually supposed to be the case in 1.2, but something went awry in the implementation.

0:06 I think that fix is in 1.2.1 as well?

0:06 chewbran1a: technomancy: finally diving into a small clojure project

0:07 livingston: the reason there will be boat loads of these things is I have an RDF triple store with say 6.8B triples in it... I'll run a query and look for something, I could get a lot of responses that I have to look through or process etc. they will be processed as symbols/keywords/whatever-you-all-tell-me-isn't-going-to-kill me

0:07 cemerick: livingston: i.e. the retention of created symbols even after they are no longer in active use.

0:07 technomancy: chewbran1a: sweet

0:07 chewbran1a: yeah, it's a shame new dependencies can't be loaded up into the currently-running process; it's a silly limitation of the JVM =\

0:08 cemerick: livingston: Absolutely do not use symbols from that. Interned Java strings simply cannot be un-interned, period. You'll crush your permgen every time.

0:08 chewbran1a: technomancy: hahaha yeah, just found that one out, good to know

0:08 livingston: if symbols / keywords with no pointers to them, get GC'ed I'm ok...

0:08 * cemerick now wonders if java strings are interned outside the heap entirely…

0:09 livingston: cemerick: right, I'm really worried about that, but if these things are fundamentally string data? what else could I do?

0:09 chewbran1a: technomancy: any recommendations on a json lib?

0:09 cemerick: livingston: only keywords for you, then, unless the domain of name and namespaces used in the symbols in question is fixed/size-limited

0:09 technomancy: the keyword intern fix for 1.2.1 was about a race condition; apparently the weakref fix didn't get included

0:10 livingston: cemerick: namespace is finite, names is finite but the number is in the billions

0:10 technomancy: chewbran1a: we are using https://github.com/dakrone/cheshire at work; danlarkin's json lib is also good.

0:10 cemerick: technomancy: so 1.3 HEAD it is, I take it?

0:10 technomancy: cemerick: ja

0:11 cemerick: livingston: get thee on the latest of 1.3, and use keywords

0:11 livingston: keywords know their name though, right? so that had to be a string at one point and will end up doing whatever every other string does, right?

0:11 cemerick: Keywords' strings aren't interned though.

0:11 They will get GC'd.

0:11 chewbran1a: technomancy: cool, cheshire looks like it will do the trick

0:12 livingston: oh, you can do that in the jvm?

0:12 cemerick: do what?

0:13 amalloy: livingston: i just demonstrated that not all strings are interned, didn't i? "a" wasn't identical to "a"

0:13 livingston: cemerick: not intern a string

0:13 cemerick: no, strings are not interned by default

0:13 mec: literal strings are interned

0:13 amalloy: &((juxt = identical?) "a" (apply str (rest "ba")))

0:13 sexpbot: ⟹ [true false]

0:13 mec: ,(identical? "a" "a")

0:13 clojurebot: true

0:13 livingston: the a that you chopped out of a string, yeah

0:14 chewbran1a: hey not sure if anyone is around who works with clojars.org, but couple comments, first thanks for building it, very useful, as someone new to clojure, I see two issues, first, you sort by modified time in ascending order, that is backwards, I want to see what is actually up to date, not what was updated possibly years ago, second, more meta data about the projects would be nice, I'm having trouble parsing lists of resources to f

0:14 amalloy: livingston: as long as your .clj file doesn't have 100 million strings typed into it you're okay

0:15 chewbran1a: not trying to be rude by any means, just giving some feedback

0:15 technomancy: chewbran1a: yeah, clojars search needs to be totally rewritten.

0:15 it's doing a sqlite query for each search even though there are lucene indices on disk

0:15 chewbran1a: I'm actually thinking about doing that for a seajure hack night =)

0:15 well, I was going to do it client-side, but that code could be adapted for the web site too

0:16 livingston: so just to be clear ... I'm making the vast majority of these "tokens" from the output from another data source coming at me effectively as strings and I have (filter :foo (map keyword giganto-stream-of-output)) I'm not going to blow anything up?

0:16 chewbran1a: technomancy: oh cool, that would be fun

0:16 technomancy: chewbran1a: it's super rough-around-the-edges, but https://github.com/technomancy/lein-search/tree/lucene might be better than the current search on clojars.org

0:16 amalloy: livingston: cemerick says you would blow things up iff you used symbols instead of keywords

0:16 technomancy: plus it searches any repo you've got configured

0:16 cemerick: amalloy: way to pass the buck, man! :-P

0:16 ;-)

0:17 amalloy: cemerick: that's what you get for being helpul. you get blame

0:17 livingston: amalloy: no the clj files will have comparatively few symbols/keywords in them ... the rest come from interpreting the output of the triplestore

0:17 chewbran1a: technomancy: interesting, how well does lucene integrate with sqlite? haven't combined the two before, my first instinct would be to use something like couchdb, seems ideal to be able to just store arbitrary json for project data

0:17 cemerick: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Symbol.java#L50

0:17 * cemerick appeals to the highest authority on Symbol interning

0:17 technomancy: chewbran1a: in this case they are totally separate

0:18 the lucene index is built from the poms on disk

0:18 chewbran1a: I tried to convince them to use couch so that 3rd-party mirrors down the line would be really easy to do with replication, but I think that never went past the exerimental stage

0:18 sqlite seems to be doing the job fine for everything except search

0:19 apparently the traffic is low enough that getting mirrors set up is not a high priority

0:19 chewbran1a: yeah I'm biased towards couch, but sqlite can get the job done, and besides you would have to hooked up lucene to it anyways

0:20 what are the plans for clojars?

0:20 technomancy: I don't know of any plans really

0:20 a while back there were a couple guys who were interested in contributing

0:20 chewbran1a: as in is it something that is considered mostly feature complete, or is there plans to extend it farther to something like cpan that has automated testing and comments and what not

0:21 livingston: unless I'm mistaken keywords do the same thing no? https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Keyword.java

0:21 technomancy: I poked the maintainer and got some "getting started hacking on it" instructions, but I don't know if they went anywhere with it

0:21 chewbran1a: automated testing would probably be a stretch. there are other sites that offer review/comment features though

0:22 amalloy: livingston: you are mistake

0:22 n

0:22 chewbran1a: technomancy: you think so? I figured since its mostly (completely?) all leiningen projects, that it would be too hard to just run lein test on everything

0:22 cemerick: livingston: Keyword.java maintains its own interning map, using WeakRefs and a ReferenceQueue to ensure that unused keywords are ejected. Symbol.java interns component strings in the JVM itself, and has no way to "unintern" those strings.

0:22 technomancy: chewbran1a: well, it's more a question of sandboxing untrusted code, I think

0:23 chewbran1a: technomancy: fair enough

0:23 livingston: amalloy: all the constructors take either symbols or two strings that are immediately turned into a symbol though? wouldn't that entail the same thing as creating a symbol?

0:23 amalloy: livingston: well. kinda seems that way to me so i'ma let cemerick tell us why he's right

0:23 chewbran1a: technomancy: it might just be because I'm still getting familiar with clojure, but when I know of a library I want, clojars/leiningen rocks and works perfectly, but finding those libraries is difficult

0:24 _ato````: chewbran1a: I'm the Clojars guy. Yeah, good idea about descending sort, that's a tiny fix and you're right it would help a lot.

0:25 chewbran1a: technomancy: for instance, I'm looking for a couchdb api, and I'm leaning towards rolling my own because the list of couchdb plugins I get doesn't tell me much: http://clojars.org/search?q=couchdb

0:25 technomancy: _ato````: I'll ping you once I've rewritten lein-search to use lucene

0:25 that code could probably be adapted for server-side use

0:26 _ato: technomancy: cool, yeah that'd be good.

0:26 chewbran1a: _ato: hey glad to get in touch with you, yeah the sorting through me off for a second, thanks for clojars and I hope my criticisms comes off as positive, I'm just on the new to clojure side of the fence so I figured something I could actually contribute to is how the experience is for new users

0:27 technomancy: _ato: are you still in school these days?

0:27 cemerick: Ugh. :-(

0:27 _ato: technomancy: nope

0:28 cemerick: livingston, amalloy: I retract my statements re: Keyword component interning.

0:28 * cemerick wonders what the hell he's doing attempting to give advice this late

0:28 livingston: cemerick: it's cool

0:28 it would have been awesome if you were right

0:29 chewbran1a: as for the couchdb lib thing, just kind of throws me off, at least the 5 most recently updated repos don't have any links to code repos, so I'm just kind of curious, how do you guys go about finding new libs to work with? hit clojars and google down a code base? come in here and ask? or what?

0:29 livingston: it looks like there's no option that precludes loading the java string table / creating symbols etc.

0:30 cemerick: livingston: Simply using strings for your data avoids the whole mess, though I'll recuse myself at this point.

0:30 hiredman: or byte[]s

0:30 _ato: chewbran1a: I follow the mailing list, people tend to announce stuff there. But also: http://www.clojure-toolbox.com/

0:31 I should probably link that from Clojars

0:31 technomancy: simple ratings might be nice to add to clojars, but you'd have to worry about gaming the ratings then.

0:31 there's also http://clojure-libraries.appspot.com/

0:32 chewbran1a: _ato: ahhh nice, good link

0:32 livingston: cemerick: hiredman: neither of those options really seem appealing

0:33 technomancy: I think hiredman was joking

0:33 ?

0:33 livingston: I think I'll just make the thing work like mad, and if it dies I'll deal with it then

0:33 hiredman: well, keywords used to be permanently interned, so possible some solution can be found for symbols

0:34 chewbran1a: well here's the thing, searching couchdb on clojars gives me close to 20 results, so there is bound to be something that will do what I want, so I go down and look at the most recently updated link, and its called 'clojure-couchdb', ok, so I hit google to search for it, and turn up half a dozen different repos on github alone named 'clojure-couchdb'

0:34 brehaut: chewbran1a: have you looked at clutch?

0:34 livingston: I mean making things be pointer equal (which is a really obvious advantage) necessarily requires some kind of interning... it'd be nice if there was a way to know when that interning could go away or somethinng though

0:35 hiredman: but is it required that 'foo be .equals to 'foo

0:35 technomancy: chewbran1a: yeah, a lot of that is just shared community knowledge that isn't captured anywhere canonical. there's still no replacement for asking on IRC.

0:35 hiredman: livingston: well, you would do the samething with keywords, weakref, etc

0:36 technomancy: which is fine by me; I like IRC =)

0:36 livingston: hiredman: right - that's what I want

0:36 chewbran1a: brehaut: yeah I started in on this last night and came across clutch, and it looked interesting, but more heavily focused on creating a clojure based view server when all I'm looking for is a minimal client lib

0:36 livingston: pointer = that is

0:36 banjiewen: chewbran1a: part of the 'problem' may lie with couchdb's interface more than anything - if there are 20 libraries, it's because it's so easy to write one.

0:36 hiredman: I did the original weakref patch for keywords, which never got applied, and then what was applied had a nasty race condition in it

0:37 brehaut: chewbran1a: there is a minimal client lib in there too

0:37 chewbran1a: ive not worried about the view server stuff at all and its worked well for me

0:37 cemerick: chewbran1a: FWIW, clutch's client lib is particularly complete -- the view server is there, but hardly the focus (at least by the devs).

0:38 chewbran1a: technomancy: yeap I'm fine with irc too, but I've been following clojure for a bit now, and one of the things I've seen repeatedly brought up is difficulty for new people to figure out tools and how to get up and running with things, so I figured I would take some 'notes' while going through the process

0:38 livingston: hiredman: bummer

0:38 chewbran1a: banjiewen: yeah agreed, which is why I was about to just roll my own (still might for educational purposes)

0:38 hiredman: well, the race condition was fixed

0:38 but was arond in 1.2.0 for a long time

0:38 chewbran1a: brehaut: ok cool, I'll take another peek at clutch

0:38 hiredman: around

0:39 livingston: oh

0:39 technomancy: yeah, I wired up clojure-http-client to couch in ~40 LOC back in the day just for kicks =)

0:40 banjiewen: chewbran1a: for sure, yeah. I've been up to my eyeballs in couch for nearly 2 years now and haven't found anything more useful than an httpclient and a couple of helpers for formatting querystrings.

0:40 livingston: although the keywords using symbols code entails that every keyword calls symbol, right? so unless symbols (which are two string pointers) and their underlying strings go away everything is there for the long haul

0:40 chewbran1a: lol... so I did actually manage to track down the 'clojure-couchdb' library last updated on clojars.org by pieterbreed, its literally a fork of a fork of a fork of a fork of clojure-couchdb

0:41 banjiewen: *chuckles*

0:41 technomancy: that's another thing that clojars needs; a way to visually emphasize the original over the forks.

0:41 it's debatable whether org.clojars.foo hits should even show in the default search at all

0:42 chewbran1a: banjiewen: yeah that's definitely one nice thing about couchdb, if you have an http client, you're set, and I just got setup with clj-http ;-)

0:42 technomancy: yeah, gnir is great

1:09 semperos: I second "make finding 'the right' jar on Clojars more intuitive", esp. WRT org.clojars.foo

1:20 carllerche: what are people's preferred testing libraries?

1:22 amalloy: carllerche: midje looks crazy-awesome, but when i tried to use it i couldn't figure out the syntax. i'd say take a look at that and if you figure it out plz teach me

1:22 carllerche: amalloy: alright, i'll take a look!

1:23 huh, it does look interesting

1:25 livingston: i love when I have apparently equal code that does two different things deterministically... maybe I need a testing library

1:31 oh that was a huge waste of time... so a lazy seq that is actually read outside of the (binding) block that created it will use the values for the *var* in the scope when the lazy seq is expanded?

1:31 not those that were in play inside the binding scope that created it?

1:33 amalloy: livingston: that's exactly the difference between dynamic and lexical scope

1:35 livingston: but this isn't good: (def *foo* 1) (binding [*foo* 2] (map (fn [x] *foo*) '(2 3))) versus (binding [*foo* 2] (doall (map (fn [x] *foo*) '(2 3))))

1:35 the first returns (1 1) the second (2 2) that seems really off to me

1:36 amalloy: livingston: because you are imagining that dynamic scope is lexical

1:36 you can use ##(doc bound-fn) to work with this

1:36 sexpbot: ⟹ "Macro ([& fntail]); Returns a function defined by the given fntail, which will install the same bindings in effect as in the thread at the time bound-fn was called. This may be used to define a helper function which runs on a different thread, but needs the same bindings in place."

1:36 livingston: yeah, well crap

1:37 I want lazy seqs, but I also want them to have my bindings, os I need to call fntail and create a new function before I map

1:40 I have a library that has helper methods like (foo kb query) and if it's called with out the first arg (foo query) it just uses the value of *kb* for the kb. but now anything it produces is potentially borked.

1:56 amalloy: to...call...fntail?

1:57 livingston: ?

1:59 amalloy: livingston: fntail does not exist as a callable thing. it is the name of the argument to boundfn

2:00 livingston: oh

2:00 amalloy: it's not exactly well documented, but there are several places that use "fntail" to mean "whatever you would use to fill in the blank in (fn ____)"

2:00 the "tail" of a fn

2:01 livingston: ah

4:17 markoman: how can you match and replace list of items? (s/replace "1234" [2,3] "") -> "14"

4:18 documentation says match can be a pattern or function

4:20 tomoj: match can be a string, char, or pattern

4:20 it's replacement that can be a function

4:21 do you really have a vector of integers?

4:24 markoman: hmh, ids might be integers yes, but can be converted to strings, or should in this case

4:25 tomoj: pretty weird

4:25 raek: ,(clojure.string/replace "1234" #"2|3" "")

4:25 clojurebot: "14"

4:25 raek: ,(clojure.string/replace "abcd" #"[bc]" #(.toUpperCase %))

4:25 clojurebot: "aBCd"

4:25 tomoj: are all the ids single-digit?

4:26 raek: ,(re-pattern (apply str (interpose "|" [1 2 3])))

4:26 clojurebot: #"1|2|3"

4:27 raek: markoman: one way to do it could be to construct a regex from a sequence of integers as in the above example ^

4:28 markoman: i was trying to use regex and its working here well. thanks.

4:28 raek: markoman: but if you will parse the string later anyway, you might instead want to parse it first and then do the substitution

4:29 markoman: tomoj: i have a bad habit of simplifying problem here on channel, so actual case, these no need for int conversions, its all string

4:30 but good talk and im learning more than I asked again :)

4:31 btw, what is espace char in clojure regex?

4:34 tomoj: markoman: ah, I had wondered what the heck you were doing :)

4:40 raek: markoman: if you enter #"foo\bbar", the string containing f o o \ b b a r will be compiled with java.util.regex.Pattern. the regex pattern compilator also understands the usual \\ \t \n \u1234 escapes, so those are handled correctly too

4:42 so basically, you don't have to escape backslashes an extra time, as you need in elisp: #"\\" (matches one backslash character), and not #"\\\\", #"\b" (matches a word boundary), and not #"\\b"

4:42 markoman: so if i want to match [ which is a group indicator on regex, then i should use \\[ not \[ as i was trying

4:43 raek: you should use \[

4:43 you write exactly as it says in http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html

4:43 so there is no need to insert extra backslashes

4:43 markoman: i get Unsupported escape character: \[

4:44 raek: oh, is this in a regex literal or in a string literal?

4:44 ,#"\["

4:44 clojurebot: #"\["

4:44 raek: ,"\["

4:44 clojurebot: Unsupported escape character: \[

4:44 raek: clarification: what I said only applies to regex _literals_ in clojure

4:45 ,(re-pattern "\\[")

4:45 clojurebot: #"\["

4:45 markoman: i see, i see

4:46 ejackson: Friday !

5:37 matthias_: what's theb est thing to read to learn clojure?

5:42 ejackson: matthias_: what level are you at with programming in general ?

5:42 I'd probably suggest starting with "Programming Clojure" by Halloway, and follow that up with "The Joy of Clojure" by Fogus+Houser

5:43 fliebel: ejackson: Are you still being ignored by the air guys?

5:44 ejackson: oh I gave up on that

5:44 being ignored by more important people that I need to chase :)

5:45 matthias_: im a good programmer but new to clojure

5:45 my "mothertongue" is c++

5:45 ejackson: then you might be OK to start with JoC

5:46 functional programming is a bit odd at first

5:46 fliebel: ejackson: Hm, I could give it a try, but I doubt I sound any more authoritative than you do.

5:46 matthias_: ive been learning some haskell

5:46 ejackson: you'll be fine then

5:46 enjoy :)

5:46 matthias_: still a noob at it though, just wrote half a raytracer with terrible code

5:46 thanks, i shall google joc

5:49 ejackson: Its by manning

5:49 and is excellent

5:56 matthias_: ordered

5:58 ejackson: matthias_: well done.

6:01 matthias_: gonna take two weeks to arrive D:

6:01 (im in germany)

6:03 ejackson: it comes with a free ebook, did you not get details of that with the purchase ?

6:03 that would suck

6:30 clgv: ejackson: do you also get the ebook when ordering via amazon ?

6:31 ejackson: clgv: Most likely. I got the MEAP back in the day, so got ebooks that way, then when the deadtree came it had a flyer inside letting me know how to get a .pdf version.

6:31 clgv: ah ok :)

6:32 amazon still displays 3-6 weeks delivery time... :/

6:32 ejackson: eish

6:32 mine is at my elbow, and I'm in the UK

6:33 clgv: amazon UK displays some weeks as well...

6:34 ejackson: can you get it direct from Manning ?

6:38 clgv: ejackson: might be an option. or I get it from amazon market (less shipping fee)

6:40 ejackson: I want to let the company of my side shop order the book for me ;)

6:40 s/shop/job/

6:40 sexpbot: <clgv> ejackson: I want to let the company of my side job order the book for me ;)

6:40 ejackson: yeah, having companies willing to do that sort of thing is nice

6:40 provided its your company of course

6:41 or they let you keep the books they order for you

6:43 clgv: they can compensate some overtime for it ;)

7:14 markoman: s/what/is/this

7:14 ejackson: search and replace

7:14 so if I type s/this/that/ on the next line

7:14 s/this/that/

7:14 sexpbot: <ejackson> so if I type s/that/that/ on the next line

7:15 ejackson: sexpbot will helpfully replace this with that

7:15 markoman: heh, nice

7:15 s/nice/cool/

7:15 sexpbot: <markoman> heh, cool

7:16 markoman: what about the other special features ## , ?

7:18 ,(println "this I know")

7:18 clojurebot: this I know

7:19 markoman: is there some help available for channel bot features?

7:28 Borkdude: What is currently the common way to query a nested map structure?

7:29 Kototama: get-in

7:31 thorwil: is there a common name/idiom for functions that are like predicates, only that they pass there argument on, if it's "true" (so returning either the arg or false/nil)?

7:32 arbscht: thorwil: like or?

7:34 thorwil: arbscht: no, i mean the general case of something like http://paste.pocoo.org/show/372107/

7:34 tomoj: doesn't identity satisfy that?

7:35 oh, the truthiness check isn't of the argument

7:36 thorwil: i need functions like that for routing with moustache

7:37 Borkdude: thorwil: like this? (fn [arg pred] (if (pred arg) arg nil))

7:37 thorwil: if i use a predicate in the url-match, the handler only gets to see "true", instead of the value that i tested

7:38 Borkdude: yes

7:38 i was just thinking this must be common enough to have a label, but if there's none, i guess i will call these "guards"

7:42 anyone with experience with multiple file upload and appengine-magic around?

7:42 tomoj: (if x y false) seems at the same time strange and more clear

7:44 Borkdude: thorwil: https://gist.github.com/921568 ?

7:44 raek: thorwil: in the moustache library, they are called validators

7:47 thorwil: Borkdude: cool, thanks

7:47 ah, i should look into the libraries i use some more :)

9:11 zoldar: hello, I'm trying to use multimethod with dispatch on first argument's class: (defmulti physics-apply (fn [arg & _] (class arg))) - methods have varying number of arguments; I'm getting an error of too many arguments passed to "class" - what am I missing?

9:14 hoeck: zoldar: looks good so far, sure that your error is coming from the dispatch fn and not some other fn being called?

9:15 zoldar: hoeck, honestly I'm not sure, because stack trace is cryptic, but that's the only possibility in scope of currently compiled namespace

9:16 raek: zoldar: note that if you redefine the dispatch function, you need to "flush out" the old one first by doing (def physics-apply nil)

9:16 hoeck: zoldar: I remember multimethods being hard to reload properly, often I still was using an old dispatch function even after redefining

9:16 raek: defmulti will do nothing if the var already exists

9:16 * hoeck stops wondering

9:17 zoldar: raek, that was it, thank you

9:17 raek: it is similar to defonce

9:22 zoldar: are multimethods deprecated in any way?

9:23 raek: no

9:24 they have some overlap with protocols for the scenario when you only dispatch on the type of the first arg

9:24 zoldar: raek, protocols probably give better performance?

9:25 raek: zoldar: you can also solve the defmulti problem like this: (defn physics-apply-dispatch [arg & _] (class arg)) (defmulti physics-apply #'physics-apply-dispatch)

9:26 zoldar: yes they do. that's one the of the big motivations for them

9:26 zoldar: raek, looks the same to me - what's "#" here for? looks like CL :)

9:27 raek: instead of taking the current value of the physics-apply-dispatch var, that yields the var itself

9:27 zoldar: ah

9:28 raek: and vars can be used as functions too (the simply call the function they contain currently)

9:28 zoldar: thanks for tips

9:28 raek: np :)

10:21 zoldar: how should I refer to a record defined through defrecord from different namespace? now I'm getting something along "No such var: remote-ns/ExampleRecord"

10:22 should I compile that namespace explicitly at the beginning?

10:25 raek: zoldar: in addition to require the namespace, the client needs to import the record class too

10:25 this is one of the reasons you often see constructor functions

10:26 this is being thought upon: http://dev.clojure.org/display/design/defrecord+improvements

10:26 zoldar: ok, got it, I need to import it

10:28 I had common constructor, to which I would pass record class as the first argument - now I'm adding wrappers

11:35 matthias_: what the hell? fn is being converted into some weird f in my emacs... that just caused me some confusion. :|

11:36 jlf`: matthias_: sounds like you have http://www.emacswiki.org/emacs/PrettySymbol or something like it running

11:38 matthias_: i installed the starter kit. so it musth ave come with that.

11:38 not sure if i like it

11:39 fliebel: There was a trick to run -main of a ns without aot, right?

11:40 jlf`: matthias_: yep, i see pretty-lambdas mentioned in starter-kit-defuns.el

11:41 clgv: fliebel: just tape (-main) on repl ;)

11:41 s/tape/type/

11:41 sexpbot: <clgv> fliebel: just type (-main) on repl ;)

11:42 fliebel: clgv: nono, without the repl. just an option to lein I think.

11:43 clgv: ah kk. dont know that. lein only builds uberjars for me ;)

11:43 well gotta go now. cya

11:45 raek: fliebel: lein run

11:46 or in clojure 1.3: java .... clojure.main -m the.ns

11:50 fliebel: raek: Cool, thanks.

11:51 * fliebel wonders if java would accept ellipsis as the CP for convenience.

11:57 jashmenn: hey, how can i "apply" the dot (.) operator?

11:59 dnolen: jashmenn: wrap it in a fn, . is a special form.

12:00 ,(apply #(. % length) ["foo"])

12:00 clojurebot: 3

12:04 jashmenn: sure but what if you want to apply the "length" + args part?

12:05 ,(apply #(. "foo" %) 'length)

12:05 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol

12:05 jashmenn: doesn't work

12:06 raek: jashmenn: you have to use reflection in if you want to look up the method at runtime like that

12:06 jashmenn: ah ok

12:06 raek: methods are not first class values like functions

12:07 jashmenn: is it possible to use a macro to "trick" the dot operator without using reflection?

12:07 i tried (and failed) to do that

12:08 like

12:08 ,(defmacro dot-apply* [t m a] `(. ~t ~m ~@a))

12:08 clojurebot: DENIED

12:08 raek: yes, it is indeed possible to use a macro to generate (. "foo" length) given 'length

12:09 you should be able to use (dot-apply "foo" length) with that

12:09 oh, sorry. (dot-apply "foo" length [])

12:10 ...but you can't do this with a "length" only known at runtime

12:11 jashmenn: right

12:11 which is why i'll have to use reflection (?)

12:11 raek: think of macros as functions that take and return code

12:11 jashmenn: is the method name only known at runtime, or is it known when your program starts up?

12:12 jashmenn: the method name is known at startup, the number of arguments is variable

12:13 matthias_: hmm, shouldn't paredit highlight the parenthesis you're currentliy in? i mean if yo ugot (bla bla) and the point is in the middle, it should somehow hightlight all of (bla bla). with a different background or but just highlighting the parentheses

12:13 raek: ah, then the method is not known at startup, since methods with the same name but different arities are different methods

12:14 jashmenn: note that vararg parameters (those that look like foo(int x, int... y) in java) are only an invention of the java compiler. they are actually passed as an array as the last argument

12:14 matthias_: that sounds like http://www.emacswiki.org/emacs/HighlightParentheses

12:15 jashmenn: raek: right. i think im going to just go with varargs

12:15 thanks for your help raek

12:16 raek: ,(String/format "%d %d %d" (into-array [1 2 3]))

12:16 clojurebot: "1 2 3"

12:17 raek: ,(#(String/format %1 (into-array %&)) "%d %d %d" 1 2 3)

12:17 clojurebot: "1 2 3"

12:17 raek: jashmenn: you can "functionize" a vararg method like that ^

12:17 jashmenn: perfect

12:18 raek: have fun :-)

13:53 no_mind: is there a way to store the result of *print-dup* to a string ? I need to serialize a map and store it in db

13:54 stuartsierra: `with-out-str`

13:54 no_mind: k

13:55 amalloy: or just pr-str

13:55 &(binding [*print-dup* true] (rest (pr-str *ns)))

13:55 sexpbot: java.lang.Exception: Unable to resolve symbol: *ns in this context

13:55 amalloy: &(binding [*print-dup* true] (rest (pr-str *ns*)))

13:55 sexpbot: ⟹ (\= \( \f \i \n \d \- \n \s \space \s \a \n \d \b \o \x \1 \5 \7 \6 \4 \))

14:00 choffstein: hey all. I have an algorithm question. Basically, I have two lists that look like this: [5 1 3 9 0 6 2 5 1] [:h :h :h nil nil :h :l nil :l]. I would like to transform this into [nil nil nil :h nil nil nil :l], where for consecutive :h (or nils), the highest value is selected and the rest are set to nil, and for consecutive :l (or nils), the lowest value is selected. Any ideas? I'm stumped on how to do this one

14:00 without multiple passes. It seems like the best way is to break it down into blocks of consecutive signals, work on that list, and re-assemble. Any ideas?

14:01 amalloy: huh?

14:01 ataggart: ditto

14:01 amalloy: the problem specification could use some work

14:02 znutar_: yeah I thought as described you'd get [::h nil nil nil nil :l nil :l]

14:03 er, extra :h in there before the first :l

14:03 Raynes: wut

14:07 choffstein: Herm, badly specified...

14:09 Mainly because I am wrong in how I explained it. Okay, so, basically, we have three signals -- high, neutral, and low. For a sequence of highs and neutrals, uninterrupted by lows, we select the highest value previously marked as 'high' and set everything else to neutral. For a sequence of lows and neutrals, uninterrupted by highs, we select the lowest value previously marked by 'low' and set everything else to neu

14:10 So, given [:h nil :h :l nil] [5 4 6 2 4], we would get [nil nil :h :l nil] back.

14:11 it's ... sort of a strange problem

14:11 ataggart: nil is neither high nor neutral nor low, so why are they in the first vecotr?

14:12 choffstein: yeah, sorry. nil is the neutral value

14:12 my head is swimming.

14:12 i'm trying to break this down into smaller problems

14:13 ataggart: it might help to give an example that actually has uninterrupted anythign.

14:14 also if you're "select[ing] the highest value previously marked as 'high'" why does the resultant vector not contain the numerical values?

14:14 I'm assuming there's spome correlation between the first and second vector, but it's not apparent

14:18 choffstein: ataggart: yes, there is, but for all intents and purposes, they can be thought of separate time series. So the first is a time series of 1, 0, and -1. The latter is a time series of floats. When the first time series goes positive, it should start reading the second time series and record all values marked as 1. It should stop reading when the first signal goes negative. It should then find maximum of the values

14:18 recorded and mark it. A similar process should occur for when the first time series goes negative -- record all values in the second time series marked as negative and find the lowest when the first series goes back positive. If the first time series ends, it is considered to be the same as the time series changing signal.

14:19 I think I am just going to need to do a recursive function and keep track of some state...

14:20 amalloy: choffstein: if you don't know how to solve the problem, saying "i will just do x" means you will waste some time writing code that doesn't solve the problem. better to think about it for a while longer

14:21 znutar_: yeah you should just need to keep track of the length of the current :h/:l run, the position and level of the peak, and accumulate until you switch from high to low or vice verse

14:21 choffstein: amalloy: very true -- but i'd rather hack and re-factor to see if it spurs some creativity.

14:21 amalloy: go for it, then

14:22 choffstein: amalloy: don't worry, i'll come back crying in half an hour ;)

14:24 ataggart: choffstein from your description: (f [1 0 0 -1 0 0 1 0 0 ] [1 2 3 4 5 6 7 8 9]) => [3 4 9] but your examples don't return a vector of the numeric values. A better grasp of the question would probably lead you to a batter answer.

14:25 choffstein: ataggart: My description was wrong :)

14:25 ataggart: good luck

14:25 choffstein: Haha, thanks. I'll need it.

14:25 I'll come back with a clearer head and try again. might be time to step away from the computer

14:50 P_E: .

14:51 I need a macro that I basically use as (for), but it wraps it into (doall (for)) instead.

14:52 Could someone help with this?

14:53 The goal is to be able to update java arrays in for loops.

14:53 no_mind: I have to represent a DAWG in clojure. any idea which data structure will be most suitable for this ?

14:56 thorwil: i'd like to chain validators (functions that either return their single arg, or false). trying to make sense of the maybe monad, i arrived at: (defn dodo [a] (domonad maybe-m [x a, y (fn [x] (if (< x 10) x false))] (fn [y] (if (> y 5) y false)))) but how do i realize that?

14:57 fliebel: P_E: Have you seen doseq?

14:57 P_E: fliebel: no, haven't, I'll take a look

14:58 fliebel: awesome, thanks, that's just what I need

14:59 fliebel: no_mind: Maybe a nested map?

14:59 no_mind: Or you'd have to implement your own.

15:00 thorwil: Have you seen -?> It's somewhere in contrib, or on the webz.

15:02 thorwil: hmm, google seems to like to ignore things like "-?>"

15:02 P_E: thorwil: maybe you can search github fori t

15:02 fliebel: thorwil: It's like ->, but stops when something returns false.

15:03 manutter: would it be listed in the clojuredocs site?

15:03 replaca: http://clojure.github.com/clojure-contrib/core-api.html#clojure.contrib.core/-?&gt;

15:04 fliebel: thorwil: Oh, it returns nil, is that what you wanted, or do you want the last value?

15:04 thorwil: fliebel: i need the last value

15:06 fliebel: thorwil: Then modify the when-not to an if that returns ~'i# https://github.com/clojure/clojure-contrib/blob/b8d2743d3a89e13fc9deb2844ca2167b34aaa9b6/src/main/clojure/clojure/contrib/core.clj#L22

15:06 P_E: At the point of mvn installing clojure-contrib at http://riddell.us/ClojureOnUbuntu.html, I'm running into a problem: "Unable to find resource 'org.clojure:clojure:pom:1.2.0-master-SNAPSHOT' in repository clojure-snapshots (http://build.clojure.org/snapshots)"

15:07 stuartsierra: 1.2.0-master-SNAPSHOT is a very old version number.

15:07 and build.clojure.org is no longer the host for the latest snapshots.

15:07 thorwil: actually, the way i read it, -?> should be appropriate, but i have to try. still would like to make sense of the domonad business :)

15:07 no_mind: fliebel: the problem with nested map is that for a given node, I need to store a) the sub tree b) auxiliary information about the node for search terminating at the node. So how do I store two piece of information with one key in nested map ?

15:08 stuartsierra: P_E: Those instructions are way out of date.

15:09 P_E: stuartsierra: where would I be able to find a newer version?

15:09 fliebel: no_mind: metadata? I honestly don't know.

15:09 stuartsierra: P_E: Just download the latest release from clojure.org

15:09 If you want the source, use github.com/clojure, not github.com/richhickey

15:09 See also http://dev.clojure.org/display/doc/Getting+Started

15:11 P_E: stuartsierra: ok, but where do I find general getting started for setting up clojure? I'm using Vim, but it already assumes I have the install ready.

15:11 stuartsierra: just download it

15:11 It's Java: no installation necessary.

15:12 technomancy: that really ought to be called out explicitly on the getting started pages; something like "you don't need to install clojure"

15:13 ataggart: thorwill: I'm probably misreading your question, but why wouldn't 'and work?

15:13 P_E: stuartsierra: ok, I did do that initially, but I had problems with clojure-contrib.jar. I included it into the classpath in my clojure alias java -cp "clojure.jar:clojure-contrib.jar" clojure.main, but it has problems when I :require say clojure.contrib.string

15:14 stuartsierra: what problems?

15:14 markskilbeck: Has anybody read Paradigms of Artificial Intelligence Programming?

15:15 P_E: stuartsierra: could not locate string__init or string on classpath

15:15 file not found error

15:15 maacl: Can anyone explain why hiccup 0.3.4 blows up on compile when I try to use in a project with cake or lein? I get Unable to resolve symbol: resolve-uri in this context (core.clj:10)

15:16 stuartsierra: clojure.contrib.string does not exist after 1.2, maybe that's what you're running in to.

15:17 P_E: stuartsierra: could you tell me something that does then?

15:17 stuartsierra: I also tried xml and sql

15:18 stuartsierra: clojure.contrib.xml never did exist. I think clojure.contrib.sql still does, though it will also be moving to a separate repository soon.

15:18 P_E: stuartsierra: sql doesn't work

15:19 stuartsierra: same error there

15:19 stuartsierra: (require 'clojure.contrib.sql) ?

15:20 amalloy: no_mind: {:k [some-meta sub-tree]}?

15:20 P_E: stuartsierra: (ns solution (require 'clojure.contrib.sql)) ?

15:22 stuartsierra: I'm getting the same error without the namespace specifier

15:22 amalloy: P_E: that is not a well-formed ns form

15:22 fliebel: P_E: Oh, ns uses a different syntax. Make it a keyword and strip the quote.

15:22 P_E: yeah that's how I previously wrote it

15:22 still doesn't work

15:22 fliebel: (ns solution (:require clojure.contrib.sql))

15:22 stuartsierra: Check this: (System/getProperty "java.class.path")

15:23 * fliebel is to slow, and forgets the name of the classpath property.

15:25 P_E: stuartsierra: OK so I actually have it in the path now, but there's a different (bigger) error

15:25 stuartsierra: ok

15:25 P_E: stuartsierra: it's out of bounds in Vim so let me get that in a repl

15:26 stuartsierra: user=> (require 'clojure.contrib.sql) NoSuchMethodError clojure.lang.RestFn.<init>(I)V clojure.contrib.def/defmacro---509 (def.clj:39)

15:27 stuartsierra: That's a version mixup. You have an old version of clojure-contrib with a newer version of Clojure, or vice-versa.

15:28 P_E: stuartsierra: ok I'll try to git the very newest versions now properly

15:29 stuartsierra: Remember, you don't really need "clojure-contrib.jar"

15:29 Especially just getting started.

15:29 P_E: stuartsierra: I just want to have it in case I need something for Google Code Jam

15:29 stuartsierra: I'm gonna try to use clojure there

15:30 fliebel: P_E: Have you looked into use Lein instead? Might be easier.

15:30 choffstein: anyone know any good tutorials on how to use defmulti and defmethod? I can't seem to dig up any really clear examples on google.

15:31 stuartsierra: P_E: If the Google Code Jam problems are algorithmic, it's highly unlikely you will need anything in clojure-contrib.

15:31 P_E: stuartsierra: combinatorics might be useful

15:31 ataggart: choffstein: look at how it's used here https://github.com/clojure/clojure/blob/master/src/clj/clojure/java/io.clj

15:31 choffstein: ataggart: Thanks :)

15:31 P_E: stuartsierra: and complex numbers as well

15:32 stuartsierra: Both are unmaintained.

15:32 P_E: fliebel: no I didn't even know what Lein was

15:33 amalloy: clojurebot: lein?

15:33 clojurebot: lein is http://github.com/technomancy/leiningen

15:33 P_E: fliebel: I don't yet need to build projects

15:33 amalloy: P_E: doesn't matter, you want lein or cake anyway

15:34 fliebel: P_E: Lein also works as just a repl.

15:34 kingpotato: Lein is a lot more than just a build tool... it has a lot of other stuff that will help you get going

15:36 amalloy: i wonder if technomancy should change the summary of lein so that new people will stop saying "but i don't need a build tool"

15:36 choffstein: lein is ammmaaaazzziinnnnggg

15:37 can I invoke a multimethod based on the number of elements in a list?

15:37 amalloy: indeed! (defmulti foo count)

15:37 P_E: what is the difference between leiningen and cake?

15:37 and do they actually help me install clojure?

15:38 amalloy: P_E: they're basically the same from an end-user (ie you and me) perspective

15:38 stuartsierra: Different people wrote them. Neither is official.

15:38 amalloy: and yes

15:38 P_E: and which one would you suggest for the long haul?

15:38 choffstein: ahhh, count. duhhh

15:38 stuartsierra: Clojure's only 3 years old, there is no long haul yet.

15:38 P_E: fair enough

15:39 matthias_: does cake also give you a repl?

15:39 P_E: yes

15:39 amalloy: matthias_: yes

15:39 choffstein: i could swear i've actually done this before, but i guess i threw it out and replaced it with something else

15:39 matthias_: which is better? :p

15:39 dnolen: P_E: Clojure itself probably won't ship with any sort of build/packaging solution anytime soon. lein and cake both are useful and supported by the community.

15:39 amalloy: matthias_: the one you're usef to using

15:39 Raynes: Cake gives you an REPL with completion and a global project so you can have dependencies in it like with cljr.

15:40 matthias_: usef?

15:40 amalloy: used

15:40 dnolen: P_E: the main advantage of cake is instant-on REPL

15:40 amalloy: jeez, picky in here today

15:40 Raynes: Also, I'm covering cake in my book. That makes it awesome. ;>

15:40 choffstein: amalloy: count works perfectly. I am just really used to pattern matching in Haskell / ML -- so using 'dispatch' methods for 'matching' is messing with my head a bit.

15:40 matthias_: which book?

15:40 Raynes: matthias_: http://meetclj.raynes.me/

15:41 amalloy: choffstein: funny. i'm trying (again) to teach myself haskell

15:41 kingpotato: the only problem with lein is the awful teutonic name

15:41 choffstein: amalloy: Yeah ... Haskell and I have a love hate relationship. It loves itself, and I hate it.

15:41 amalloy: oh burn

15:41 matthias_: i like the name. but im german

15:41 redinger: kingpotato: Makes it easy to google info on it though

15:42 kingpotato: no offense intended but German is just to harsh a language for naming things

15:42 choffstein: So this might be stupid, but can I do a match on keywords with defmulti? Like, if one of the args I pass in is a keyword, I handle my methods on that keyword...

15:43 Raynes: redinger: Is it pronounced "red-ing-er" or "red-in-jer"?

15:43 fliebel: $mail ejackson I just found out some airlines offer group discounts, this might be an easier and financially viable alternative.

15:43 sexpbot: Message saved.

15:43 raek: choffstein: yes, just make the dispatch fn return that keyword

15:43 redinger: red-in-jer

15:43 yes, it's German :)

15:43 Raynes: Alan Dipert pronounced it when we were talking on the phone last week, but I can't for the life of me remember.

15:43 Awesome, thanks.

15:43 choffstein: raek: Herm, I tried that. I think I must be doing it wrong :D

15:43 matthias_: you can install cake with gem? isnt that the ruby package manager? Oo

15:43 amalloy: (defmulti kwmulti (fn [_ kw _] kw))

15:44 raek: the dispatch fn needs to take the same number of args (at least) as the implementation

15:44 amalloy: (defmethod kwmulti :foo [size this-is-foo data] (...))

15:44 P_E: do I need a cakefile for doing "cake repl"

15:44 amalloy: matthias_: cake is clojure with a thin layer of ruby

15:44 Raynes: P_E: Read about the global project in the cake README.

15:45 Even outside of a project, you're always in a project.

15:45 Hence the ability to add dependencies to the 'outside-of-a-project' REPL.

15:45 Kind of like cljr.

15:45 amalloy: cakefiles don't really exist. they're part of coffeescript's cake, not clojure's, iirc

15:45 P_E: crap

15:45 when I write cake, it sort of tries to use the coffeescript cake

15:45 stuartsierra: Oh yeah, Clojure's got its "getting started" story ALL figured out.

15:45 matthias_: heh

15:46 fliebel: Raynes: How are the Swing wrapper plans? I have an idea for a GUI app, but I don't want to die-ie-ie!

15:46 matthias_: someone needs to make clojure platform

15:46 Raynes: P_E: I support a name change, but ninjudd isn't into it. :\

15:46 raek: choffstein: note that in order to redefine a defmulti, you need to either remove the var or give it a non-multimethod value first: (def the-multimethod nil)

15:46 Raynes: fliebel: Non-existent would classify them well.

15:46 raek: (since it behaves as defonce)

15:46 P_E: ok so I'm actually switching to lein because of this

15:46 choffstein: raek: Yep, that is exactly what is going wrong

15:47 raek: choffstein: this works more nicely when doing interactive development: (defn foo-dispatch [...] ...) (defmulti foo #'foo-dispatch)

15:47 also, why isn't this in the docs? >:(

15:47 choffstein: raek: Ah, awesome. Thanks :)

15:48 fliebel: Raynes: non-existent (yet/anymore)?

15:48 Raynes: Yet. Too much busy.

15:48 amalloy: fliebel: i tried to warn him about announcing the project before he had any ideas or time :)

15:49 redinger: stuartsierra: There are lots of "getting started" stories. Should we just have one official one that we point people to?

15:50 stuartsierra: redinger: There should be no story except "Download, Unzip, Run."

15:50 redinger: That's what's on the getting started page

15:50 fliebel: amalloy: Well, the idea was certainly there, and "no time" is crap, that just means "no priority".

15:51 stuartsierra: redinger: yeah, but it doesn't handle anything beyond the first steps into the REPL.

15:51 If people can't manage a classpath (anyone who hasn't worked extensively with Java) you're kind of stuck at that point.

15:57 Somelauw: Is clojure most suitable for web applications, desktop applications or what is it most suitable for actually?

15:57 stuartsierra: Everything!

15:57 Raynes: Everything and more.

15:57 choffstein: Is there a function to find the index of an element in a list?

15:57 And why do I have so much trouble googling for this info?

15:57 Raynes: I once built a spaceship in Clojure and visited Mars.

15:58 Somelauw: So, what big projects have been created in clojure so far?

15:58 stuartsierra: ummmmmm

15:58 Raynes: I imagine nobody has asked that question before in such a way that it was easily googleable.

15:58 Somelauw: Except your paper spaceshit :P

15:58 spaceship

15:59 redinger: No luck finding the trip to mars on Google

15:59 stuartsierra: AltLaw, Sonian's stuff, various client projects at Relevance.

15:59 Somelauw: Was what I wanted to say.

15:59 s*** was a typo

15:59 redinger: http://flightcaster.com/

16:00 stuartsierra: oh yeah, that too

16:01 redinger: Do we know yet which part of Akamai is using Clojure?

16:01 stuartsierra: The good part.

16:01 choffstein: But...seriously, is there a function that tells me the indices that an element occurs in a list?

16:01 Somelauw: I was thinking of learning how to write web applications or something, but that would probably require me to learn how web applicatrions work in java first.

16:01 stuartsierra: choffstein: map-indexed in some combination

16:03 Somelauw: It's not that bad. Jetty + Ring gets you 85% of the way there.

16:04 redinger: I found this helpful: http://mmcgrana.github.com/2010/07/develop-deploy-clojure-web-applications.html

16:04 choffstein: stuartsierra: yep ... that worked. can't believe I had to write that code though

16:04 Somelauw: What in that other 15% case?

16:04 stuartsierra: Learn Java.

16:04 tufflax: choffstein http://stackoverflow.com/questions/4830900/how-do-i-find-the-index-of-an-item-in-a-vector and http://www.mail-archive.com/clojure@googlegroups.com/msg34159.html

16:04 amalloy: choffstein: .indexOf

16:04 choffstein: Ah, cause Java has it

16:04 Freakin' Java.

16:04 Somelauw: I already learned java syntactically.

16:05 stuartsierra: Then pick your deployment poison: Jetty, JBoss, Glassfish, etc. etc.

16:05 amalloy: but srsly you should think about not doing that. there are certainly times when managing indices is the right thing to do, but usually they complicate things for no particular purpose

16:07 stuartsierra: Clojure's very Zen about things. "How do I do X?" "The only way to do X is to not try."

16:07 Somelauw: So how to do X?

16:08 By doing y instead?

16:08 Raynes: Yes.

16:09 choffstein: amalloy: in time series work, sometimes I need to pull the index of something

16:12 ataggart: choffstein: you only think you do.

16:13 heh

16:13 choffstein: ...

16:13 O_o

16:13 I think I just reached enlightenment

16:14 And/or my brain exploded

16:14 markskilbeck: I thought that once.

16:14 Was just heartburn.

16:14 ataggart: which only proves you didn't

16:15 markskilbeck: Whoa.

16:15 I know kung fu.

16:22 TimMc: stuartsierra: http://www.kendall-online.com/blog/uploaded_images/software-project.jpg <-- "How do I attach this rope around the trunk of the tree?"

16:23 I feel like a very good programming idiom parody could be made of that image.

16:35 Somelauw: Why would a customer want a wheel hanging by a rope on a tree?

16:35 lol

16:38 amalloy: Somelauw: is this clever satire, or genuine confusion?

16:43 matthias_: i need to modify penumbra. is that easy to do? i mean i have it auto installed via leiningen, i dont even know where it puts stuff

16:44 hmm, i have a jar file. maybe i dont even have the code

16:44 technomancy: matthias_: you probably want checkout dependencies; see the lein faq in the readme

16:45 TimMc: Somelauw: You're either joking or have never seen a tire swing.

16:48 amalloy: TimMc: if it's satire it's pretty good though

16:48 TimMc: yeah

16:48 matthias_: thanks, technomancy

16:52 fliebel: TimMc: I must admit that I do not really get the wheel thing either. Except… It's probably the only image that works, besides the roller coaster.

16:57 amalloy: $google tire swing

16:57 sexpbot: First out of 250 results is: Tire swings

16:57 http://www.pppresentations.com/

16:58 amalloy: maybe it's an american thing, but they're iconic. an easy way to make your own swing with no real engineering skills or raw materials that are hard to find

16:59 fliebel: amalloy: No, we have them as well. It was the "Easy to make" part I was overlooking.

17:00 amalloy: i'm not sure that part is really relevant to the comic, but maybe it is

17:01 fliebel: amalloy: If it's not, what is?

17:02 amalloy: that what the customer asked for isn't really what they wanted

17:03 fliebel: well, true, but how is the tire relevant in *any* way then? Oh, wait, maybe it isn't, and that is how I got confused :P

17:03 * fliebel goes to bed

17:04 * amalloy specializes in explaining jokes until they're not funny

17:04 matthias_: so leiningen stores the same files multiple times on your computer hwen you use them in more than one project?

17:04 fliebel: matthias_: Yes, or maybe it syslinks them, don;t know.

17:04 TimMc: amalloy: that first google result is what happens when the client gives up and has their nephew make the website

17:04 amalloy: yeah, that was a horrible page

17:05 it stores them several times, for now

17:05 fliebel: You know, as a child, it is really hard to make swings.

17:05 Somelauw: I don't remember having ever sit on a tire swing as a kid.

17:06 fliebel: Somelauw: There is still time, do it now!

17:07 TimMc: Never too late.

17:08 Somelauw: But I might have.

17:08 Then I will need to find a playjard somewhere that has it first.

17:09 fliebel: Somelauw: Or make one yourself, double fun :)

17:10 TimMc: My dad made me a swing when I was a child. It was a wooden slab with a rope running up from a hole in the center to a tree branch far above.

17:10 So much fun.

17:10 fliebel: We all love Swing ;)

17:11 Somelauw: But I do remember th hours I spend on a regular swing.

17:11 spent

17:15 matthias_: any hints about how i tell leiningen that i want it to use a local version of a library? i successfully made my change and compiled a new .jar i believe

17:18 technomancy: matthias_: using checkout deps should get that for you

17:19 otherwise fiddle with the version and do lein install, then lein deps on your other project

17:19 ataggart: it'd be nice if there was just a way to specify an additional local lib dir.

17:22 P_E: what is the most common function for splitting a string nowadays?

17:22 amalloy: re-seq? it kinda depends how you want to split it

17:23 technomancy: ataggart: you can specify :repositories with file:/// notatino

17:24 but nearly every time it's more fruitful to ask yourself why you think you want it

17:24 P_E: rmarianski: cool that's what I needed, thanks

17:29 matthias_: i dont quite get that checkouts stuff. i got a folder named checkouts in my project root directory and in it i have a symlink called penumbra to the root folder of where my changed version of penumbra is

17:29 do i need more than that to let lein find it?

17:30 does the symlink have to have a specific name?

17:30 technomancy: no, that should be all you need

17:30 as long as penumbra is in project.clj as a :depedency too

17:30 matthias_: yes. i even changed the version number of my version of penumbra and changed it in the dependencies of my actual project

17:31 before that, it just kept using the old version

17:36 dnolen: huh, since Clojure enforces an order of definition seems like that would make an optional type system much simpler ... no need for multiple passes ...

17:38 sometimes rhickey's decisions really only make sense 3 years later.

17:38 hiredman: well, it makes the compiler much simpler in general

17:47 matthias_: technomancy, i've been looking around in the leininge code on github a bit and it actually seems like checkout_deps.clj doesnt even exist in the main branch

17:52 technomancy: matthias_: that's correct; it is not a namespace or file.

17:52 it's just a feature

17:53 matthias_: i just tried simply overwriting the old .jar with my new one in my libs folder. it still know that that one function i added doesnt exist. hmm

17:57 technomancy: you need to restart you clojure process; that stuff is cached

17:59 matthias_: now it worked. i had forgotten something.

17:59 of course this is a rather ugly way of doing this

18:34 TimMc: Something is not quite right with my ray-tracer... http://i.imgur.com/VPay2.png

18:37 choffstein: Anyone use Sphinx with clojure?

18:39 technomancy: choffstein: not much call for Sphinx when Lucene is readily available as I Understand

18:39 choffstein: ...yeah, that makes sense

18:39 I'm full of stupid questions today

18:39 I think it's time to just "call it Friday" and move on

18:39 carllerche: has anybody tried using ClojureCheck (quickcheck for clojure)?

18:47 TimMc: OK, in my ray tracer, I can compute a seq of intersections of objects with a given ray. Each has a :dist -- I want the closest intersection.

18:47 Naïvely, I used reduce to find the min.

18:48 The complication is that I need to throw away the closest (and use the second closest instead) if it meets a certain predicate.

18:49 Options: A) sort the seq by distances and take either the first or second.

18:49 choffstein: you could use sort-by :dist

18:49 TimMc: B) reduce to find min and next-min and choose between them.

18:49 sort-by does more work than necessary, but finding the min-2 is a more challenging algorithm, I think.

18:49 amalloy: TimMc: C) generalize to n-smallest?

18:50 technomancy: does anyone use the user/*classpath* var that leiningen creates?

18:50 amalloy: TimMc: On Lisp has an implementation of n-smallest

18:50 TimMc: hmm

18:50 Do you know of such an implementation in Clojure?

18:50 technomancy: I was going to wait till 2.0 to remove it, but it's kind of dumb, and if nobody uses it I will just cheat and do it in a minor-point

18:51 * TimMc furiously attempts to use user/*classpath* everywhere in his code

18:51 choffstein: TimMc: sort-by would be computational over-kill compared to a linear search for just the min...

18:51 technomancy: TimMc: ಠ_ಠ

18:51 TimMc: choffstein: Right.

18:51 choffstein: TimMc: But starts to make sense when you need to find the n-smallest

18:52 amalloy: TimMc: page 183 of On Lisp. translation to clojure would be pretty trivial

18:52 maybe

18:53 choffstein: amalloy: nthmost function? because looking at it is blowing my mind.

18:54 amalloy: choffstein: the punctuation in CL, and especially the font he uses, makes it look worse than it is

18:54 TimMc: I think I'll look elsewhere for an algorithm. o.o

18:55 choffstein: TimMc: Don't think you're going to get much faster than O(2N) for first and second min unless the points are pre-sorted

18:55 TimMc: linear is fine

18:55 Hell, sort-by is probably fine for my purposes.

18:56 That's what I'll use for the first commit anyway, just to make writing unit tests easier.

18:56 * amalloy writes it as an exercise

18:58 choffstein: TimMc: Can you just keep track of the min 2 as you trace the rays? It is a bit rigid, but sometimes it is better to choose rigidity if the problem is defined over an over-generalized function that you never reuse in a general form.

18:58 ...that was a horribly written sentence

18:58 what is going on with me today

18:58 i feel like a big barrel of stupid. It took me 2 hours to write 14 lines of clojure code...

19:01 amalloy: choffstein: put in some more newlines

19:01 choffstein: it's already 8 lines of comments :D

19:02 amalloy: TimMc: okay, i take it back, that nthmost macro is complicated

19:03 TimMc: It's a *macro*. Why?

19:03 amalloy: TimMc: pushing bounds checking and iteration to compile time

19:03 choffstein: Seems like C++ template wizardry to me

19:04 TakeV: Is there some sort of system to be able to add new code to a file through the repl, without having to copy and paste it into the file?

19:05 hiredman: "emacs"

19:05 amalloy: TakeV: go the other direction. put code in the file, and let swank/slime send that to the repl

19:05 TakeV: I don't use swank/slime. :\

19:05 Vim/Lein for me.

19:06 amalloy: so, vim has something similar to slime

19:06 hiredman: lein is orthogonal

19:09 talios: vimclojure is good

19:09 TimMc: By the way, here's what happens if I *don't* drop the first intersection under certain conditions: http://i.imgur.com/VPay2.png

19:09 talios: uses screen

20:07 lancepantz: TakeV: still around?

20:08 TakeV: I used to use this setup when using vim, i think it's what you're looking for. http://writequit.org/blog/?p=386

20:09 but switching to emacs was the best decision i ever made :0

20:11 technomancy: the author of that post switched too =)

20:13 TimMc: Ahh, much better: http://i.imgur.com/ZgmIq.png <-- Still too bright, but now reflected rays do not accidentally register a hit on their point of origin half the time.

20:15 carllerche: What would be some good idiomatic OSS clojure projects that could be interesting to read over to learn how to structure a clojure app w/ a somewhat complex data model? (yeah, i know it's a vague question :P)

20:17 lancepantz: technomancy: hah! that's classic

20:17 technomancy: ring is probably too simple. incanter maybe?

20:22 carllerche: i'll take a look... I'm trying to figure out how to organize stuff

20:25 rak85: how do i transform a keyword into a string?

20:25 technomancy: ,(name :my-keyword)

20:25 clojurebot: "my-keyword"

20:26 rak85: thanks!

20:26 technomancy: np

20:27 TimMc: rak85: /msg sexpbot $findfn :foo "foo"

20:27 :-)

20:29 * TimMc writes a findfn macro that goes into IRC at compile time to ask sexpbot for a matching function

20:29 TimMc: e.g. ((findfn :foo "foo") :blarg)

20:30 rak85: ((findfn :foo "foo") :blarg)

20:30 hahah

20:31 TimMc: It would take the first in the list, appropriate or not. :-)

20:42 amalloy: TimMc: feel free to fork sexpbot. you could get him to expose findfn to clojure evaluation requests

21:38 TimMc: OK, ray tracer is definitely doing mirror reflection properly now: http://i.imgur.com/ktXQ7.png :-D

22:05 carllerche: Is there a function to go from [[1 2] [3 4] [5 6]] -> [[1 3 5] [2 4 6]] ?

22:06 amalloy: &(apply map vector [[1 2] [3 4] [5 6]] )

22:06 sexpbot: ⟹ ([1 3 5] [2 4 6])

22:07 carllerche: &(+ 1 1)

22:07 sexpbot: ⟹ 2

22:07 carllerche: cool! (thx btw) :P

22:07 amalloy: carllerche: it's good practice to understand why that transposition works, btw

22:08 carllerche: yeah... not sure what vector does. gonna look it up

22:08 amalloy: &(vector 1 2 3)

22:08 sexpbot: ⟹ [1 2 3]

22:09 amalloy: apply turns it into (map vector [1 2] [3 4] [5 6]), which is the same as [(vector 1 3 5) (vector 2 4 6)]

22:09 carllerche: huh, that's cool

22:10 amalloy: yeah, map is a really powerful combination of several ideas that are separate in some other functional languages

22:15 carllerche: amalloy: makes sense... i still have a ways to go before i can wield all of these functions

22:17 TimMc: carllerche: Look up juxt.

22:18 amalloy: &((juxt inc dec) 1)

22:18 sexpbot: ⟹ [2 0]

22:19 TimMc: At first, you won't have any clue why you'd want to use it... but you'll eventually find uses. :-)

22:21 amalloy: well, i think my first "high-power" use of juxt was like ##((juxt quot rem) 52 10)

22:21 sexpbot: ⟹ [5 2]

22:22 TimMc: Did we decide if there was a good reason that there isn't a native divmod function?

22:23 I mean, ISAs generally have something like that.

22:23 amalloy: TimMc: probably because it would be inconvenient to use in java?

22:23 int[]s are not very handy to work with

22:23 TimMc: point

22:24 amalloy: allocating the eight bytes probably costs more than just doing the division twice anyway

22:33 dnolen: ,unchecked-remainder

22:33 clojurebot: #<core$unchecked_remainder clojure.core$unchecked_remainder@51e62>

22:35 dnolen: Logos now has support for declaring facts, and indexing those facts, https://gist.github.com/922790, predicate dispatch here we come!

22:36 amalloy: &(doc unchecked-remainder)

22:36 sexpbot: ⟹ "([x y]); Returns the remainder of division of x by y, both int or long. Note - uses a primitive operator subject to truncation."

22:36 amalloy: &(unchecked-remainder 52 1-)

22:36 sexpbot: java.lang.NumberFormatException: Invalid number: 1-

22:36 amalloy: &(unchecked-remainder 52 10)

22:36 sexpbot: ⟹ 2

22:37 dnolen: on a side not, ints[]s are fine to work if you take the time to write some macros.

22:37 s/not/note

22:37 sexpbot: <dnolen> on a side note, ints[]s are fine to work if you take the time to write some macros.

22:37 dnolen: night folks

22:37 amalloy: dnolen: well of course. but not in java

22:42 TimMc: It's all well and good in assembly languages, where the results of divmod go into two predefined registers (generally.)

22:43 amalloy: TimMc: it's fine for the jvm too. put them both on the stack and pop them to wherever you want

22:43 but java doesn't have syntax that would make it easy to say where to put them

22:46 eg: a, b = 52 %/ 10;

23:28 chewbran1a: technomancy: ping

23:36 technomancy: chewbran1a: sup

23:37 chewbran1a: technomancy: hey man, having a hell of a time getting a dependency loaded in leiningen, was wondering if you had a minute to check it out

23:38 technomancy: sure; paste project.clj?

23:38 chewbran1a: I'm tryin to install: http://clojars.org/org.clojars.pieterbreed/clojure-couchdb

23:38 sure just a second

23:40 technomancy: http://paste.lisp.org/display/121541

23:40 so anytime I try and required the couchdb jar, I get a file not found error, I've tried requiring 'clojure-couchdb, 'org.clojars.pieterbreed/clojure-couchdb, 'org.clojars.pieterbreed.clojure-couchdb

23:41 amalloy: chewbran1a: but lein deps works?

23:41 assuming that much, your problem isn't related to lein at all

23:41 chewbran1a: amalloy: yeah works fine, I've got clojure-couchdb-0.4.7.jar in lib/

23:42 technomancy: chewbran1a: if you open up the jar, you can see that the only clojure file it contains is couchdb/client.clj

23:42 so that's your ticket

23:42 amalloy: chewbran1a: so just (require) the usual couchdb stuff. putting the clojars crap in front of it is a misunderstanding of how namespaces and jars interact

23:42 technomancy: sounds like a case of lousy docs though =\

23:44 chewbran1a: technomancy: ahhh ok

23:44 amalloy: yeah I was tried 'clojure-couchdb first, then went on to trying other varients

23:48 tomoj: someone with reach should blog "remember to put your namespaces in the readme"

23:53 chewbran1a: ok great, got it working, I forgot you could just open up jars directly, good to kno

23:53 *know

23:55 technomancy: yeah, emacs lets you just open up jars like directories; you can probably do that in vim too

23:55 very useful

23:56 chewbran1a: yeah just opened it in vim and it was a typical directory listing, definitely useful

23:57 justinlilly: also, zgrep

23:59 chewbran1a: justinlilly: does zgrep work on jars?

23:59 justinlilly: seems like it ought to..

Logging service provided by n01se.net