#clojure log - Apr 30 2009

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

0:01 hiredman: http://gist.github.com/104249

0:04 durka42: that's neat

0:41 z5h: Are there a set of regression tests run against clojure releases? Are they available somewhere?

0:47 ahhh. part of clojure-contrib http://code.google.com/p/clojure-contrib/source/browse/#svn/trunk/src/clojure/contrib/test_clojure

2:27 Lau_of_DK: Top of the morning gents

5:37 neotyk: Hi All

5:38 After downloading clojure I have problems building clojure-contrib (fresh from svn), error in types.clj:14

5:40 only when built clojure from svn can build clojure-contrib

5:52 leafw: neotyk: that is not surprising

5:52 clojure-contrib svn repos chases clojure repos.

5:53 neotyk: leafw: wouldn't it be a good idea to have distribution jars as clojure has?

5:54 leafw: neotyk: I am not sure how many people uses clojure-contrib that doesn't write parts of it too. Documentation is the code itself at the moment, as far as I've seen.

5:56 neotyk: leafw: for new comers like me, I wan't to get clojure env in vim and it needs clojure-contrib

5:57 so to use vimclojure i need to build from svn

5:57 fine by me, but not very user friendly

5:58 leafw: neotyk: explain it to the mailing list, a solution may come up.

5:59 neotyk: leafw: I'll post to list

6:23 Raynes: neotyk: Do you have the newest rev of Clojure? If not, try building Clojure from source (comes with an ant build script, no catches ;).) and then using it to build clojure.contrib.

6:25 neotyk: Raynes: clojure-contrib builds fine if clojure is built from svn, just mailed it to mailinglist

8:11 cemerick: the interaction of namespaced keywords and requiring namespaces w/ an :as alias is really painful. Assuming you've required com.foo.mynamespace :as myns, (= :myns/foo :com.foo.mynamespace/foo) => false

8:11 am I missing something really simple here?

8:14 rhickey: ::myns/foo

8:21 * cemerick sighs

8:22 cemerick: I guess I was pretty tired, or something. Yeah, that's my excuse. :-(

8:23 AWizzArd: rhickey: did you see my messages (about 14 hours ago)?

8:23 rhickey: AWizzArd: no

8:23 Raynes: cemerick got owned by The Creator.

8:23 AWizzArd: Can you scroll up in the history of this channel?

8:23 Raynes: :p

8:25 rhickey: AWizzArd: find the time anchor in http://clojure-log.n01se.net/date/2009-04-29.html

8:26 AWizzArd: It started http://clojure-log.n01se.net/date/2009-04-29.html#17:45

8:28 * rhickey pausing Torvalds on git video to look at AWizzArd propose hg

8:28 jdz: i have not used hg, but imho git is awesome

8:29 rhickey: AWizzArd: what's the question?

8:29 cemerick: oh good, an SCM LOC pissing match. Haven't seen one of those in a while. :-P

8:31 AWizzArd: I just was not sure if you maybe missed that your main points can easily be achieved with hg and git. In the last talk there were several git fans who had time to answer, while some experienced hg users could not say overly much.

8:32 That could have left the impression that work with branches in hg is somehow difficult.

