2011-02-26
| 00:00 | amalloy | ccw has a lot of the paredit functionality now, i believe |
| 00:02 | Lulu58e2 | Yeah, I was using la-clojure in IDEA but I don't it sat idle for quite a while, not many features |
| 00:02 | Lulu58e2 | * ... I think it sat idle ... |
| 00:02 | Lulu58e2 | (My brain edits as I type and my hands get confused) |
| 00:03 | amalloy | try the other way around. let your fingers edit while your brain gets confused |
| 00:05 | Sgeo | Lulu58e2, each nick has a color |
| 00:05 | Sgeo | It's deterministic what nick becomes what color |
| 00:05 | seancorfield | Lulu58e2: i'm using whatever is the standard default on ubuntu :) |
| 00:05 | Lulu58e2 | Sgeo: as in, the hash of the nick or some such? |
| 00:05 | Sgeo | And I don't see you as grey or blue. That's just for yourself |
| 00:06 | Sgeo | Lulu58e2, I don't know details |
| 00:06 | Lulu58e2 | seancorfield: lol, gnome I think |
| 00:06 | Sgeo | But you're the same color as seancorfield |
| 00:06 | Lulu58e2 | Sgeo: well that's good to know, thanks |
| 00:06 | Lulu58e2 | I had a brilliant idea: rtfm ... lol |
| 00:09 | seancorfield | Lulu58e2: mostly i use linux on servers so i never see the GUI... and i generally have Macs for desktop / laptop |
| 00:09 | Lulu58e2 | seancorfield: ah, lucky |
| 00:09 | seancorfield | i just bought a system76 starling netbook for traveling with and it has ubuntu netbook remix on it |
| 00:09 | seancorfield | which is what i'm on right now :) |
| 00:11 | Lulu58e2 | seancorfield: very nice |
| 00:18 | Lulu58e2 | Okay, so the xchat help didn't help, but someone on #xchat did. |
| 00:25 | amalloy | and? |
| 00:25 | Lulu58e2 | Settings -> Advanced -> Text Events "has everything to do with it" |
| 00:26 | Lulu58e2 | Colour and formatting codes for all events |
| 00:26 | amalloy | neat |
| 00:47 | Lulu58e2 | lol |
| 00:47 | Lulu58e2 | So easily distracted from the task at hand |
| 00:56 | Sgeo | I'm going to try to translate the PMD paper's demo to Clojure |
| 01:54 | cobol_expert | what are symbols of the form *symbol* called? |
| 01:58 | Sgeo | I think I like Haskell's State monad a little more than I like Clojure's -> macro |
| 01:59 | cobol_expert | also, when docs say 'set *warn-on-reflection* to true...' how do you set it? |
| 01:59 | cobol_expert | just redefine it, like (def *warn-on-reflection* true) ?? |
| 02:00 | amalloy | cobol_expert: (set! ...) |
| 02:00 | amalloy | symbols are wrapped in *earmuffs* usually to indicate that they're expected to change and/or be rebound |
| 02:01 | amalloy | Sgeo: wut. they are completely different things. clojure has a state monad too |
| 02:01 | cobol_expert | okay, thanks. i remember seeing that before, but I don't see docs for 'set!' anywhere.. i would expect it to be in clojure.core |
| 02:02 | cobol_expert | what ns is set! in? |
| 02:02 | amalloy | &(doc set!) |
| 02:02 | sexpbot | java.lang.SecurityException: You tripped the alarm! set! is bad! |
| 02:02 | amalloy | blah. cobol_expert, set! is a special form |
| 02:02 | amalloy | (doc set!) |
| 02:02 | clojurebot | Pardon? |
| 02:03 | cobol_expert | ah, whenever I can't figure something out, it's a 'special form' :) |
| 02:03 | Sgeo | Are Clojure monads used as commonly as monads in Haskell (subtracting usage of Haskell's IO monad, of course) |
| 02:03 | cobol_expert | i should know by now |
| 02:04 | amalloy | you bots all suck: http://clojure.org/vars#Vars%20and%20the%20Global%20Environment--%28set!%20var-symbol%20expr%29 |
| 02:05 | Sgeo | o.O Clojure can use Monadic I/O |
| 02:05 | Sgeo | I'm going to hazard a guess that it's mostly used by Haskellers |
| 02:07 | amalloy | as with every clojure tool, it's mostly used by developers who think it's the best widget for the current job |
| 02:14 | cobol_expert | okay, so how do I create a new global variable to use set! with? (def *a* 1) ; (set! *a* 2) doesn't work.. that link says it 'must resolve to a global variable' |
| 02:19 | amalloy | cobol_expert: don't: clojure doesn't want you to introduce mutable state. vars should created with def and bound with (binding [var value] (var is globally changed until binding form is over)) |
| 02:20 | amalloy | once a var has been bound, you can set it with set!, but usually shouldn't anyway |
| 02:21 | amalloy | in fact i've never set! anything but warn-on-reflection and a couple java instance fields :P |
| 02:22 | cobol_expert | okay, thanks for clearing that up :) |
| 02:23 | cobol_expert | i just see that form a lot and wondered if I ought to be using it for my programs' globals.. i guess not |
| 02:23 | Sgeo | binding is dynamic though, couldn't it cause weird issues if not used with caution? |
| 02:23 | Sgeo | (binding [some-function-name-but-i-dont-realize-it nil] ...) |
| 02:24 | Sgeo | Hmm, accidentally binding a function name like that probably wouldn't happen, come to think of it' |
| 02:27 | Sgeo | All names are namespaced? |
| 02:29 | cobol_expert | binding seems to create its own namespace |
| 02:29 | amalloy | neither of the previous two statements is true |
| 02:30 | cobol_expert | 'seems to' is not an assertion :) |
| 02:30 | amalloy | lol |
| 02:30 | amalloy | lots of names aren't namespaced, for example x in (let [x 10] (inc x)) |
| 02:30 | amalloy | *most* vars are namespaced, which may have been what you meant |
| 02:31 | amalloy | cobol_expert: binding pushes the value of a global variable onto a stack, changes it, and sets it back, more or less |
| 02:31 | cobol_expert | yeah, i was struggling with how to say it |
| 02:31 | cobol_expert | more or less |
| 02:32 | amalloy | it piggybacks on top of the existing namespaces in the vars; it definitely doesn't create its own |
| 02:34 | Sgeo | Why are there no lisps that have special forms be first-class values? Or are there? |
| 02:35 | amalloy | that's what makes them special |
| 02:38 | Sgeo | I thought what made them special was that inner arguments aren't fully evaluated before being sent |
| 02:38 | Sgeo | Or something along those lines |
| 02:40 | amalloy | Sgeo: the same is true of user-defined macros, and those definitely aren't special |
| 02:46 | Sgeo | I meant to include user-defined macros |
| 02:46 | Sgeo | But why aren't they first-class? |
| 02:47 | amalloy | they don't have values. it doesn't make sense to be able to pass a macro as a value at runtime, because it can only perform actions at compile time |
| 02:47 | Sgeo | Ah |
| 02:48 | Sgeo | Sorry if I seem like an idiot. |
| 02:51 | amalloy | Sgeo: http://rantsand.blogspot.com/2006/09/intelligence-wisdom-ignorance-and.html is an entertaining discussion of the difference between stupidity and ignorance |
| 04:03 | semperos | I have a structure like {:foo #{"bar" "baz"}} |
| 04:03 | semperos | starting with an empty map |
| 04:03 | semperos | I know if I do |
| 04:03 | semperos | ,(assoc {} :foo #{}) |
| 04:03 | clojurebot | {:foo #{}} |
| 04:04 | semperos | I get a structure with which I can use update-in to conj onto the set |
| 04:04 | semperos | ,(update-in {:foo #{}} [:foo] conj "bar") |
| 04:04 | clojurebot | {:foo #{"bar"}} |
| 04:04 | semperos | and so on as I add to that set |
| 04:04 | semperos | my question is |
| 04:04 | Arelius | I'm not sure I understand why when I eval a ns block, I get an error 'replace already refers to ...." in slime when normally that's just a warning. |
| 04:04 | amalloy | semperos: fnil |
| 04:05 | amalloy | &(update-in {} [:foo] (fnil conj #{}) "bar") |
| 04:05 | sexpbot | ⟹ {:foo #{"bar"}} |
| 04:05 | semperos | amalloy: thank you for anticipating my question |
| 04:05 | semperos | I keep forgetting that fnil exists |
| 04:05 | amalloy | semperos: you were building up to it quite thoroughly :) |
| 04:05 | semperos | :) |
| 04:05 | semperos | I knew there was a way |
| 04:06 | semperos | and I keep missing the opportunities to use it |
| 04:06 | semperos | amalloy: thanks, really appreciate it |
| 04:06 | amalloy | semperos: i went out of my way to use fnil the other day. up till now i basically just use it for update-in |
| 04:06 | semperos | very natural fit for this kind of thing |
| 04:07 | Toomasu | I hadn't seen fnil yet, tangible benefit from following the channel for a couple of minutes :) |
| 04:07 | amalloy | and in fact even in https://gist.github.com/ac577998a404164266aa i'm really just using it for a more-specialized version of update-in, i guess. so no extra credit for finding new places to use fnil |
| 04:09 | semperos | gotcha |
| 04:10 | semperos | Toomasu: imho, you won't find many channels better than this one |
| 04:10 | semperos | for any language/project |
| 04:11 | amalloy | semperos: i have a tidier version of that code somewhere but i might have thrown it away. i surprised myself by writing (let [[< inc] (map #(fnil % 0) [< inc])] ...) |
| 04:11 | amalloy | so that the nil-handling code didn't have to be next to the math-handling code |
| 04:12 | semperos | absolutely, your use in that gist makes sense |
| 04:12 | semperos | with a more complex data structure elsewhere in my code, I think I already committed an oversight and "prepped" map entries |
| 04:12 | amalloy | ah |
| 04:12 | semperos | so I'll have to go back and fnilify that |
| 04:13 | amalloy | fnilify. that's a tricky one to pronounce |
| 04:13 | semperos | :) |
| 04:14 | semperos | eff-nil-ify |
| 04:14 | semperos | how I hear it, anyway |
| 04:25 | fliebel | morning. |
| 04:25 | amalloy | allo fliebel |
| 04:27 | fliebel | In this post by dnolen, why is he creating these multimethods with a single method? http://dosync.posterous.com/beyond-javascript-prototype-chains The type inheritance is nice and all, but I don't see why he does not use regular functions, or a single multimethod. |
| 06:07 | amalloy | semperos, if you're still around and are interested, i've written two more versions of keep-only at https://gist.github.com/ac577998a404164266aa |
| 06:11 | amalloy | i'm not sure whether the second or third version is more readable, and the fourth certainly isn't, but it's been fun playing with refining an idea, and figuring out how to lazify it was a real headache |
| 06:13 | kencausey | I've just created #las3r for anyone interested in the AVM2 'port' of Clojure - https://github.com/aemoncannon/las3r |
| 06:14 | semperos | amalloy: unfortunately I am still around, can't sleep |
| 06:14 | semperos | thanks, I'll take a look |
| 06:14 | amalloy | semperos: same here, though i was about to clock out. what time is it where you are? |
| 06:14 | semperos | 6 |
| 06:14 | semperos | you? |
| 06:14 | clojurebot | You will not become skynet |
| 06:15 | amalloy | 3 |
| 06:15 | semperos | more sane :) |
| 06:15 | semperos | I slept for a few hours |
| 06:15 | semperos | but woke around 2:30 my time and can't sleep |
| 06:15 | semperos | go get some rest, thanks for all your help |
| 06:16 | amalloy | semperos: you're welcome. i'm not doing it for you, though :) - i think i'll write a blog post about how a simple idea evolves into various different versions |
| 06:17 | amalloy | kencausey: hey neat. one of my friends thinks clojure is really cool but will never spend the time to do anything with it - maybe i can get him halfway there in his native flash environment |
| 06:18 | kencausey | It's not my implementation of course, I'm just an interested user. And note it is as much influenced by clojure as a port, but yes, it is sort of halfway |
| 06:18 | kencausey | I would say it is less polished at this point and certainly has nothing like the community of clojure, I'm hoping to improve that somewhat |
| 06:18 | amalloy | well, i'll remember not to claim i know the guy who wrote it all |
| 06:19 | kencausey | :) |
| 06:21 | amalloy | night folks |
| 06:44 | semperos | I've removed clojure.contrib from my project.clj, but leiningen keeps pulling in the lib when I run 'lein deps' and 'lein uberjar' |
| 06:44 | semperos | am I missing something? |
| 06:45 | semperos | nm |
| 08:04 | gfrlog | Good morning clojure |
| 08:07 | tscheibl | may I introduce queuejure |
| 08:08 | gfrlog | please |
| 08:10 | tscheibl | it's a http long polling library based on a compojure ring aleph lamina combination |
| 08:11 | gfrlog | now I have to find out what lamina is |
| 08:11 | tscheibl | it's very lightweight.. not as bloated as CometD is... |
| 08:11 | tscheibl | lamina is a channel framework |
| 08:11 | gfrlog | was it extracted from aleph? |
| 08:12 | tscheibl | ..just enough functionality to implement a reliable server messagequeue |
| 08:12 | tscheibl | gfrlog: lamina? |
| 08:12 | gfrlog | yes |
| 08:12 | tscheibl | probably |
| 08:13 | tscheibl | it's quite usefull for implementing messagequeues |
| 08:13 | tscheibl | .. I mean.. you don't have much mor to implement |
| 08:14 | gfrlog | cool |
| 08:15 | tscheibl | queuejour primarily focuses on hiding http request concurrency issues and request timeouts |
| 08:16 | tscheibl | well.. I think I will call it queuejour ... despite the fact that technomancy won't like it ;) |
| 08:16 | gfrlog | I was thinking of that naming controversy |
| 08:16 | tscheibl | got a better name? ;) |
| 08:16 | tscheibl | I'm open for proposals |
| 08:17 | fliebel | tscheibl: Are you making a message queue? |
| 08:17 | gfrlog | queue-ball |
| 08:17 | tscheibl | Yesterday it started to do everything I expected in my testbed... currently I try to create a decent library from the prototype code |
| 08:18 | fliebel | clueue :) |
| 08:18 | tscheibl | lol |
| 08:18 | gfrlog | can't beat that |
| 08:19 | tscheibl | msjqueue |
| 08:19 | tscheibl | ..nah |
| 08:19 | gfrlog | ueueueue |
| 08:19 | tscheibl | jeujeujeujeu |
| 08:19 | gfrlog | pronounced "oooh!" |
| 08:19 | tscheibl | jeujour |
| 08:19 | tscheibl | excuse my french ;) |
| 08:20 | fliebel | ceuj |
| 08:20 | tscheibl | cjeu ? |
| 08:20 | tscheibl | cjeur ? |
| 08:20 | raek | monsieur clojeur |
| 08:20 | tscheibl | clojard |
| 08:21 | raek | (the community seems to have settled on "clojurian", but always felt that "clojeur" was an interesting option) |
| 08:21 | fliebel | raek: I agree :) |
| 08:22 | tscheibl | org.myveryownorangisationname.http.toolkits.qeuejour |
| 08:22 | tscheibl | arghh |
| 08:22 | raek | fliebel: that even fits the dutch spelling system, doesn't it? |
| 08:23 | fliebel | yea… but that is probably because dutch borrows heavily from french |
| 08:23 | tscheibl | they borrow from everyone ;) |
| 08:23 | raek | Klåschör |
| 08:24 | tscheibl | you are scandinavian, aint you? |
| 08:24 | raek | swedish does that too to some extent, but the spelling makes it less obvious |
| 08:24 | tscheibl | yess Sweden |
| 08:25 | tscheibl | raek |
| 08:25 | tscheibl | I'm from Austria |
| 08:25 | tscheibl | ... no... no Kangaroos |
| 08:25 | fliebel | you did not say australia did you? |
| 08:26 | tscheibl | Claustralia |
| 08:26 | tscheibl | .but there is no j in it |
| 08:26 | gfrlog | my great grandparents are from sweden |
| 08:26 | fliebel | I've been to sweden last month (to contribute some other random fact) |
| 08:27 | tscheibl | I've been in Norway some years ago.. that's at least close ;) |
| 08:27 | gfrlog | I think that roughly equals great-grandparentage as far as being-swedish goes |
| 08:27 | tscheibl | would be like great-grandparents |
| 08:29 | gfrlog | Sweden is in the news lately |
| 08:30 | fliebel | gfrlog: Because of that leaking guy? O rjust because Sweden is taking over3 the world? |
| 08:31 | tscheibl | I think you confuse it with Libya |
| 08:31 | gfrlog | it's always those two |
| 08:31 | gfrlog | I'm like "which is which?" and I can never remember |
| 08:32 | fliebel | gfrlog: sweden hos no sand, so if you seen sand in the news, it's not sweden |
| 08:32 | gfrlog | well I hope al-Gaddafi is nice to Mister Assange... |
| 08:33 | fliebel | So, is Anonymous behind these protest after all? |
| 08:33 | tscheibl | both of them will need political asylum in the near future |
| 08:33 | tscheibl | .. if they make it before beeing executed |
| 08:34 | tscheibl | ..ahhh don't say 'anony....' they will close down irc |
| 08:36 | gfrlog | maybe we could use queuejure to send Mister Assange a helpful message |
| 08:36 | gfrlog | or a sequence thereof |
| 08:36 | tscheibl | or.. queueball |
| 08:36 | tscheibl | I'm not so jour anymore |
| 08:36 | fliebel | or clueue |
| 08:36 | tscheibl | or jeujeujeu |
| 08:37 | fliebel | Anyway, does anyone know if Clojure runs on Mono yet? |
| 08:37 | tscheibl | who needs that? |
| 08:37 | tscheibl | I mean... why the hell? |
| 08:38 | tscheibl | I can understand if you are ms fanboy you prefer to run it on the .NET CLR on an MS Platform... but Mono? |
| 08:39 | Cozey | :-) btw. sweden had and has some good music bands: http://www.youtube.com/watch?v=Aq4apgYriXE |
| 08:39 | fliebel | Well, why not? I heard they have some nice stuff on the CLR, plus MonoTouch would be cool :) |
| 08:39 | tscheibl | do they have Clojure in Sweden? |
| 08:40 | tscheibl | I've got a grey import here in Austria |
| 08:40 | tscheibl | ;) |
| 08:40 | tscheibl | MonoTouch? |
| 08:40 | tscheibl | I knoe.. goolge is ya... |
| 08:40 | tscheibl | w |
| 08:41 | fliebel | $google monotouch |
| 08:41 | sexpbot | First out of 43200 results is: Main Page - MonoTouch from Novell |
| 08:41 | sexpbot | http://monotouch.net/ |
| 08:41 | gfrlog | oh I know why everybody is European...I'm on IRC way too early |
| 08:41 | gfrlog | now it all makes sense |
| 08:42 | gfrlog | the western hemisphere is still hungover |
| 08:42 | gfrlog | $google gfrlog |
| 08:42 | sexpbot | First out of 91 results is: gfrlog: |
| 08:42 | sexpbot | http://gfredericks.com/ |
| 08:43 | gfrlog | I wonder how it is googling...the result count seems low |
| 08:51 | kencausey | Not everyone is European ;) but point taken and agreed to |
| 08:51 | gfrlog | kencausey: are you also an exception to the hungover-westerner rule? |
| 08:55 | kencausey | Yes |
| 08:55 | kencausey | hmm, actually I'm not certain what yes and no means to that question... |
| 08:56 | kencausey | I consumed no alcohol yesterday, I'm a loner geek/nerd of the first order |
| 08:56 | clojurebot | No entiendo |
| 09:31 | TimMc | gfrlog: Me too. |
| 09:43 | gfrlog | kencausey & TimMc: well good. |
| 09:43 | gfrlog | no wonder this party is so happening |
| 09:43 | TimMc | Boston, USA here. |
| 09:43 | gfrlog | That is my time zone but not my climate |
| 09:44 | gfrlog | I would love to be there though |
| 09:51 | gfrlog | isn't there a method somewhere that could go by the name 'eval-in-ns? |
| 09:51 | gfrlog | I feel like I heard of it the other day |
| 09:52 | gfrlog | $findfn 'difference clojure.set/difference |
| 09:52 | sexpbot | [] |
| 09:55 | gfrlog | and is (deref (future (expr...))) equivalent to (expr...)? |
| 09:55 | gfrlog | wondering why I used the former... |
| 09:55 | gfrlog | oh it probably has to do with agents waiting on things... |
| 10:06 | raek | gfrlog: modulo costs for thread allocation and that exceptions get wrapped in a ExecutionException, yes |
| 10:11 | eckroth | Is there some idiomatic improvement of the following: (first (filter pred coll)) ? |
| 10:13 | raek | eckroth: (some #(when (pred %) %) coll) is an alternative. when pred is =, it can be written as (some #{x} coll) |
| 10:13 | kencausey | I prefer the original myself |
| 10:14 | raek | yeah, me too in this case. but #'some can be useful sometimes. |
| 10:14 | eckroth | raek: thanks; seems like this is common enough to have something like (pick-out pred coll) |
| 10:16 | kencausey | eckroth: so add it, Lisp is all about customization |
| 10:16 | eckroth | well yeah but then I have my own special function floating around in some duplicated file for all my projects :) |
| 10:16 | eckroth | oh well |
| 10:16 | kencausey | not an unusual situation |
| 10:16 | eckroth | I suppose so |
| 10:17 | kencausey | have you check the contrib libs? |
| 10:17 | eckroth | no; will do now |
| 10:17 | kencausey | if it's not there maybe you can get it added |
| 10:19 | msappler | Hello I have a question regarding require and loading: http://pastebin.com/NRnLmzaq |
| 10:20 | raek | msappler: (:require (a.test2)) should be (:require a.test2) |
| 10:20 | eckroth | kencausey: thanks for the push to look in contrib; I found it: |
| 10:20 | eckroth | (clojure.contrib.seq/find-first pred coll) |
| 10:20 | raek | (:require foo.x foo.y foo.z) is the same as (:require (foo x y z)) |
| 10:21 | kencausey | eckroth: excellent |
| 10:21 | eckroth | kencausey: its definition: (first (filter pred coll)) |
| 10:21 | eckroth | haha |
| 10:21 | raek | so (:require (a.test2)) means "require no namspaces starting with a.test" |
| 10:22 | kencausey | :) |
| 10:22 | msappler | oh |
| 10:23 | msappler | why is this not in the require docs? |
| 10:25 | eckroth | does anybody already know of an optimization of (second (first coll))? |
| 10:26 | fliebel | eckroth: What is there to optimize? |
| 10:26 | raek | eckroth: (let [[[_ x]] coll] ...) |
| 10:26 | raek | not an optimization, but another way of writing it |
| 10:26 | eckroth | yeah, ok... I thought maybe something like CL's cadr, caadr, etc. |
| 10:27 | fliebel | there are a couple of ones named like fnext and such |
| 10:27 | eckroth | yeah |
| 10:27 | raek | I think clojure has fnext and nnext, but destructuring is used more often my gut feeling tells me |
| 10:29 | gfrlog | raek: regarding my (deref (future (expr...))) question, you would agree that it has different behavior within an agent, right? |
| 10:30 | raek | gfrlog: how? |
| 10:30 | fliebel | $findfn [[1 2] 3 4] 2 |
| 10:30 | sexpbot | [] |
| 10:30 | gfrlog | raek: I believe you cannot call (await) within an agent |
| 10:31 | gfrlog | but you can within a future that the agent derefs |
| 10:31 | gfrlog | so you can get the same behavior, but with the advantage of harder-to-understand code |
| 10:31 | raek | ah, now I see what you mean |
| 10:32 | raek | I get the feeling you are using agents for something they weren't designed for (I may be wrong, though) |
| 10:32 | gfrlog | I thought of that, and it make be the case. But what I'm doing is using clojure.contrib.http.agent for synchronous http calls |
| 10:32 | gfrlog | so it wasn't my idea to make it an agent |
| 10:33 | gfrlog | but maybe doing the synchronous http is inappropriate; that would require more thinking |
| 10:33 | raek | yeah, agents are meant to be primarily asynchronous |
| 10:33 | gfrlog | well naively I would say that I want a synchronous http library and there just aren't any |
| 10:34 | gfrlog | so I have to use clojure.contrib.agent and just wait for them |
| 10:34 | gfrlog | but there's probably a cleaner way to do what I'm doing |
| 10:35 | raek | there are a lot of other http client libs |
| 10:37 | raek | I would recommend checking them out to see if their api fits better for your usage |
| 10:39 | bobo_ | async http client? https://github.com/neotyk/http.async.client |
| 10:54 | gfrlog | ,(do (dorun (repeatedly 500 (partial agent 4))) "all those poor unused agents") |
| 10:54 | clojurebot | "all those poor unused agents" |
| 10:56 | gfrlog | I feel like the documentation for the (ns) macro might be wrong... |
| 10:56 | gfrlog | I thought this is not valid: (:require (clojure.contrib sql sql.tests)) |
| 10:57 | gfrlog | either that or the documentation for 'require is wrong: After removing the |
| 10:57 | gfrlog | prefix, the names that remain must not contain any periods. |
| 10:57 | gfrlog | or alternatively, I'm confused |
| 11:05 | gfrlog | is 'for always nicer than using 'map with an anonymous function? |
| 11:05 | pdk | the intent is clear enough with map and it's more concise |
| 11:05 | gfrlog | it is? |
| 11:05 | gfrlog | (the concise part I mean) |
| 11:06 | pdk | cf. (map anon-fn list) and (for [i list] (anon-fn i)) |
| 11:06 | gfrlog | more like (map #(do-this %) list) and (for [i list] (do-this i)) |
| 11:06 | gfrlog | I feel like the second one looks nicer |
| 11:07 | pdk | if do-this takes one argument you only need to write (map do-this list) |
| 11:07 | Sgeo | (map (partial do-this) list) |
| 11:07 | Sgeo | Oh |
| 11:07 | gfrlog | pdk: I know, but when I say "anonymous function" I'm specifically ruling that out |
| 11:07 | gfrlog | I agree map is nicer when you can just pass a function |
| 11:08 | gfrlog | assuming that that map alternative involves typing #(...) or (fn [_] ...) |
| 11:08 | gfrlog | both of which seem clunkier |
| 11:08 | pdk | in that case i guess for would be fine |
| 11:10 | gfrlog | ,(map for list) |
| 11:10 | clojurebot | java.lang.Exception: Can't take value of a macro: #'clojure.core/for |
| 12:12 | sritchie_ | hey all -- is there a way to bind a vector of all arguments to defn to a variable? |
| 12:12 | sritchie_ | like -- (defn read-test [datasets resolutions tiles :as args] ... ) |
| 12:12 | sritchie_ | I'm not destructuring, I just want to apply a function to all of these arguments |
| 12:17 | spewn | sritchie_: As in (defn foo [& bar] (apply str bar)) ? |
| 12:17 | sritchie_ | spewn: yeah, that's true... I just wanted to make it clear what the arguments should be |
| 12:18 | TimMc | You want individual names and also a name for the whole list? |
| 12:18 | sritchie_ | TimMc: yeah, exactly. I think I need to think more about these functions, but I was just curious about that possibility |
| 12:19 | Sgeo | (defn foo [a b c] (let [args [a b c] (apply str args))) ;Note: Don't trust anything I write, I'm somewhat new |
| 12:20 | sritchie_ | Sgeo: no, that works, that's good |
| 12:21 | TimMc | sritchie_: OK, here we go |
| 12:21 | TimMc | ,((fn [& [a b :as e]] [a b e]) 1 2 3) |
| 12:21 | clojurebot | [1 2 (1 2 3)] |
| 12:21 | Sgeo | Maybe I'll try Clojure Box |
| 12:21 | TimMc | Note that there is nothing forcing the correct number of arguments. |
| 12:22 | TimMc | Sgeo: Your example would be better done as (defn foo [a b c] (str a b c)) |
| 12:22 | sritchie_ | TimMc: noted -- that makes sense, though, since the :as clause I was thinking about is found in destructuring |
| 12:22 | sritchie_ | so we just destructure the variadic arguments |
| 12:22 | TimMc | sritchie_: It still may not be what you want. |
| 12:23 | sritchie_ | Sgeo: I'm currently using TimMc's method, of just feeding them through into the next function |
| 12:23 | sritchie_ | Sgeo: I was curious about shorthand |
| 12:23 | TimMc | ,((fn [& [a b :as e]] [a b e]) 1) |
| 12:23 | clojurebot | [1 nil (1)] |
| 12:28 | _2x2l | http://pastie.org/1610288 does anyone know why lein is throwing that error? seems like the syntax should be right according to the github docs. |
| 12:29 | Sgeo | Yay Clojure Box1 |
| 12:36 | Sgeo | Emacs seems to have some weirdities with [] |
| 12:36 | Sgeo | I mean I guess that's to be expected |
| 12:36 | Sgeo | But still |
| 12:39 | TimMc | Sgeo: I haven't experienced any weirdness with that. |
| 12:39 | Sgeo | Typing ] doesn't show the other [ |
| 12:39 | Sgeo | And it indents weirdly |
| 12:39 | TimMc | You're probably not in the right modes. |
| 12:40 | Sgeo | http://ideone.com/M96Yh |
| 12:40 | Sgeo | I'd expect that println to be further to the left |
| 12:41 | TimMc | Right. You're probably not in the right modes. |
| 12:41 | TimMc | I get the expected behavior in Clojure + Paredit + hl-p |
| 12:43 | Sgeo | This thing came with paredit but it's not enabled by default |
| 12:43 | Sgeo | What's hl-p? |
| 12:44 | bennylut | what am i doing wrong? ^(with-meta '(1) {:x 5}) => #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata must be Symbol,Keyword,String or Map> |
| 12:44 | TimMc | Sgeo: highlight-parentheses-mode |
| 12:45 | TimMc | ,(with-meta '(1) {:x 5}) |
| 12:45 | clojurebot | (1) |
| 12:45 | TimMc | bennylut: Drop the initial caret. |
| 12:46 | bennylut | TimMC: i want to receive the metadata |
| 12:46 | bennylut | when i wrote ^(with-meta '(1) {:x 5}) i wanted to get (meta (with-meta '(1) {:x 5})) |
| 12:46 | TimMc | ,(meta (with-meta '(1) {:x 5})) |
| 12:47 | clojurebot | {:x 5} |
| 12:47 | TimMc | I don't think ^ does that. |
| 12:47 | bennylut | i see, i have read that writing ^x means (meta x) am i wrong? |
| 12:47 | bennylut | ok, thanks! |
| 12:48 | TimMc | bennylut: ^String foo means (with-meta foo {:tag String}) |
| 12:49 | TimMc | and ^{:a :b} foo gives you (with-meta foo {:a :b}) |
| 12:49 | bennylut | hmm.. i see, thanks |
| 12:52 | bennylut | TimMc: but see that- (def my ^String y) (meta my) => {:line 9} why? |
| 12:54 | bennylut | where y is : (def y '(1)) |
| 12:54 | TimMc | Hmmm. This is where vars start to complicate things and I am out of my depth. |
| 12:55 | TimMc | ,(meta ^String (list 3)) |
| 12:55 | clojurebot | nil |
| 12:55 | TimMc | OK, ignore the bit I said about :tag, then. |
| 12:56 | bennylut | see that: (meta #'my) => {:tag String} |
| 12:56 | TimMc | All I'm sure of is that ^ is for associating metadata, not for reading it. |
| 12:57 | bennylut | ok i think that i will use the full methods for metadata cause the reader macros seem to be little awkword |
| 12:59 | TimMc | What we're dealing with here is the difference between metadata on a var and metadata on a value. |
| 13:01 | bennylut | so ^String x will put metadata on the var and (with-meta {:tag String} x) will put metadata on the value? if so in order to give the compiler a type hint what should i use ? |
| 13:05 | TimMc | ,(do (set! *warn-on-reflection* true) |
| 13:05 | clojurebot | EOF while reading |
| 13:05 | TimMc | bah |
| 13:05 | TimMc | ,(do (set! *warn-on-reflection* true) (let [x "foo"] (.length ^String x))) |
| 13:05 | clojurebot | java.lang.IllegalStateException: Can't change/establish root binding of: *warn-on-reflection* with set |
| 13:05 | TimMc | OK, let me play with my own REPL for a sec. |
| 13:08 | TimMc | bennylut: Anyway, (set! *warn-on-reflection* true) in your REPL and then try (.length (identity "foo")). |
| 13:08 | TimMc | This will give you a baseline for determining that hinting might be useful. |
| 13:09 | TimMc | identity here serves to strip any knowledge that the argument to .length is a String. |
| 13:09 | TimMc | Then try different approaches: (.length ^String (identity "foo")) |
| 13:15 | bennylut | TimMc: thanks i will check it and post here |
| 13:15 | TimMc | bennylut: It's the ^String approach, btw. |
| 13:16 | TimMc | ,(with-meta (identity "foo")) |
| 13:16 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$with-meta |
| 13:16 | TimMc | ,(with-meta (identity "foo") {:tag String}) |
| 13:16 | clojurebot | java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IObj |
| 13:17 | TimMc | You can't put Clojure metadata on most Java objects, including strings. |
| 13:17 | TimMc | That is, (with-meta ...) won't work with most Java values. |
| 13:18 | bennylut | i see, so this is why you must put the metadata on the var - so that the compiler will be able to search metadata on static location :) |
| 13:19 | TimMc | Something like that. I don't understand it myself yet. |
| 14:11 | DespiteItAll | Hmmm, (Boolean. false) is true |
| 14:15 | TimMc | ,(Boolean. false) |
| 14:15 | clojurebot | false |
| 14:15 | DespiteItAll | ,(if (Boolean. false) "true" "false") |
| 14:15 | clojurebot | "true" |
| 14:15 | TimMc | Oh, I see. |
| 14:15 | TimMc | Yeah. |
| 14:15 | DespiteItAll | I thought clojure false was the same as java's false |
| 14:16 | TimMc | ,(if false "true" "false") |
| 14:16 | clojurebot | "false" |
| 14:16 | Lulu58e2 | Isn't anything not nil or false is true? (or something) |
| 14:16 | TimMc | It is. |
| 14:16 | DespiteItAll | ,(class false) |
| 14:16 | clojurebot | java.lang.Boolean |
| 14:16 | DespiteItAll | Hmmmm |
| 14:16 | TimMc | DespiteItAll: (Boolean. ...) is an object, which is always true. |
| 14:16 | danlarkin | clojure's false is Boolean/FALSE |
| 14:17 | Lulu58e2 | Not same instance though? |
| 14:17 | DespiteItAll | Ahh, got it |
| 14:17 | DespiteItAll | I know no java so the distinction is lost on me, but I see that there is one |
| 14:17 | Lulu58e2 | I'm not 100% sure, I'm just guessing |
| 14:18 | TimMc | (class) might auto-box the input |
| 14:18 | TimMc | So, false -> (Boolean. false) |
| 14:18 | Lulu58e2 | ,(hash (Boolean. false)) |
| 14:18 | clojurebot | 1237 |
| 14:19 | Lulu58e2 | ,(hash false) |
| 14:19 | clojurebot | 1237 |
| 14:19 | Lulu58e2 | Hmmm |
| 14:19 | DespiteItAll | So, (Boolean. false) is the same as (Boolean. Boolean/FALSE) |
| 14:19 | DespiteItAll | whatever that means |
| 14:19 | TimMc | ,(identical? false (Boolean/FALSE)) |
| 14:19 | clojurebot | true |
| 14:19 | TimMc | ,(identical? false (Boolean. false)) |
| 14:19 | clojurebot | false |
| 14:20 | TimMc | ,(identical? (Boolean. false) (Boolean. false)) |
| 14:20 | clojurebot | false |
| 14:20 | mrBliss | ,(if (Boolean. false) "true" "false") |
| 14:20 | clojurebot | "true" |
| 14:20 | TimMc | The hash does not tell you about identity. |
| 14:20 | Lulu58e2 | lol |
| 14:20 | mrBliss | (if (boolean false) "true" "false") |
| 14:20 | Lulu58e2 | Ah, I thought each instance had a unique hash |
| 14:21 | TimMc | Nope. |
| 14:21 | mrBliss | (Boolean. false) is evil, use boolean ##(map boolean [false nil 1 () true]) |
| 14:21 | mrBliss | ,(map boolean [false nil 1 () true]) |
| 14:21 | clojurebot | (false false true true true) |
| 14:23 | TimMc | ,(type false) |
| 14:23 | clojurebot | java.lang.Boolean |
| 14:23 | TimMc | hrm |
| 14:23 | TimMc | Still auto-boxing. :-) |
| 14:58 | amalloy | &(.getComponentClass (class (into-array [false]))) |
| 14:58 | zippy314 | Hi folks, I'm using emacs and lein swank for my REPL. I'd love to have all my files compiled at load time rather than having to C-c C-k each one. Anybody know a shortcut for this? |
| 14:58 | sexpbot | java.lang.IllegalArgumentException: No matching field found: getComponentClass for class java.lang.Class |
| 14:59 | amalloy | &(.getComponentType (class (into-array [false]))) |
| 14:59 | sexpbot | ⟹ java.lang.Boolean |
| 15:00 | amalloy | zippy314: C-c C-k is transitive. if you compile your "main" file that depends on all the others, they all get compiled |
| 15:00 | zippy314 | Cool. Thanks. |
| 15:07 | jk_ | if i remove a namespace with remove-ns, what happens to the vars that were mapped into that namespace? are they garbage collected? if not, how do you access them? |
| 15:10 | amalloy | jk_: looks to me like they get GCed |
| 15:12 | amalloy | try this entertaining experiment: (in-ns 'tmp) (def x 1) (in-ns 'user) (def h #'tmp/x) (remove-ns 'tmp) @h |
| 15:13 | amalloy | yields 1 because h is keeping a reference to the defunct var, but if you redef h, there's no longer any way to get at it |
| 15:18 | Null-A | lol amalloy |
| 15:24 | jk_ | amalloy: yes that makes sense because you simply grabbed a reference to it before you trashed the namespace map. i was basically wondering if there is anything internally that keeps a reference or whether it gets garbage collected |
| 15:24 | amalloy | i don't think so |
| 15:25 | jk_ | i was basically wanting to know whether i could blow away stuff in a long-running repl simply by removing namespaces without having a memory leak |
| 15:25 | amalloy | should be fine |
| 15:25 | jk_ | thanks, amalloy |
| 15:35 | rikva | Beginners question: Is it possible to use multiple lines of code within a if form? Or is that not the Clojure way? |
| 15:36 | no_mind | rikva: if you are looking for executing multiple lines inside braces like non-functional programing languages, then I think it is not possible |
| 15:36 | amalloy | whoa slow down |
| 15:36 | no_mind | but I am no clojure master :) |
| 15:37 | amalloy | rikva: it is possible, and also it is not the clojure way :) |
| 15:37 | rikva | then, what is the clojure way? :) |
| 15:37 | rikva | moving the code to a new function? |
| 15:38 | amalloy | rikva: code without side effects when possible. if you think about it, you only want a "multi-line" if statement when the first few expressions have side effects |
| 15:38 | amalloy | if you are aware of that, and side effects are the right solution to your problem, clojure lets you do it: ##(if false 10 (do (println 1) (println 2))) |
| 15:38 | sexpbot | ⟹ 1 2 nil |
| 15:40 | amalloy | if you only have one branch in your if (ie no else), there's shorthand for the if/do combo: ##(when true (println 1) (println 2)) |
| 15:40 | sexpbot | ⟹ 1 2 nil |
| 15:40 | amalloy | rikva: making any sense yet? |
| 15:41 | rikva | yes, you are making perfect sense. I'll try it the Clojure way ;) |
| 15:45 | Null-A | rikva: (when true (println) (println) ..) |
| 15:45 | Null-A | er already explained |
| 16:03 | amalloy | Null-A: but you included the ... that i was missing :) |
| 16:03 | Null-A | heh |
| 16:03 | gfrlog | best way to check if I have a list or vector? |
| 16:05 | gfrlog | am handling source code |
| 16:08 | Guest22761 | gfrlog: (list? x) (vector? x) ? |
| 16:10 | dsantiago | It seems like clojure.core/name will cause a null pointer exception when it is passed nil. Why wouldn't it just return nil? |
| 16:13 | Guest22761 | dsantiago: that seems like a reasonable thing to do if you don't pass it an actual clojure.lang.Named |
| 16:13 | Guest22761 | dsantiago: return nil, i mean. |
| 16:14 | dsantiago | Yeah. Most other functions seem to cope very nicely with nil. I am just wondering if it is a bug or if it's deprecated or there's a good reason for that or what. |
| 16:14 | dsantiago | Can't imagine why you'd want the NPE, epecially when so many other clojure functions cope with nils as if they are empty objects of the type they are interested in. |
| 16:15 | TimMc | I can't say I'm too pleased with nil propagation as an idiom. |
| 16:16 | TimMc | Makes it hard to know where the logic bug actually occurred. |
| 16:17 | dsantiago | But it's not really a logic bug if nil means "the empty list" or something like that. |
| 16:18 | Guest22761 | i like the idea of (name) basically telling you tehre is no name |
| 16:18 | Guest22761 | without just blowing up :) |
| 16:21 | TimMc | Nil as empty seq (and nil propagation) are problematic for fail-fast programming. |
| 16:21 | amalloy | gfrlog: don't use list? for source code. seq? is better |
| 16:21 | amalloy | macros expand into seqs, not lists |
| 16:22 | dsantiago | amalloy: Is seq? better than sequential? seq? returns true on a map, but sequential? doesn't. |
| 16:22 | Guest22761 | amalloy: but that's not telling you that it's a list or vector, right? |
| 16:22 | amalloy | &((juxt seq? sequential?) {}) |
| 16:22 | sexpbot | ⟹ [false false] |
| 16:23 | amalloy | &(map (juxt list? seq? sequential?) [() [] {} (range 0)]) |
| 16:23 | sexpbot | ⟹ ([true true true] [false false true] [false false false] [false true true]) |
| 16:24 | amalloy | note that seq? returns true for the list and the lazy-seq, but not for the vector or the map. sounds like what gfrlog was asking for |
| 16:25 | Guest22761 | ok, if it's exclusively one or the other than you have then that's fine |
| 16:25 | Guest22761 | s/than you/that you/ |
| 16:25 | sexpbot | <Guest22761> ok, if it's exclusively one or the other that you have then that's fine |
| 16:26 | dsantiago | Weirdly mixed up about that. |
| 16:26 | amalloy | Guest22761: if you need to distinguish scheme-style "atoms" from "listy things", you have coll? |
| 16:26 | dsantiago | I ran into that same question like 3 days ago, apparently I alredy forgot everything about the differences. |
| 16:30 | Sgeo | Maybe I should translate one of my few Haskell programs to Clojure... |
| 16:32 | gfrlog | ,(seq? (read-string "(+ 3 4)")) |
| 16:32 | clojurebot | true |
| 16:33 | gfrlog | ,(seq? (read-string "[+ 3 4]")) |
| 16:33 | clojurebot | false |
| 16:33 | gfrlog | amalloy: seq? misses vectors |
| 16:33 | gfrlog | guess I gotta go with (or (seq? ..) (vector ..)) |
| 16:33 | amalloy | gfrlog: it sounded like you wanted to tell seqs and vectors apart, not lump them together |
| 16:34 | gfrlog | amalloy: sorryo, no |
| 16:34 | amalloy | see my juxty thing earlier. you want sequential? |
| 16:34 | gfrlog | wanted to distingush them from other things |
| 16:34 | gfrlog | ,(sequential? "hoo ha") |
| 16:34 | clojurebot | false |
| 16:34 | gfrlog | nice |
| 16:35 | gfrlog | ,(map sequential? [[] () (read-string "(+ 3 4)") "okay" :nope 'yeah]) |
| 16:35 | clojurebot | (true true true false false false) |
| 16:35 | gfrlog | that is exactly what I wanted |
| 16:35 | gfrlog | thx amalloy |
| 16:35 | amalloy | gfrlog: what's with the read-strings, anyway? '(+ 3 4) seems easier |
| 16:36 | amalloy | hm. i wonder. ##(sequential? (sorted-set [])) |
| 16:36 | sexpbot | ⟹ false |
| 16:37 | gfrlog | amalloy: strings aren't available till runtime |
| 16:37 | gfrlog | my strings I mean; wasn't saying something bizarre about strings gin general |
| 16:37 | amalloy | lol |
| 16:38 | gfrlog | I'm doing all kinds of disgusting crap with these strings, like doing gsubs with namespace names... |
| 16:38 | rikva | i'm doing a small test with recursion but I can't seem to figure it out. Can someone tell me what's wrong with this? http://pastebin.com/JZM3tSUv |
| 16:38 | Sgeo | Once Clojure-in-Clojure is completed, will Clojure be ported to bare metal? |
| 16:39 | gfrlog | amalloy: I wrote my own parser for the (ns) sub-language |
| 16:39 | amalloy | rikva: the a needs to be inside the if |
| 16:39 | gfrlog | just shake your head slowly |
| 16:39 | amalloy | gfrlog: is there a reason not to just steal it from clojure.core source? |
| 16:40 | gfrlog | amalloy: I seriously doubt it. Do you know how that works? i.e., what it parses to? |
| 16:40 | gfrlog | I know it initially goes to (require ...) and (use ...) |
| 16:41 | gfrlog | I did look at the source some |
| 16:41 | gfrlog | what I ended up with wasn't too long... |
| 16:41 | fliebel | gfrlog: I'd try macroexpand-all combined with the lisp reader. |
| 16:42 | gfrlog | fliebel: the (ns) macro only transforms to direct calls to require and use |
| 16:43 | gfrlog | doesn't manipulate the arguments at all |
| 16:43 | gfrlog | I guess there might be more macros underneath... |
| 16:43 | fliebel | (do (clojure.core/in-ns (quote test)) ((fn* loading__4410__auto__ ([] (. clojure.lang.Var (clojure.core/pushThreadBindings {clojure.lang.Compiler/LOADER (. (. loading__4410__auto__ getClass) getClassLoader)})) (try (clojure.core/refer (quote clojure.core)) (clojure.core/use (quote clojure.set)) (finally (. clojure.lang.Var (clojure.core/popThreadBindings)))))))) |
| 16:44 | rikva | amalloy: in what way? |
| 16:44 | amalloy | (if (> n 1) (test ...) a) |
| 16:44 | gfrlog | fliebel: heck that probably works |
| 16:44 | gfrlog | thanks |
| 16:45 | fliebel | gfrlog: (macroexpand-all (read-string "(ns test (:use clojure.set))")) |
| 16:45 | rikva | amalloy: ah wow. Thanks a lot! |
| 16:46 | fliebel | gfrlog: What are you trying to achieve? |
| 16:46 | amalloy | also rikva, i realize you have a lot on your plate learning a new way of thinking, so feel free to put this off as long as you like, but as a matter of style you don't want ) on their own line. just stack up a load of them in sequence on one line. doing that will also help you stop thinking of (if) as a control-flow statement/block and more as a conditional expression |
| 16:47 | gfrlog | fliebel: I'm trying to have several versions of a library loaded at the same time, by transforming the namespace names |
| 16:47 | fliebel | amalloy: Good point, I still tend to think of functions and for loops as blocks, while they work perfecly inline. |
| 16:47 | gfrlog | so the prefix syntax for (require) and (use) cause a problem for naive string substitution |
| 16:49 | amalloy | fliebel: yeah, the number of times i've changed (if foo (myfn a b c d) (myfn a b waffle d)) to (myfn a b (if foo c waffle) d) is surprising |
| 16:50 | gfrlog | mmm, waffles... |
| 16:50 | amalloy | gfrlog: all my code needs more waffles |
| 16:50 | gfrlog | amalloy: lolwaffle.com |
| 16:51 | fliebel | amalloy: Hava you read any of those schemer books? they contain a ot of food code. Much better than foo/bar/baz |
| 16:51 | amalloy | fliebel: i haven't. i'd like to, but not badly enough to put them in front of all the other reading i'm not doing :P |
| 16:52 | fliebel | hm, I forgot to mention the food in my blogpost about it :( |
| 16:54 | _2x2l | is there a way to get meta-point to work in emacs with clojure, i.e., to auto-manipulate the jar? |
| 16:55 | amalloy | _2x2l: it already does work for moving from your source to the library function you use. if you find a way to make it move from one jarred library to another i'll be delighted |
| 16:56 | dsantiago | I can't find any docs on what the {:static true} metadata means... |
| 16:56 | amalloy | dsantiago: not rebindable |
| 16:56 | amalloy | in 1.3 it's being replaced by {:dynamic true} as the default changes from rebindable to not rebindable |
| 16:56 | dsantiago | amalloy Ah, OK, is this related to the new semantics for varS? |
| 16:56 | dsantiago | I see. |
| 16:58 | rikva | amalloy: thanks! |
| 17:10 | arohner | I've got a question. I'm looking for something vaguely hadoop-like, but I'm not exactly sure Hadoop is the right tool for the job. I've got a clojure function that takes a big, nested map (hundreds of thousands of keys), and iterates over a set of possible outcomes, and scores each one. Is hadoop the right tool for parallelizing that on a cluster? |
| 17:12 | amalloy | arohner: it doesn't sound like the *wrong* tool, at least. it might depend on what a "set of possible outcomes" is. are you basically processing all the possible ways to walk from the root to any leaf, or something? |
| 17:13 | arohner | amalloy: I'm building a DAG from the input dataset, and then scoring each DAG. Then I want to return the DAG with the highest score |
| 17:14 | arohner | or rather, building all possible DAGs from the input dataset, and scoring them |
| 17:17 | amalloy | hm. in that case it's not really clear to me how to partition the task into independent maps and reduces. every DAG will need to work with the whole dataset, you'll just be passing a different parameter like "build DAGs 1024-2047 out of this" |
| 17:18 | amalloy | which sounds like you'll need to subvert a lot of hadoop's intended use-cases. sadly i don't really know a better tool for the job, myself |
| 17:21 | arohner | amalloy: right, that was my concern. I think I can make it work, just wanted to make sure I wasn't forgetting about something |
| 17:21 | amalloy | arohner: undoubtedly you are forgetting about something, but i don't know what it is either :) |
| 17:52 | Null-A | arohner: cascalog |
| 18:09 | _2x2l | is there a way to print locals via attaching to a running instance of swank? |
| 18:13 | amalloy | _2x2l: check out george jahad's clojure debugging toolkit |
| 18:45 | DespiteItAll | hahaha, i wrote a maze generator that kicks out an svg file. Kept making bigger and bigger mazes to see how firefox would take it. It completely froze up on a 250x250 grid |
| 18:46 | DespiteItAll | and the file is 5.5MB |
| 18:54 | joshua__ | Would it be accurate to say that most functions we work with are multivariate functions? |
| 18:54 | arohner | man, lein uberjar is *slow* |
| 18:55 | arohner | joshua__: as in most functions take more than one variable? |
| 18:55 | joshua__ | arohner, basically yea |
| 19:07 | amalloy | joshua__: probably, but bug brehaut and he'll tell you about currying to turn everything into one-argument functions |
| 19:50 | amalloy | in (reduce (fn [a b] (...do stuff...)) coll), is there a "name" for the anonymous function? i'm calling it the "reductor" to avoid having to write "anonymous reduction function" over and over, but if there's a standard name i'd like to use it |
| 20:45 | TimMc | amalloy: "f" :-P |
| 20:49 | TimMc | amalloy: Anyway, are you writing documentation, or an instruction manual, or a blog post or what? |
| 20:49 | amalloy | TimMc: blog |
| 20:50 | TimMc | In that case, you'll be able to change it easily if you find a better name. |
| 20:51 | amalloy | TimMc: sure |
| 20:51 | TimMc | Why does it matter that the function is anonymous? |
| 20:51 | TimMc | Or is it just part of that example? |
| 20:51 | amalloy | TimMc: it doesn't, i suppose. you're suggesting i could write (reduce (fn some-name [a b] ...))? |
| 20:52 | TimMc | Most of the reduce expressions I've written have used a def'd function from elsewhere. |
| 20:52 | amalloy | the function can't be a top-level def, because i need it closing around some stuff |
| 20:52 | TimMc | That probably means I'm not using reduce enough. >_< |
| 20:52 | TimMc | ah |
| 20:55 | amalloy | anyway TimMc i'm done with the text now, just need to do some linking and tidying |
| 21:45 | sritchie_ | hey all, quick question about a function I'm writing to generate timeseries |
| 21:45 | sritchie_ | I've got something that I think is pretty clean, but I'm worried that it's inefficient -- I map across the data three times |
| 21:45 | sritchie_ | https://gist.github.com/845855 |
| 21:47 | sritchie_ | would it be better to sacrifice the second transpose call, and bring it up to the map-indexed step level? |
| 21:52 | amalloy | whew, TimMc, writing is so time-consuming. my blog post with an over-the-shoulder view of what I'm thinking as I refine a #clojure function: http://hubpages.com/t/21754f |
| 22:25 | TimMc | hah, cool |
| 22:25 | TimMc | Interesting point about application logic vs. bookkeeping code. |
| 22:25 | amalloy | TimMc: not my original idea, though. i found it in a 1969ish paper about why functional programming is the hot new thing |
| 22:26 | TimMc | :-) |
| 22:28 | amalloy | TimMc: found it! http://www.stanford.edu/class/cs242/readings/backus.pdf |
| 22:28 | clojurebot | #<RuntimeException java.lang.RuntimeException: java.lang.Exception: 503> |
| 22:30 | TimMc | Thanks! |
| 22:30 | amalloy | 5.1 was the section i was thinking of when i wrote that section |
| 22:31 | amalloy | hiredman: clojurebot has been doing a lot of barfing when some (but not all) URLs are pasted into the channel. any idea why? |
| 22:33 | TimMc | http://www.stanford.edu/class/cs242/readings/ |
| 22:33 | TimMc | Didn't barf there. |
| 22:34 | TimMc | http://www.stanford.edu/class/cs242/readings/backus.pdf |
| 22:34 | Sgeo | TimMc: found it! http://www.stanford.edu/class/cs242/readings/backus.pdf |
| 22:35 | TimMc | It sure looks like a 503 Service Unavailable, which would be a transient error if that's what's really going on. |
| 22:35 | Sgeo | No barfing? |
| 22:35 | TimMc | We need to find a page that always returns a 503 error. :-) |
| 22:36 | Sgeo | I know of one! |
| 22:36 | TimMc | Could certainly just write one. |
| 22:36 | Sgeo | Or, actually, I don't know if it really does it or just displays the custom page for the error that the person put up |
| 22:36 | Sgeo | http://zzo38computer.cjb.net/errors/error.php?code=503 |
| 22:37 | amalloy | Sgeo: it's an actual 503 |
| 22:37 | TimMc | It really does give a 503, but clojurebot didn't... |
| 22:37 | TimMc | Yeah. |
| 22:37 | amalloy | wow Sgeo that's an old page. php 4.4.0 |
| 22:38 | Sgeo | The person behind that site is a bit.. strange |
| 22:38 | amalloy | and apache on windows, i see |
| 22:38 | amalloy | which seems like a weird combo, but who am i to judge |
| 22:38 | TimMc | Man, that's great! I can get an HTTP 493 error on command! |
| 22:38 | TimMc | No wait, it's a 500. Drat. |
| 22:38 | Sgeo | He wrote a custom IRC client where he types in the PRIVMSG command, iirc |
| 22:38 | Sgeo | erm, MSG? |
| 22:39 | Sgeo | I forget the IRC protocol now |
| 22:40 | sritchie_ | more specific question, for anyone interested, about the timeseries question -- https://gist.github.com/845855 -- why is my second version of timeseries lazy? |
| 22:43 | amalloy | sritchie_: could you clarify? the simple answer is because map-indexed is lazy and it's your final result, but i don't think that's what you're looking for |
| 22:44 | sritchie_ | amalloy: sure, sorry about that. I was testing these with (partial nth (timeseries test)), and found that the second version could return an answer immediately, while the first version had to process everything before returning first |
| 22:44 | sritchie_ | s/first/ |
| 22:44 | sexpbot | <sritchie_> amalloy: sure, sorry about that. I was testing these with (partial nth (timeseries test)), and found that the second version could return an answer immediately, while the version had to process everything before returning |
| 22:45 | sritchie_ | amalloy: oh, I see. my transpose method had a wrapping call to vec. |
| 22:45 | amalloy | right |
| 22:46 | sritchie_ | amalloy: I'm finding that the second version is about 20% faster |
| 22:46 | amalloy | interesting. i wonder why |
| 22:47 | amalloy | memory usage, maybe? having to alloc a huge block of memory and not free any of it until you've processed all of it may be slowing things down somewhere |
| 22:48 | sritchie_ | amalloy: even when I take that wrapping call to vec out, it retains the advantage |
| 22:48 | sritchie_ | Here's how I'm doing my micro-benchmark -- (time (dotimes [n 10] (count (timeseries tester)))) |
| 22:48 | sritchie_ | test-chunks, rather, as defined in the gist |
| 22:49 | amalloy | $source cons |
| 22:49 | sexpbot | cons is http://is.gd/nKzkPw |
| 22:49 | sritchie_ | I get about 24 seconds for the first version, 20 for the second |
| 22:49 | sritchie_ | over multiple runs |
| 22:49 | amalloy | i'm thinking your map-indexed call may be lazily consing onto a list without computing the whole list? |
| 22:49 | amalloy | but i dunno |
| 22:51 | sritchie_ | this is for a hadoop job, so the faster one wins, but the first one describes more clearly what's going on |
| 22:51 | sritchie_ | interesting stuff |
| 22:53 | amalloy | i think it's because the #(vector ...) form has to make a four-element vector, while the second one is consing a single number to the front of a two-element vector |
| 22:54 | amalloy | so the first version requires reconstituting a whole new structure out of four elements, while the first just adds one element to a structure that reuses existing data |
| 22:56 | amalloy | but take that with a grain of salt because i barely understand what you're doing and generally don't deal with the nitty-gritty of performance |
| 22:57 | amalloy | sritchie_: ^, and afk for a bit |
| 22:57 | sritchie_ | amalloy: no problem, thanks for looking at this! I'm going to goof around with changing the arguments to vector, and see if I can figure it out |
| 22:57 | sritchie_ | amalloy: that seems like a good approach to thinking about it, though |
| 23:15 | jcromartie | is there any solution to printing/reading defrecords? |
| 23:16 | amalloy | jcromartie: i think defrecord2 does it for you, and i've seen a couple other solutions on the mailing list. that said, the easiest solution is often to use maps instead of records |
| 23:16 | jcromartie | amalloy: you mean to convert to/from maps? |
| 23:17 | jcromartie | maybe have a :_recordname key or something |
| 23:17 | amalloy | jcromartie: that's a possibility |
| 23:17 | talios | You could just seralize to yaml/json etc. |
| 23:18 | amalloy | talios: why? serializing to a map will be at least as easy and we're in a lisp |
| 23:19 | talios | for the "print" side of things. |
| 23:19 | amalloy | talios: (print (into {} my-record-object)) |
| 23:19 | jcromartie | yeah that's easy enough... now go the other way :P |
| 23:19 | amalloy | jcromartie: but serializing to json won't make the other direction any easier |
| 23:20 | jcromartie | I wouldn't go to JSON |
| 23:20 | jcromartie | the constructor is the problem |
| 23:20 | jcromartie | there's no empty constructor |
| 23:20 | jcromartie | is there any function that returns the arity of a constructor? |
| 23:20 | amalloy | jcromartie: i assume the set of record types is limited? |
| 23:20 | jcromartie | yeah I mean it could just be handled in logic |
| 23:22 | amalloy | (defmulti build-a-record :_type) (defmethod build-a-record ::person [{:keys [name age]}] (Person. name age))? |
| 23:23 | jcromartie | not bad |
| 23:23 | amalloy | then (build-a-record {:type ::person :name "dave" :age 30}) should work |
| 23:23 | jcromartie | better than what I just came up with :P |
| 23:23 | jcromartie | (defn read-car [s] (let [c (Car. nil nil nil) m (read-string s)] (merge c m))) |
| 23:23 | jcromartie | (defrecord Car [year make model]) |
| 23:24 | sattvik | sritchie_: The reason is simple: Vector only creates vectors of up to 4 elements. With more than 4 elements, it uses a lazy vector to provide the rest. |
| 23:24 | jcromartie | but what I was thinking was, if you know the arity of the constructor for the record type you can just call that and merge the map |
| 23:24 | amalloy | somewhere i have a def-record-with-constructor macro that creates a make-myobj function |
| 23:25 | amalloy | but defrecord2 surely does a better job of it than i did |
| 23:25 | sritchie_ | sattvik: but my first function doesn't use more than 4 |
| 23:25 | sritchie_ | sattvik: it uses four |
| 23:25 | jcromartie | yeah defrecord2 looks good |
| 23:25 | jcromartie | it should become defrecord at some point |
| 23:25 | amalloy | sattvik: also what you said is false in every way i can think of. vectors are not at all lazy |
| 23:26 | sattvik | $source vector |
| 23:26 | sexpbot | vector is http://is.gd/rHjtsJ |
| 23:27 | sattvik | For more than four args: ([a b c d & args] (. clojure.lang.LazilyPersistentVector (create (cons a (cons b (cons c (cons d args)))))))) |
| 23:28 | amalloy | sattvik: and have you looked at the source of LazilyPersistentVector()? it's just passing a lazy sequence of arguments to the actual java function that eagerly creates a vector |
| 23:30 | jcromartie | well I can get the arity of a record constructor |
| 23:31 | jcromartie | (count (.getParameterTypes (first (.getDeclaredConstructors klass)))) |
| 23:31 | jcromartie | easy enough |
| 23:31 | jcromartie | and apply the constructor with the right number of nil args |
| 23:31 | sattvik | amalloy: Now that I look at it in detail, you are right. |
| 23:31 | jcromartie | so it's slow |
| 23:31 | sattvik | My mistake. |
| 23:31 | jcromartie | but it works for generic printing and reading of records |
| 23:31 | jcromartie | yay |
| 23:32 | amalloy | jcromartie: record classes have two constructors. are you *sure* the right one will always be first? i guess it doesn't matter though |
| 23:32 | amalloy | since you're just giving nil args |
| 23:32 | jcromartie | yeah |
| 23:33 | amalloy | why are you using records to begin with? |
| 23:35 | sritchie_ | amalloy, sattvik: the only difference between the two is the place where I apply the vector operation |
| 23:36 | sritchie_ | I think it's slower when map-indexed does the job, than when I put it inside map |
| 23:36 | jcromartie | amalloy: why? I dunno, I am just getting into protocols and records |
| 23:36 | jcromartie | and this is something interesting |
| 23:36 | sritchie_ | but that's handwaving, I don't know the source well enough to back that up with any real reason |
| 23:37 | amalloy | i mean, this is causing you great pain, so if you're not desperate for performance you can just use hashmaps |
| 23:38 | amalloy | (even if you are desperate for performance, verify that this is the bottleneck) |
| 23:39 | jcromartie | yeah I'm not there yet :) |
| 23:40 | jcromartie | hash-maps and multimethods would probably be fine |
| 23:40 | jcromartie | it's just a data access layer |
| 23:40 | jcromartie | basically an interface to a nasty ol' database |
| 23:40 | jcromartie | 10 years old |
| 23:40 | jcromartie | no design |
| 23:40 | jcromartie | built mostly in MS Access |
| 23:40 | jcromartie | and most of our apps are bolted directly to the database (or at the most through stored procedures) |
| 23:41 | amalloy | oh, the irony: clojure 1.2, powered by ms access |
| 23:41 | jcromartie | so the goal is to design a "nice" library to access it, and protocols are a good fit because we have lots of methods on various types, and we eventually want to switch the implementation when the interface is solid and there are no apps using the DB directly |
| 23:42 | jcromartie | and a RESTful API on top of that for web apps and such |
| 23:42 | jcromartie | anyway that's my plan |
| 23:42 | amalloy | jcromartie: because calling protocol functions looks just like calling regular functions (or indeed multimethods), you can start simple and bolt on protocols later if it becomes necessary |
| 23:43 | amalloy | no need to change the client api |
| 23:43 | jcromartie | good point |
| 23:44 | amalloy | i succumbed to records in my first clojure program because i was so used to thinking of things as objects and classes. didn't even have protocols for them |
| 23:44 | jcromartie | man I hate OOP for building stuff like this... it's like Clojure makes it so simple that it's not obvious after doing things the OOP way |
| 23:44 | jcromartie | :P |
| 23:44 | jcromartie | yup |
| 23:44 | jcromartie | great minds think (or fail to think) alike |
| 23:44 | amalloy | remember what OOP practiced backwards is |
| 23:46 | jcromartie | heh |
| 23:46 | jcromartie | the thing is, I love Smalltalk to |
| 23:46 | jcromartie | too |
| 23:46 | jcromartie | OK so here's a generic record print/read |
| 23:46 | jcromartie | https://gist.github.com/845906 |
| 23:48 | jcromartie | (now with docstrings!) |
| 23:48 | amalloy | jcromartie: you can make this substantially faster by memoizing the class-name=>base-record function |
| 23:48 | jcromartie | true |
| 23:49 | amalloy | and (to-array (repeat arity nil)) is fine i guess, but i like (make-array Object arity) |
| 23:50 | jcromartie | ah yes that's better |
| 23:51 | amalloy | not sure why you're using into in one case, and merge in the other |
| 23:51 | amalloy | they're basically the same |
| 23:51 | jcromartie | not sure either |
| 23:52 | jcromartie | well merge is for maps, into is generic |
| 23:52 | jcromartie | might as well use merge for both |
| 23:52 | amalloy | *shrug* i usually use into but it doesn't matter |
| 23:53 | jcromartie | I've used merge and merge-with for specific situations before |
| 23:53 | jcromartie | can't recall though |
| 23:53 | amalloy | sure |
| 23:53 | jcromartie | anyway thanks for all the feedback |
| 23:53 | amalloy | welcome. i'ma go kill some zombies now, but ping me whenever |