2009-04-30
| 00:01 | hiredman | http://gist.github.com/104249 |
| 00:04 | durka42 | that's neat |
| 00:41 | z5h | Are there a set of regression tests run against clojure releases? Are they available somewhere? |
| 00:47 | z5h | ahhh. part of clojure-contrib http://code.google.com/p/clojure-contrib/source/browse/#svn/trunk/src/clojure/contrib/test_clojure |
| 02:27 | Lau_of_DK | Top of the morning gents |
| 05:37 | neotyk | Hi All |
| 05:38 | neotyk | After downloading clojure I have problems building clojure-contrib (fresh from svn), error in types.clj:14 |
| 05:40 | neotyk | only when built clojure from svn can build clojure-contrib |
| 05:52 | leafw | neotyk: that is not surprising |
| 05:52 | leafw | clojure-contrib svn repos chases clojure repos. |
| 05:53 | neotyk | leafw: wouldn't it be a good idea to have distribution jars as clojure has? |
| 05: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. |
| 05:56 | neotyk | leafw: for new comers like me, I wan't to get clojure env in vim and it needs clojure-contrib |
| 05:57 | neotyk | so to use vimclojure i need to build from svn |
| 05:57 | neotyk | fine by me, but not very user friendly |
| 05:58 | leafw | neotyk: explain it to the mailing list, a solution may come up. |
| 05:59 | neotyk | leafw: I'll post to list |
| 06: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. |
| 06:25 | neotyk | Raynes: clojure-contrib builds fine if clojure is built from svn, just mailed it to mailinglist |
| 08: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 |
| 08:11 | cemerick | am I missing something really simple here? |
| 08:14 | rhickey | ::myns/foo |
| 08:22 | cemerick | I guess I was pretty tired, or something. Yeah, that's my excuse. :-( |
| 08:23 | AWizzArd | rhickey: did you see my messages (about 14 hours ago)? |
| 08:23 | rhickey | AWizzArd: no |
| 08:23 | Raynes | cemerick got owned by The Creator. |
| 08:23 | AWizzArd | Can you scroll up in the history of this channel? |
| 08:23 | Raynes | :p |
| 08:25 | rhickey | AWizzArd: find the time anchor in http://clojure-log.n01se.net/date/2009-04-29.html |
| 08:26 | AWizzArd | It started http://clojure-log.n01se.net/date/2009-04-29.html#17:45 |
| 08:28 | jdz | i have not used hg, but imho git is awesome |
| 08:29 | rhickey | AWizzArd: what's the question? |
| 08:29 | cemerick | oh good, an SCM LOC pissing match. Haven't seen one of those in a while. :-P |
| 08: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. |
| 08:32 | AWizzArd | That could have left the impression that work with branches in hg is somehow difficult. |
| 08: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 |
| 08:35 | rhickey | these decisions are never purely technical |
| 08:36 | AWizzArd | yes |
| 08:37 | AWizzArd | If the choice is (one-of :git :hg), then I am already sure, it is a good descision. |
| 08:37 | AWizzArd | Would just be nice if you got a fair impression of both candidates. |
| 08:38 | rhickey | Torvalds says they're essentially the same, modulo some implementation details |
| 08: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. |
| 08:40 | AWizzArd | rhickey: I also had mostly that impression. I was/am using both systems. |
| 08: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. |
| 08:42 | rhickey | cemerick: have you seen enclojure's support for looking at multimethods? |
| 08:42 | AWizzArd | cemerick: could you tell a bit more what the obviously extras in capability are? |
| 08:43 | neotyk | as recently jvanzyl (maven guy) is totally after git I'd expect very good support for it in Java world |
| 08:43 | AWizzArd | neotyk: Sun uses hg for the OpenJDK and for OpenSolaris... |
| 08:43 | cemerick | rhickey: You mean some widgets for doing some introspection on them? |
| 08:43 | rhickey | cemerick: yeah, really neat |
| 08:43 | AWizzArd | I think for people working in the Java domain hg seems to be a good fit. |
| 08: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. |
| 08:44 | neotyk | AWizzArd: I know, and kenai is HQ as well |
| 08:44 | cemerick | AWizzArd: arbitrary dispatch fns (or dispatch multimethods themselves) brings a whole 'nuther level to it all. |
| 08:44 | neotyk | but Sun is not providing much of the tooling for it, does it? |
| 08:45 | AWizzArd | cemerick: some lines of CL code can extend CLs multimethods to do the same. |
| 08:46 | AWizzArd | I think it is a good design descision that rhickey took with Clojure. In CL it is possible, but noone is doing it. |
| 08:46 | cemerick | AWizzArd: Good to know. I'd certainly prefer avoiding picking up any bad (non-clojure-idiomatic) habits from other multimethod systems, though. |
| 08:46 | AWizzArd | yes |
| 08: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. |
| 08:47 | AWizzArd | *g* |
| 08:54 | AWizzArd | 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. |
| 09:19 | cemerick | hrm, what's the magic java.util.Formatter incantation to get a list's elements to be printed out? |
| 09:19 | cemerick | nm, it was just a lazy seq... |
| 11:38 | cemerick | ~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 | AWizzArd | Also watch the number of members in the google group |
| 11:38 | AWizzArd | 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 | tashafa | 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 | cemerick | 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 | cemerick | 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 | cemerick | :-) |
| 11:57 | cemerick | 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 | cemerick | ...in this case, anyway. |
| 12:04 | cemerick | 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 | replaca | 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 | replaca | 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 | rhickey | so static |
| 12:18 | Chouser | rhickey: really? why? something about Java classes in particular, or general to the idea of types. |
| 12:18 | Chouser | 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 | rhickey | open and extensible, no proliferation of useless types |
| 12:21 | rhickey | dynamic |
| 12:22 | rhickey | call-foo-throwing-bar becomes possible |
| 12:22 | rhickey | 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 | Chousuke | 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 | rhickey | 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 | rhickey | 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 | 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 | technomancy | 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 | cemerick | 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 | technomancy | 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 | tashafa | http://elhumidor.blogspot.com/ |
| 12:42 | Chouser | out where? out there! |
| 12:42 | Chouser | 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 | rsynnott | 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 | technomancy | 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 | technomancy | 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 | technomancy | 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 | AWizzArd | 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 | rhickey | 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 | technomancy | or I could do it if you prefer |
| 13:02 | technomancy | 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 | danlarkin | 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 | technomancy | 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 | technomancy | 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 | danlarkin | 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 | technomancy | 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 | technomancy | except it won't be able to tell you when requests are malformed |
| 13:14 | technomancy | you'll just have to be more careful when specifying what you're expecting |
| 13:15 | technomancy | 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 | danlarkin | it is for me, since I am running java5 |
| 13:17 | technomancy | oh... =( |
| 13:17 | technomancy | 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 | danlarkin | 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 | bitbckt | 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 | Raynes | 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 | stuhood | ...yuck |
| 15:01 | danlarkin | there's when-let |
| 15:01 | danlarkin | 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 | AWizzArd | 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 | rlb | 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 | Chousuke | 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 | Chousuke | well, hm, I dunno how lazy, though :) |
| 15:34 | AWizzArd | stuhood: performance may be an issue |
| 15:35 | AWizzArd | 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 | stuhood | (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 | Chousuke | 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 | hiredman | 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 | stuhood | 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 | rlb | 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 | rlb | (just as an example -- similar arguments can apply wrt cache) |
| 16:15 | rlb | 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 | rlb | 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 | AWizzArd | 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 | technomancy | 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 | technomancy | actually... that ignores request bodies |
| 17:07 | technomancy | 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 | technomancy | ah... I see my problem. the "bindings" of with-open are lexical, not dynamic |
| 17:20 | technomancy | 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 | cp2 | 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 | hiredman | , |
| 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 | technomancy | 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 | danlarkin | 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 | technomancy | 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 | technomancy | so we'll need to return an fn instead of a map |
| 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 | technomancy | but how would you allow for a case-insensitive lookup? |
| 18:52 | technomancy | 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 | technomancy | 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 | danlarkin | 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 | danlarkin | 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 | technomancy | and implemented custom request headers. |
| 19:05 | technomancy | 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 | technomancy | 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:19 | gnuvince_ | CLOJURE FUCKING RULES! |
| 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 | eee | will have to really study it this weekend |
| 22:35 | eee | need a second pair of eyes |
| 22:35 | eee | but other than that it looks promissing |
| 22:35 | eee | (I think) |
| 22:35 | eee | as a cool think for clj |
| 22:36 | eee | had to comment out a line of code to "make it work" |
| 22:36 | eee | but I don't get why :) |
| 22:36 | eee | 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 | danlarkin | 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 | eee | when you insert |
| 23:14 | eee | so is that a side affect? |
| 23:14 | eee | effect |
| 23:14 | eee | 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 | eee | but . . i mean, the whole jvm "changed" |
| 23:15 | eee | so that's like a side-effect, too |
| 23:15 | eee | but I guess that's not what you mean |
| 23:16 | eee | 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 | eee | i found an article on haskel which did lot's of destructive stuff |
| 23:17 | eee | was way complicated |
| 23:17 | eee | he showed that he could quicksort in place |
| 23:17 | eee | partition in one pass |
| 23:17 | eee | etc |
| 23:17 | eee | 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 | eee | the hard part was supporting deletes from the middle of the heap |
| 23:19 | eee | and change priority from middle of heap |
| 23:19 | eee | i may have succeeded |
| 23:20 | eee | but there's a gnawing feeling there's a bug that I just haven't found yet |
| 23:20 | eee | also, usability |
| 23:20 | eee | let's say I put in "a" with priority 5 |
| 23:21 | eee | then I put in "b" with priority 4 |
| 23:21 | eee | then I decide "a" needs an update |
| 23:21 | eee | it is in the heap somewhere |
| 23:21 | eee | min is where "b" is |
| 23:22 | eee | so I have to tell the truth and say change "a" from 5 to 3 |
| 23:22 | eee | but if the program won't crash if you had said change "a" from 98 to 3 |
| 23:22 | eee | even though no such value |
| 23:23 | eee | is that ok? |
| 23:23 | eee | 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 | eee | that would answer my question for me |
| 23:26 | eee | so next step is to try to use it for A* search problems |
| 23:26 | eee | like 15 puzzle |
| 23:26 | eee | or I could implement shortest path |
| 23:27 | eee | A* can just use regular heap without those fancy structures |
| 23:27 | eee | but |
| 23:27 | eee | djikstra's |
| 23:28 | eee | need's "decreaseKey()" |
| 23:28 | eee | i went for extra credit here making my life tough and you can "increaseKey()" too |
| 23:29 | eee | 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 | eee | my ultimate goal is to do parallel branch and bound in clojure |
| 23:34 | eee | but first I needed the heap |
| 23:34 | eee | then I need to learn the parallel stuff in clj |
| 23:34 | eee | as well as just getting good at clj |
| 23:35 | eee | the problem in the most generic terms, is that breadth-first-search is space-consuming |
| 23:35 | eee | besides time-wasting |
| 23:36 | eee | depth-first is just silly . . .sometimes even with a bounding function |
| 23:36 | eee | but |
| 23:36 | eee | breadth-first with a bounding function and a heuristic as to what to try first |
| 23:36 | eee | well |
| 23:36 | eee | the heap allows you to try stuff in priority order |
| 23:37 | eee | and the bounding function allows you to delete what you can prune from the queue |
| 23:37 | eee | which requires delete from the middle |
| 23:37 | eee | i'd use eagerDelete to try to reclaim the memory as soon as possible there |
| 23:38 | eee | since memory is the main commodity |
| 23:38 | eee | so that's the problem space |
| 23:39 | eee | cads, this is cheating |
| 23:39 | eee | but |
| 23:39 | eee | you can call gnuplot from java |
| 23:40 | eee | as an exec |
| 23:41 | eee | http://www.ies.co.jp/math/java/misc/SimpleGraph3D/SimpleGraph3D.html |
| 23:41 | eee | a 3d java thing |
| 23:47 | eee | gnight all |