8:35 rhickey: It's not just about the SCM, it's SCM, plus pubic Clojure hosting, plus commercial hosting (I'm not learning/using 2 things), plus IDE/tools support

8:35 these decisions are never purely technical

8:36 AWizzArd: yes

8:37 If the choice is (one-of :git :hg), then I am already sure, it is a good descision.

8:37 Would just be nice if you got a fair impression of both candidates.

8:38 rhickey: Torvalds says they're essentially the same, modulo some implementation details

8:38 cemerick: does anyone know of either some materials (blog posts/wikis/etc) that dig deep into how to leverage clojure's multimethods maximally, or alternatively, a codebase that does so? We now officially have a hash of various usage patterns, and I'd like to go beyond my intuition about idiomatic design, etc.

8:40 AWizzArd: rhickey: I also had mostly that impression. I was/am using both systems.

8:41 cemerick: I suppose I could dig into CL materials, but there's obviously a lot more capability in clojure, and I'd rather avoid the impedance mismatch.

8:42 rhickey: cemerick: have you seen enclojure's support for looking at multimethods?

8:42 AWizzArd: cemerick: could you tell a bit more what the obviously extras in capability are?

8:43 neotyk: as recently jvanzyl (maven guy) is totally after git I'd expect very good support for it in Java world

8:43 AWizzArd: neotyk: Sun uses hg for the OpenJDK and for OpenSolaris...

8:43 cemerick: rhickey: You mean some widgets for doing some introspection on them?

8:43 rhickey: cemerick: yeah, really neat

8:43 AWizzArd: I think for people working in the Java domain hg seems to be a good fit.

8:43 cemerick: we actually haven't upgraded our enclojure in quite a while -- we're using remote REPLs extensively, and everything's working, and I don't want to upgrade until we have some breathing room to allow for breakage.

8:44 neotyk: AWizzArd: I know, and kenai is HQ as well

8:44 cemerick: AWizzArd: arbitrary dispatch fns (or dispatch multimethods themselves) brings a whole 'nuther level to it all.

8:44 neotyk: but Sun is not providing much of the tooling for it, does it?

8:45 AWizzArd: cemerick: some lines of CL code can extend CLs multimethods to do the same.

8:46 I think it is a good design descision that rhickey took with Clojure. In CL it is possible, but noone is doing it.

8:46 cemerick: AWizzArd: Good to know. I'd certainly prefer avoiding picking up any bad (non-clojure-idiomatic) habits from other multimethod systems, though.

8:46 AWizzArd: yes

8:47 cemerick: it's bad enough that I've been thumbing through a pile of scheme code here and there. I actually wrote (define (...)) the other day in enclojure, and couldn't understand why I was getting evaluation errors for 30 seconds.

8:47 AWizzArd: *g*

8:54 Google did some measurements of how fast cloning a hg repository is vs cloning a git repo over http. For hg they had about 8 seconds, for git it were around 178 seconds.

9:19 cemerick: hrm, what's the magic java.util.Formatter incantation to get a list's elements to be printed out?

9:19 nm, it was just a lazy seq...

11:38 ~max

11:38 clojurebot: max people is 164

11:38 cemerick: I wonder what prompted that spike, and then falloff

11:38 AWizzArd: yes, strange

11:38 Also watch the number of members in the google group

11:38 and the number of postings made

11:39 cemerick: That's like a 30% short-term spike. That must have corresponded with rhickey presenting somewhere. Maybe qcon?

11:45 Raynes: I might just scream the next time I hear "Git is awesome!!1!1!!"

11:45 bitbckt: "Git is awesome!!1!1!!"

11:47 Raynes: I openly recognize that Git must be great, but the fanboyism that goes on about it is painful.

11:48 bitbckt: The people on either side of a Holy War are equally to blame.

11:48 tashafa: clojure is on the front page of HackerNews

11:48 if heads didnt alreadyknow

11:49 cemerick: is there any way to define an exception type that is specifically catchable in clojure code? I've tried proxying Exception and then doing (catch (class proxied-exception) ...), but try/catch is a macro, so it's looking for a classname there...

11:51 danlarkin: cemerick: you need to gen-class the Exception derivative

11:51 cemerick: ok, that's what I figured.

11:51 whoa, it's my first .java file in at least a month! :-)

11:52 danlarkin: it's annoying, but c'est la vie for now. You can always use Chouser's error-kit though!

11:52 dnolen: cemerick: try/catch isn't a macro, it's special form right? in general, that's the trouble with special forms.

11:52 cemerick: eh, too simple a case for that...but yes, I do plan on digging into it eventually

11:52 dnolen: yes, yes, you're right

11:53 dnolen: ;)

11:54 rhickey: cemerick: being a special form is irrelevant - the jvm bytecode itself catches exceptions by classname

11:56 cemerick: rhickey: sure -- what I was thinking was that I could proxy an exception type, get a sample proxied exception, get its class, and then use that class/name to catch with.

11:56 Chouser: or

11:56 cemerick: It's been a while since I've used proxy, and now it seems that (class proxied-exception) always returns something like clojure.proxy.java.lang.Exception, rather than a separate class identifying the proxy that was created.

11:56 clojurebot: proxy is <Chouser> proxy teases with its ease of use, then suddenly betrays.

11:57 Chouser: or use error-kit

11:57 cemerick: that's all sort of moot though, since try/catch requires a classname symbol

11:57 :-)

11:57 Chouser: danlarkin beat you to it!

11:58 Chouser: oh, sorry.

11:58 cemerick: Chouser: I definitely plan on digging into what you've done with error-kit, but it was way too easy to just create a 4-line .java file.

11:58 ...in this case, anyway.

12:04 I'm way, way behind on my skimming of contrib in general -- I *just* "discovered" graph, which saved me a bunch of time.

12:14 replaca: cemerick: be careful with custom exceptions -> they often get wrapped in runtime exception on the way up the stack

12:14 cemerick: replaca: by clojure, you mean?

12:14 replaca: cemerick: that means it's hard to count on the exception type :-(

12:14 cemerick: yeah, by clojure

12:14 cemerick: hrm. I guess we'll see how it goes.

12:15 rhickey: replaca: could be by anyone, Java's checked exceptions misfeature means there's no guaranteed path for any arbitrary exception to travel unchanged

12:15 cemerick: I'm using the ex to catch constraint violations while processing a stateful queue, so if necessary, I could alter a ref with error info.

12:16 replaca: rhickey: I understand. In the case to which I was referring it was just me and clojure :-)

12:16 But I think that at the time rhickey and Chouser made me understand the reasons

12:16 cemerick: thank goodness we don't use much in the way of libraries

12:17 replaca: checked exceptions seemed like such a good idea back in '94

12:17 rhickey: using types to convey data (what went wrong) is a bad idea

12:17 so static

12:18 Chouser: rhickey: really? why? something about Java classes in particular, or general to the idea of types.

12:18 hm... you want more of a tag or property based thing

12:18 replaca: rhickey: agreed, but it's nice too be able to have a place to shove a globally understood token that I can guarantee is unique to my code

12:19 Chouser: throw a map full of details?

12:19 rhickey: Chouser: types are generally closed - a map would be far preferable, all call paths should be able to convey all problems

12:20 Chouser: hm... error-kit throws a map, and you can catch on whatever you want, but the syntax provided makes it by far easiest to catch by type

12:21 rhickey: think about how silly it is to have to define a new class rather than just say :problem :my-ns/my-problem-foo

12:21 open and extensible, no proliferation of useless types

12:21 dynamic

12:22 call-foo-throwing-bar becomes possible

12:22 e.g. if you have a problem, throw this thingy

12:22 Chousuke: In such a system, what alternatives do you have if you wanted the "sanity checks" that static typing can offer? :/

12:23 Perhaps you could assign types to things, but those types could not be used to make decisions in the program logic itself.

12:23 rhickey: Chousuke: are you pro- or anti- checked exceptions?

12:24 Chousuke: I'm against them, I guess :P

12:24 replaca: rhickey throws down the gauntlet :-)

12:25 Chousuke: I'm not talking about just exceptions though, but typing and compile-time checking in general.

12:25 clojurebot: http://paste.lisp.org/display/74305

12:25 rhickey: then you know there is a tradeoff to static 'sanity checks' - rigidity and inflexibility

12:25 Chousuke: it's just a continuum of rigidity

12:26 mattrepl: maybe "sanity checks" could be provided by identifying generalized types based on attributes (keys). either by looking at code or the runtime

12:27 technomancy: danlarkin: how's your http client going?

12:27 rhickey: I think there wil be a world where we have substantially more introspection capabilities for our code and that could support any number of pre-runtime validations and reasoning about all sorts of properties of our programs, type-based or not

12:27 enforced or advisory

12:28 danlarkin: technomancy: http://gist.github.com/98612 is the last I've worked on it

12:29 cemerick: http client?

12:29 technomancy: danlarkin: cool; thanks. any further plans for it?

12:29 * cemerick thinks that danlarkin is a little nuts ;-)

12:29 replaca: Apropos of almost nothing: my latest ideas for a utility is a function that reads all your files and finds defns that have the doc string after the args.

12:29 Raynes: bitbckt: That is exactly why I put absolutely no mind to the VCS. I just use whatever options I have. :p

12:30 danlarkin: rhickey: I look forward to the utopian future :)

12:31 rhickey: danlarkin: http://java-source.net/open-source/code-analyzers

12:31 bitbckt: Raynes: Then your frustration seems misplaced.

12:33 danlarkin: technomancy: yes... well... it's at least got to expose some way to add in arbitrary HTTP headers

12:33 technomancy: danlarkin: yeah. that and a more interesting name would be nice. =)

12:33 but names are hard

12:34 danlarkin: I'm gunning for clojure.contrib.http, ideally

12:34 technomancy: that's a pretty good name. =)

12:34 rhickey: clojure-in-clojure -> clojure-ast-as-clojure-data -> clojure-datalog -> ask-your-question

12:36 replaca: danlarkin: maybe we could have both clojure.contrib.http.{client,server}

12:38 danlarkin: replaca: not from me :-o

12:38 cemerick: danlarkin: not that you're taking feature requests or anything, but it'd be great if your http lib could wrap apache http-client (we don't bother using java.net.* anymore for http stuff)

12:38 technomancy: cemerick: not if it's going in contrib

12:38 danlarkin: cemerick: I whipped it up exactly because I didn't want to depend on apache http-client

12:39 replaca: danlarkin: yeah, but let's leave space in the namespace for it

12:39 cemerick: man, I'm always outnumbered on the use-the-libs-that-are-available argument. ;-)

12:40 replaca: cemerick: I think that argument is going to be a feature of clojure

12:40 technomancy: cemerick: some day in the glorious future of Clojure, you'll be able to automatically handle dependencies without writing XML

12:40 cemerick: replaca: what, that contrib has clojure-y reimplementations of existing libs?

12:41 technomancy: come by sometime, I'll show you :-)

12:41 technomancy: cemerick: o rly?

12:41 replaca: cemerick: well, figuring out when that's the right thing and when the existing java version in the right thing

12:42 rsynnott: has anyone tried clojure on the java google app engine, btw?

12:42 technomancy: rsynnott: apparently it works, but you don't get threads

12:42 so it's not that interesting

12:42 Chouser: rsynnott: yeah, there are tutorials out there

12:42 tashafa: yeah theres a tutorial out there

12:42 http://elhumidor.blogspot.com/

12:42 Chouser: out where? out there!

12:42 oh, much better. :-)

12:42 cemerick: technomancy: dependencies in git repos, git submodule to pull them in, one-time dependency addition via Netbeans' project properties. *shrug*

12:43 rsynnott: ah, yep, the thread thing could potentially be a bit of a problem

12:43 makes it not all that useful

12:43 technomancy: cemerick: heh; I've been playing around with something similar: http://github.com/technomancy/corkscrew

12:44 cemerick: but you have to be able to depend on stuff in mvn repos for it to really shine, which I haven't gotten to yet

12:45 cemerick: technomancy: we keep things simple by only depending on stuff we pull from private repos.

12:45 technomancy: cemerick: that's a lot more work though; you have to convert every dependency by hand.

12:45 cemerick: Thankfully, we've never had to depend on anything that requires any kind of fancy transitive-dependency-resolution stuff, either.

12:45 Lau_of_DK: Good evening gents

12:45 technomancy: cemerick: yeah, that's where it gets really tricky.

12:45 cemerick: I refuse to depend on external services for running builds.

12:46 technomancy: cemerick: sure, but the less-manual way to do that is to get an internal mvn repo that can mirror external ones

12:46 so you don't have to convert everything by hand

12:47 cemerick: well, I dislike maven on a number of fronts. Ivy is nicer, but not by much.

12:47 technomancy: cemerick: Ivy uses maven repos

12:47 I'm just talking about the repo format here

12:48 cemerick: well, we used our own ivy repo for about a year, and that was too much trouble. Now we just have a git repo for each dependency.

12:50 AWizzArd: rhickey: does it cost much memory to make use of the mvcc feature of the stm? Example: I have 5 refs, each storing objects of 500+ MB and then make a snapshot of all 5 and keep them several minutes while at the same time I actively modify the original refs.

12:52 rhickey: AWizzArd: that's the beauty of structural sharing, your new versions should share substantially with your snapshot

12:53 AWizzArd: that would indeed be very helpful for my persistency lib

12:57 If I have 10 refs and want to take a consistent snapshot of them all I would have to do it in a dosync, ensuring all refs, yes?

12:59 rhickey: AWizzArd: just dosync will ensure a consistent read view, ensure is about preventing your transaction from completing if another transaction has changed them

12:59 you never see the effects of other transactions in your own

13:00 AWizzArd: ah ok

13:02 technomancy: danlarkin: do you want to put this HTTP lib into a real repo?

13:02 or I could do it if you prefer

13:02 I'd like to hack on it some

13:02 danlarkin: technomancy: I had avoided that so far because I thought it best belonged in contrib and didn't want it to get all confusing when it moved or something

13:03 technomancy: danlarkin: seems like a readme would set things straight

13:04 danlarkin: you can git clone the gist, you know

13:04 but if you want to create a github project for it, be my guest

13:04 technomancy: danlarkin: yeah, but I'd like to set up a test suite etc, which would need more than one file

13:04 hiredman: sounds like the developement model I pioneered

13:04 technomancy: hiredman: heh

13:05 danlarkin: ok, will do.

13:05 danlarkin: ooooo tests, excellent

13:05 technomancy: =)

13:06 lenst: It turns out gists can have more than one file.

13:06 danlarkin: I love when someone other than me writes tests

13:07 AWizzArd: ~def ensure

13:07 lenst: http://gist.github.com/96442

13:08 technomancy: lenst: too late; it's a project. =)

13:08 danlarkin: what do you suppose the best way to test it would be? maybe bundle a copy of ring that we can make requests to?

13:08 AWizzArd: ~def touch

13:09 danlarkin: technomancy: I've just been testing against example.com/netcat

13:09 but like someone (you?) said, relying on an internet connection to run tests is suboptimal

13:10 technomancy: danlarkin: yeah, I'm not a fan. IMHO it needs to be self-contained; I'm just wondering what the best server to bundle and test against would be.

13:11 hiredman: :|

13:11 danlarkin: well if it's going to be in contrib then it shouldn't really bundle anything

13:11 hiredman: you don't want to use apache's httpclient but you want to bundle a webserver?

13:12 technomancy: test dependencies are not the same as runtime deps

13:12 hiredman: ...

13:13 technomancy: for ease of hacking right now, it makes sense to bundle it since the only people who are going to use it are going to be folks hacking on it, so they'll need to run the test suite all the time

13:13 once it gets to the point where people are going to use it without modifying it, it doesn't make sense to keep that extra baggage

13:13 danlarkin: *shrug*, could always use a ServerSocket?

13:14 technomancy: that's not bad either I guess

13:14 except it won't be able to tell you when requests are malformed

13:14 you'll just have to be more careful when specifying what you're expecting

13:15 there's no built-in lightweight HTTP server in the JDK then?

13:15 danlarkin: not in java5

13:16 technomancy: well having a java6 dependency for the test suite only is not bad

13:16 * technomancy discovers http://java.sun.com/javase/6/docs/jre/api/net/httpserver/spec/index.html

13:16 danlarkin: it is for me, since I am running java5

13:17 technomancy: oh... =(

13:17 why's that?

13:18 danlarkin: it comes with OS X 10.5

13:20 technomancy: ok, I'll see about sticking with the ServerSocket then

13:20 danlarkin: I think that would be ideal... not sure how complicated it would be to have it just accept whatever input and then return the smallest valid HTTP 1.1/0 response

13:21 hopefully not very

13:37 Raynes: bitbckt: Just because I avoid the Holy War of Git doesn't mean it's not annoying.

13:39 bitbckt: Raynes: Why be annoyed by something you have no stake in? Seems like wasted cycles, to me.

13:40 Raynes: bitbckt: I still have to listen to the zealots. I'm not sure what you're getting at. Just because you can hear the siren doesn't mean you are sounding it. :\

13:42 bitbckt: Raynes: I've gotten where I'm going: it doesn't make much sense to me to be concerned, if you don't much care what the outcome is.

13:42 Raynes: The underlying point of this conversation and its topic is: to each their own.

13:43 Raynes: bitbckt: I'm not concerned, I just simply think it's annoying that whenever someone mentions "Git" people cream themselves.

13:44 bitbckt: To each their own. Enough said.

13:44 bitbckt: Raynes: Indeed.

14:53 technomancy: is there anything like while-let?

15:00 stuhood: doesn't look like it... maybe you could doseq over a lazy sequence that continuously calls your predicate?

15:00 ...yuck

15:01 danlarkin: there's when-let

15:01 or is that not what you mean

15:03 stuhood: danlarkin: he needs a loop

15:03 neotyk: what happened to lazy-cons?

15:03 stuhood: neotyk: replaced by lazy-seq

15:03 neotyk: stuhood: thanks

15:04 danlarkin: ohhh, I see. That might be a useful abstraction to make over the loop ... if... recur idiom

15:04 rhickey: for and doseq have :let options now

15:15 AWizzArd: ah, didn't know that it was available for doseq

15:16 for for I made the experience that often the core of the loop goes into the :let

15:18 stuhood: why put the let in an option instead of around the for?

15:19 AWizzArd: because only inside the for the data gets generated

15:19 clojurebot: for is not used enough

15:19 AWizzArd: ~ botsnack

15:19 clojurebot: thanks; that was delicious. (nom nom nom)

15:20 stuhood: mmm, so why not inside the for? (for [...] (let ...))

15:21 Chousuke: convenience, I guess.

15:22 rhickey: stuhood: the only reason to use :let is to use it in a subsequent clause and save evaluating it twice

15:22 rlb: Is there a standard clojure idiom for mapping over a sequence to create more than one result sequence? I assume clojure has something like srfi-1's unzip, but I wondered if there might be a preferable approach.

15:23 AWizzArd: for example for can do this

15:23 Chousuke: hmm

15:23 rlb: (avoiding the need to create a temporary, zipped sequence)

15:24 AWizzArd: ,(for [x (range 10) :when (even? x)] [x (* x x)])

15:24 clojurebot: ([0 0] [2 4] [4 16] [6 36] [8 64])

15:24 AWizzArd: Returns even numbers and their square

15:24 stuhood: rhickey: gotcha.

15:25 rlb: AWizzArd: if that's for me, I'm looking for the eventual result to be [0 2 4 6 36] and [0 4 16 36 64].

15:25 Chousuke: hmm

15:26 rlb: AWizzArd: while you can just unzip your result, I was wondering if there might be some alternate, well known approach to avoid the intermediate sequence of tuples. If not, I can always just build the lists in parallel more explicitly.

15:27 In any case, it's not a big problem -- I just wanted to make sure I wasn't overlooking something obvious in clojure.

15:28 Chousuke: clojurebot: unzip

15:28 clojurebot: Huh?

15:28 Chousuke: hmm :(

15:29 anyway, I can't think of a way to do this lazily :/

15:32 AWizzArd: rlb: ah okay I see. Well, I am not aware if there already is a function that avoids the intermediate data. So, going the explicit route seems right to me. But maybe Contrib has something.

15:32 stuhood: the intermediate tuples seems like a reasonably elegant solution

15:34 Chousuke: (def foo (lazy-seq (concat (apply map vector (map (fn [x] [(* 3 x) (* 2 x)]) [1 2 3 4 (do (println 5) 5)]))))) seems to be lazy :P

15:34 well, hm, I dunno how lazy, though :)

15:34 AWizzArd: stuhood: performance may be an issue

15:35 rlb wants something similar as group-by which at the same time is doing a mapping

15:36 stuhood: AWizzArd: maybe i don't understand the question, but if you generate a sequence of tuples, and then map nth across that sequence, everything is still lazy

15:37 AWizzArd: If one requests data out of that sequence then it would be more performant to get the desired result directly, instead of iterating over the data twice

15:40 technomancy: oh nice; :let in for. handy

15:42 AWizzArd: a loop for that task is quite verbose

15:46 stuhood: indeed. here's one that generates a sequence of integers and strings:

15:46 (let [tuple-seq (map #(list % (str %)) (range 1000000)) int-seq (map first tuple-seq) str-seq (map second tuple-seq)] ...)

15:49 Chousuke: with that, both of the values get realised when either is accessed through the seqs :/

15:49 I guess there's no way around that without using delay

15:49 stuhood: yes, but if you don't want that behaviour, then shouldn't you just create two sequences in the first place?

15:50 Chousuke: I suppose

16:11 rlb: If I don't care about traversing the input sequence multiple times independently, then I can just return multiple lazy result sequences based on the input. That's fine as long as the traversal isn't expensive (wrt cache, virtual memory, or anything else).

16:11 hiredman: lazy-seq results are cached if you hang on to the head of the seq

16:12 so if you over a seq twice, but hang on to a reference to it, the second time doesn't do the computations to generate the seq

16:14 stuhood: *facepalm

16:14 so (let [tuple-seq (range 1000000) int-seq tuple-seq str-seq (map str tuple-seq)] ...) would have the same effect

16:14 rlb: hiredman: I'm not concerned about the computations -- imagine you have a sequence that's effectively bigger than RAM, even though the results of your multiple map calls won't be. You may want to make sure to only touch each input element one time for the generation of your N output elements. But it's easy to do that manually.

16:14 hiredman: i.e. you only want to touch each thing one time b/c you don't want to hit swap more than you have to.

16:14 (just as an example -- similar arguments can apply wrt cache)

16:15 Anyway, I was mostly just curious whether or not there was a clojure idiom I didn't know. There are plenty of other ways to handle this and related problems...

16:16 Thanks for the help.

16:18 AWizzArd: You want something similar to for, such as (group-into [x (range 10) :when (even? x)] x (* x x)) ==> ([0 2 4 6 8] [0 4 16 36 64])

16:18 would be a nice addition to clojure.contrib.seq-utils

16:21 rlb: AWizzArd: hmm, assuming it does what it looks like it does, that sounds about right.

16:21 AWizzArd: yes, it just doesn't exist ;)

16:23 kotarak: ,(reduce (fn [[fs ss] [f s]] (list (conj fs f) (conj ss s))) [[] []] [[0 0] [2 4] [4 16] [6 36]])

16:23 clojurebot: ([0 2 4 6] [0 4 16 36])

16:24 AWizzArd: eager but good

16:25 kotarak: This must obviously consume the whole seq to build the first vector. Vectors are eager.

17:05 technomancy: danlarkin: does the HTTP client send an EOF or something when it's done with the request?

17:05 trying to use raw sockets to test this thing. =)

17:05 danlarkin: I think it has to send two "\r"s or something like that

17:06 technomancy: oh, ok... same as how the response separates the headers from the body then

17:07 actually... that ignores request bodies

17:07 which is fine for now, but those will be necessary

17:14 stuhood: you're implementing an http client?

17:15 technomancy: stuhood: for now just trying to add tests to danlarkin's

17:18 ah... I see my problem. the "bindings" of with-open are lexical, not dynamic

17:20 binding doesn't always mean binding, I guess.

17:57 boredandblogging: how is RT.loadResourceScript supposed to be used? If I want to load a .clj thats not in the same directory, I keep getting a FileNotFoundException

17:58 dliebke: is the file on your classpath?

18:01 boredandblogging: *sigh* need it was going to be something that stupid, dliebke, thanks :-)

18:01 technomancy: boredandblogging: generally you shouldn't be using load or loadResourceScript or anything unless you're messing around in the repl... in a real project you should stick to use and require

18:02 boredandblogging: technomancy: can you give me a link where I can read up on that? basically I'm just trying to call the .clj from java code at the moment

18:03 technomancy: boredandblogging: oh, didn't realize you were working from Java. I know next to nothing about that.

18:06 cp2: hmm...

18:06 http://doihaveswineflu.org/

18:11 ctdean: What's a simple way to read the contents of a file into a string?

18:13 hiredman: slurp?

18:13 ,

18:13 clojurebot: EOF while reading

18:13 hiredman: ,(doc slurp)

18:13 clojurebot: "([f]); Reads the file named by f into a string and returns it."

18:13 ctdean: great, thanks

18:33 lisppaste8: technomancy pasted "http client convenience functions" at http://paste.lisp.org/display/79490

18:33 technomancy: danlarkin: is that too cute?

18:43 danlarkin: technomancy: is it necessary? I like just having request

18:44 technomancy: danlarkin: I think it helps minimize the noise

18:45 but using eval is unfortunate

18:45 danlarkin: I feel like it creates noise

18:46 technomancy: in the implementation or the interface?

18:46 danlarkin: oh... sorry, I'm talking about the existence of the functions... the interface

18:47 the implementation is cute but I think not a great idea for library code

18:47 technomancy: yeah, the stacktraces will get messy

18:48 I guess since method defaults to get, you only have to specify it when you need to pass in custom headers or use post etc.

18:48 danlarkin: right

18:49 technomancy: also: response headers need to allow for case-insensitive lookup

18:49 so we'll need to return an fn instead of a map

18:50 * danlarkin wishes clojure had syntax for keyword args

18:50 danlarkin: I donno about that... then you can't run keys or vals on it... iterate over it, etc

18:51 technomancy: that's true

18:51 but how would you allow for a case-insensitive lookup?

18:52 it's possible with proxy, but that gets ugly

18:52 danlarkin: yeah proxy's all I can think of... but why does it need case-insensitive lookup?

18:53 technomancy: because according to the spec, "content-type" should be treated the same as "Content-Type"

18:53 danlarkin: ahh

18:53 technomancy: it's kind of wacky, but that's the correct behaviour

18:54 danlarkin: what about #(.toLowerCase %)ing all the keys?

18:55 technomancy: this is pretty edge-casey... I'll slap a TODO on it and deal with it later.

18:57 danlarkin: how about this compromise: :headers is a map, :get-header is a fn that handles case correctly.

18:58 danlarkin: yes, that would be okay with me

18:58 I *think* python's urllib2 does that same thing

19:00 technomancy: danlarkin: current state: http://github.com/technomancy/clojure-http-client/blob/a0f94a7778419ec353c3fc5e2bad1ef65193cb8a/test/clojure/http/test/client.clj

19:03 danlarkin: technomancy: it's looking solid

19:03 and tests! hooray

19:04 technomancy: I renamed "create-url" to "url" in order to be consistent with the "file" function in java-utils

19:04 and implemented custom request headers.

19:05 apart from that I think the only changes were making internal stuff private

19:12 danlarkin_: yeah the change to "url" is a good idea, good to be consistent

19:14 technomancy: still needs to support request bodies

19:14 transforming a map into a form-encoded POST body

19:15 hiredman: (doc repl)

19:15 clojurebot: No entiendo

19:17 hiredman: (doc clojure.main/repl)

19:17 clojurebot: Gabh mo leithsc�al?

19:17 hiredman: ,(doc clojure.main/repl)

19:17 clojurebot: "([& options]); Generic, reusable, read-eval-print loop. By default, reads from *in*, writes to *out*, and prints exception summaries to *err*. If you use the default :read hook, *in* must either be an instance of LineNumberingPushbackReader or duplicate its behavior of both supporting .unread and collapsing CR, LF, and CRLF into a single \\newline. Options are sequential keyword-value pairs. Available options and their d

20:02 danlarkin: technomancy: here's a docstring for create-cookie-string, if you like: https://gist.github.com/7c99d0a79ae714ec1ca3

20:05 technomancy: cool

20:08 danlarkin: oops! I put it after the arg list :) that's what I get for being too lazy to open the file in emacs

20:12 technomancy: good thing I didn't apply the patch directly. =)

20:19 gnuvince_: I'd like to preface this following statement with this: I am drunk


20:38 cp2: gnuvince_: :)

22:07 lisppaste8: hiredman annotated #79434 "parent node fixed" at http://paste.lisp.org/display/79434#5

22:33 eee: hi

22:34 durka42: hi eee

22:34 eee: been stuck on my heap for days

22:34 will have to really study it this weekend

22:35 need a second pair of eyes

22:35 but other than that it looks promissing

22:35 (I think)

22:35 as a cool think for clj

22:36 had to comment out a line of code to "make it work"

22:36 but I don't get why :)

22:36 what's up with others?

22:48 chessguy: hi eee . what is it you're working on, exactly

23:02 eee: http://code.google.com/p/jc-pheap/

23:07 danlarkin: blarg, why are my tests failing with "Wrong number of args passed to keyword: :type"... I'm not using type :(

23:08 some change in clojure or contrib brought this on, since they used to work and I haven't touched the code

23:11 hiredman: only two places :type is used in core, the type function and print-method

23:12 chessguy: eee: sounds interesting. do you literally mean that no operations have side effects, or just no _visible_ side effects?

23:12 eee: let me think

23:13 danlarkin: hiredman: the unit tests for my json lib

23:13 eee: it's pretty close to the former

23:13 chessguy: impressive

23:13 eee: i mean, you have to do 'new'

23:13 when you insert

23:14 so is that a side affect?

23:14 effect

23:14 kinda philosophical question

23:14 danlarkin: I went to fix a bug (decode-from-string raises an exception when passed an empty string) but now I've gotten myself sidetracked :(

23:14 chessguy: do you get back a different object on different calls of new?

23:15 eee: jvm would give you a new object

23:15 but . . i mean, the whole jvm "changed"

23:15 so that's like a side-effect, too

23:15 but I guess that's not what you mean

23:16 so I think it's the former

23:16 chessguy: well if we wanted to outlaw side effects completely, we'd use haskell or something, right?

23:16 eee: maybe that is one thing someone else could confirm

23:17 i found an article on haskel which did lot's of destructive stuff

23:17 was way complicated

23:17 he showed that he could quicksort in place

23:17 partition in one pass

23:17 etc

23:17 but it was insane

23:18 hiredman: clojurebot: shave that yak!

23:18 clojurebot: fastest sheers on IRC

23:18 eee: at any rate, I have a test that should be showing that no operation affects any other view

23:19 the hard part was supporting deletes from the middle of the heap

23:19 and change priority from middle of heap

23:19 i may have succeeded

23:20 but there's a gnawing feeling there's a bug that I just haven't found yet

23:20 also, usability

23:20 let's say I put in "a" with priority 5

23:21 then I put in "b" with priority 4

23:21 then I decide "a" needs an update

23:21 it is in the heap somewhere

23:21 min is where "b" is

23:22 so I have to tell the truth and say change "a" from 5 to 3

23:22 but if the program won't crash if you had said change "a" from 98 to 3

23:22 even though no such value

23:23 is that ok?

23:23 one reason is that there can currently be more than one "a"

23:24 danlarkin: hiredman: the error is either something to do with my custom assert-expr or something in test-is, I have concluded

23:25 chessguy: eee: do you have actual use cases for this structure?

23:25 eee: great question

23:25 that would answer my question for me

23:26 so next step is to try to use it for A* search problems

23:26 like 15 puzzle

23:26 or I could implement shortest path

23:27 A* can just use regular heap without those fancy structures

23:27 but

23:27 djikstra's

23:28 need's "decreaseKey()"

23:28 i went for extra credit here making my life tough and you can "increaseKey()" too

23:29 and there are two deletes for deleting out of the middle. eagerDelete and lazyDelete

23:29 clojurebot: for is not a loop

23:29 eee: for

23:30 cads: what can I use in clojure for drawing graphs or 3d mathematical surfaces?

23:30 danlarkin: hiredman: figured out! the syntax to call test-is/report changed. *sigh*

23:30 hiredman: tada

23:32 chessguy: eee: they say you should have at least 3 instances of a problem to really write a good solution for it

23:33 eee: ok

23:33 my ultimate goal is to do parallel branch and bound in clojure

23:34 but first I needed the heap

23:34 then I need to learn the parallel stuff in clj

23:34 as well as just getting good at clj

23:35 the problem in the most generic terms, is that breadth-first-search is space-consuming

23:35 besides time-wasting

23:36 depth-first is just silly . . .sometimes even with a bounding function

23:36 but

23:36 breadth-first with a bounding function and a heuristic as to what to try first

23:36 well

23:36 the heap allows you to try stuff in priority order

23:37 and the bounding function allows you to delete what you can prune from the queue

23:37 which requires delete from the middle

23:37 i'd use eagerDelete to try to reclaim the memory as soon as possible there

23:38 since memory is the main commodity

23:38 so that's the problem space

23:39 cads, this is cheating

23:39 but

23:39 you can call gnuplot from java

23:40 as an exec

23:41 http://www.ies.co.jp/math/java/misc/SimpleGraph3D/SimpleGraph3D.html

23:41 a 3d java thing

23:47 gnight all

Logging service provided by n01se.net