#clojure logs

2011-02-26

00:00amalloyccw has a lot of the paredit functionality now, i believe
00:02Lulu58e2Yeah, I was using la-clojure in IDEA but I don't it sat idle for quite a while, not many features
00:02Lulu58e2* ... I think it sat idle ...
00:02Lulu58e2(My brain edits as I type and my hands get confused)
00:03amalloytry the other way around. let your fingers edit while your brain gets confused
00:05SgeoLulu58e2, each nick has a color
00:05SgeoIt's deterministic what nick becomes what color
00:05seancorfieldLulu58e2: i'm using whatever is the standard default on ubuntu :)
00:05Lulu58e2Sgeo: as in, the hash of the nick or some such?
00:05SgeoAnd I don't see you as grey or blue. That's just for yourself
00:06SgeoLulu58e2, I don't know details
00:06Lulu58e2seancorfield: lol, gnome I think
00:06SgeoBut you're the same color as seancorfield
00:06Lulu58e2Sgeo: well that's good to know, thanks
00:06Lulu58e2I had a brilliant idea: rtfm ... lol
00:09seancorfieldLulu58e2: mostly i use linux on servers so i never see the GUI... and i generally have Macs for desktop / laptop
00:09Lulu58e2seancorfield: ah, lucky
00:09seancorfieldi just bought a system76 starling netbook for traveling with and it has ubuntu netbook remix on it
00:09seancorfieldwhich is what i'm on right now :)
00:11Lulu58e2seancorfield: very nice
00:18Lulu58e2Okay, so the xchat help didn't help, but someone on #xchat did.
00:25amalloyand?
00:25Lulu58e2Settings -> Advanced -> Text Events "has everything to do with it"
00:26Lulu58e2Colour and formatting codes for all events
00:26amalloyneat
00:47Lulu58e2lol
00:47Lulu58e2So easily distracted from the task at hand
00:56SgeoI'm going to try to translate the PMD paper's demo to Clojure
01:54cobol_expertwhat are symbols of the form *symbol* called?
01:58SgeoI think I like Haskell's State monad a little more than I like Clojure's -> macro
01:59cobol_expertalso, when docs say 'set *warn-on-reflection* to true...' how do you set it?
01:59cobol_expertjust redefine it, like (def *warn-on-reflection* true) ??
02:00amalloycobol_expert: (set! ...)
02:00amalloysymbols are wrapped in *earmuffs* usually to indicate that they're expected to change and/or be rebound
02:01amalloySgeo: wut. they are completely different things. clojure has a state monad too
02:01cobol_expertokay, 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:02cobol_expertwhat ns is set! in?
02:02amalloy&(doc set!)
02:02sexpbotjava.lang.SecurityException: You tripped the alarm! set! is bad!
02:02amalloyblah. cobol_expert, set! is a special form
02:02amalloy(doc set!)
02:02clojurebotPardon?
02:03cobol_expertah, whenever I can't figure something out, it's a 'special form' :)
02:03SgeoAre Clojure monads used as commonly as monads in Haskell (subtracting usage of Haskell's IO monad, of course)
02:03cobol_experti should know by now
02:04amalloyyou bots all suck: http://clojure.org/vars#Vars%20and%20the%20Global%20Environment--%28set!%20var-symbol%20expr%29
02:05Sgeoo.O Clojure can use Monadic I/O
02:05SgeoI'm going to hazard a guess that it's mostly used by Haskellers
02:07amalloyas with every clojure tool, it's mostly used by developers who think it's the best widget for the current job
02:14cobol_expertokay, 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:19amalloycobol_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:20amalloyonce a var has been bound, you can set it with set!, but usually shouldn't anyway
02:21amalloyin fact i've never set! anything but warn-on-reflection and a couple java instance fields :P
02:22cobol_expertokay, thanks for clearing that up :)
02:23cobol_experti just see that form a lot and wondered if I ought to be using it for my programs' globals.. i guess not
02:23Sgeobinding is dynamic though, couldn't it cause weird issues if not used with caution?
02:23Sgeo(binding [some-function-name-but-i-dont-realize-it nil] ...)
02:24SgeoHmm, accidentally binding a function name like that probably wouldn't happen, come to think of it'
02:27SgeoAll names are namespaced?
02:29cobol_expertbinding seems to create its own namespace
02:29amalloyneither of the previous two statements is true
02:30cobol_expert'seems to' is not an assertion :)
02:30amalloylol
02:30amalloylots of names aren't namespaced, for example x in (let [x 10] (inc x))
02:30amalloy*most* vars are namespaced, which may have been what you meant
02:31amalloycobol_expert: binding pushes the value of a global variable onto a stack, changes it, and sets it back, more or less
02:31cobol_expertyeah, i was struggling with how to say it
02:31cobol_expertmore or less
02:32amalloyit piggybacks on top of the existing namespaces in the vars; it definitely doesn't create its own
02:34SgeoWhy are there no lisps that have special forms be first-class values? Or are there?
02:35amalloythat's what makes them special
02:38SgeoI thought what made them special was that inner arguments aren't fully evaluated before being sent
02:38SgeoOr something along those lines
02:40amalloySgeo: the same is true of user-defined macros, and those definitely aren't special
02:46SgeoI meant to include user-defined macros
02:46SgeoBut why aren't they first-class?
02:47amalloythey 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:47SgeoAh
02:48SgeoSorry if I seem like an idiot.
02:51amalloySgeo: http://rantsand.blogspot.com/2006/09/intelligence-wisdom-ignorance-and.html is an entertaining discussion of the difference between stupidity and ignorance
04:03semperosI have a structure like {:foo #{"bar" "baz"}}
04:03semperosstarting with an empty map
04:03semperosI know if I do
04:03semperos,(assoc {} :foo #{})
04:03clojurebot{:foo #{}}
04:04semperosI get a structure with which I can use update-in to conj onto the set
04:04semperos,(update-in {:foo #{}} [:foo] conj "bar")
04:04clojurebot{:foo #{"bar"}}
04:04semperosand so on as I add to that set
04:04semperosmy question is
04:04AreliusI'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:04amalloysemperos: fnil
04:05amalloy&(update-in {} [:foo] (fnil conj #{}) "bar")
04:05sexpbot⟹ {:foo #{"bar"}}
04:05semperosamalloy: thank you for anticipating my question
04:05semperosI keep forgetting that fnil exists
04:05amalloysemperos: you were building up to it quite thoroughly :)
04:05semperos:)
04:05semperosI knew there was a way
04:06semperosand I keep missing the opportunities to use it
04:06semperosamalloy: thanks, really appreciate it
04:06amalloysemperos: i went out of my way to use fnil the other day. up till now i basically just use it for update-in
04:06semperosvery natural fit for this kind of thing
04:07ToomasuI hadn't seen fnil yet, tangible benefit from following the channel for a couple of minutes :)
04:07amalloyand 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:09semperosgotcha
04:10semperosToomasu: imho, you won't find many channels better than this one
04:10semperosfor any language/project
04:11amalloysemperos: 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:11amalloyso that the nil-handling code didn't have to be next to the math-handling code
04:12semperosabsolutely, your use in that gist makes sense
04:12semperoswith a more complex data structure elsewhere in my code, I think I already committed an oversight and "prepped" map entries
04:12amalloyah
04:12semperosso I'll have to go back and fnilify that
04:13amalloyfnilify. that's a tricky one to pronounce
04:13semperos:)
04:14semperoseff-nil-ify
04:14semperoshow I hear it, anyway
04:25fliebelmorning.
04:25amalloyallo fliebel
04:27fliebelIn 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:07amalloysemperos, if you're still around and are interested, i've written two more versions of keep-only at https://gist.github.com/ac577998a404164266aa
06:11amalloyi'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:13kencauseyI've just created #las3r for anyone interested in the AVM2 'port' of Clojure - https://github.com/aemoncannon/las3r
06:14semperosamalloy: unfortunately I am still around, can't sleep
06:14semperosthanks, I'll take a look
06:14amalloysemperos: same here, though i was about to clock out. what time is it where you are?
06:14semperos6
06:14semperosyou?
06:14clojurebotYou will not become skynet
06:15amalloy3
06:15semperosmore sane :)
06:15semperosI slept for a few hours
06:15semperosbut woke around 2:30 my time and can't sleep
06:15semperosgo get some rest, thanks for all your help
06:16amalloysemperos: 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:17amalloykencausey: 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:18kencauseyIt'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:18kencauseyI 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:18amalloywell, i'll remember not to claim i know the guy who wrote it all
06:19kencausey:)
06:21amalloynight folks
06:44semperosI've removed clojure.contrib from my project.clj, but leiningen keeps pulling in the lib when I run 'lein deps' and 'lein uberjar'
06:44semperosam I missing something?
06:45semperosnm
08:04gfrlogGood morning clojure
08:07tscheiblmay I introduce queuejure
08:08gfrlogplease
08:10tscheiblit's a http long polling library based on a compojure ring aleph lamina combination
08:11gfrlognow I have to find out what lamina is
08:11tscheiblit's very lightweight.. not as bloated as CometD is...
08:11tscheibllamina is a channel framework
08:11gfrlogwas it extracted from aleph?
08:12tscheibl..just enough functionality to implement a reliable server messagequeue
08:12tscheiblgfrlog: lamina?
08:12gfrlogyes
08:12tscheiblprobably
08:13tscheiblit's quite usefull for implementing messagequeues
08:13tscheibl.. I mean.. you don't have much mor to implement
08:14gfrlogcool
08:15tscheiblqueuejour primarily focuses on hiding http request concurrency issues and request timeouts
08:16tscheiblwell.. I think I will call it queuejour ... despite the fact that technomancy won't like it ;)
08:16gfrlogI was thinking of that naming controversy
08:16tscheiblgot a better name? ;)
08:16tscheiblI'm open for proposals
08:17fliebeltscheibl: Are you making a message queue?
08:17gfrlogqueue-ball
08:17tscheiblYesterday it started to do everything I expected in my testbed... currently I try to create a decent library from the prototype code
08:18fliebelclueue :)
08:18tscheibllol
08:18gfrlogcan't beat that
08:19tscheiblmsjqueue
08:19tscheibl..nah
08:19gfrlogueueueue
08:19tscheibljeujeujeujeu
08:19gfrlogpronounced "oooh!"
08:19tscheibljeujour
08:19tscheiblexcuse my french ;)
08:20fliebelceuj
08:20tscheiblcjeu ?
08:20tscheiblcjeur ?
08:20raekmonsieur clojeur
08:20tscheiblclojard
08:21raek(the community seems to have settled on "clojurian", but always felt that "clojeur" was an interesting option)
08:21fliebelraek: I agree :)
08:22tscheiblorg.myveryownorangisationname.http.toolkits.qeuejour
08:22tscheiblarghh
08:22raekfliebel: that even fits the dutch spelling system, doesn't it?
08:23fliebelyea… but that is probably because dutch borrows heavily from french
08:23tscheiblthey borrow from everyone ;)
08:23raekKlåschör
08:24tscheiblyou are scandinavian, aint you?
08:24raekswedish does that too to some extent, but the spelling makes it less obvious
08:24tscheiblyess Sweden
08:25tscheiblraek
08:25tscheiblI'm from Austria
08:25tscheibl... no... no Kangaroos
08:25fliebelyou did not say australia did you?
08:26tscheiblClaustralia
08:26tscheibl.but there is no j in it
08:26gfrlogmy great grandparents are from sweden
08:26fliebelI've been to sweden last month (to contribute some other random fact)
08:27tscheiblI've been in Norway some years ago.. that's at least close ;)
08:27gfrlogI think that roughly equals great-grandparentage as far as being-swedish goes
08:27tscheiblwould be like great-grandparents
08:29gfrlogSweden is in the news lately
08:30fliebelgfrlog: Because of that leaking guy? O rjust because Sweden is taking over3 the world?
08:31tscheiblI think you confuse it with Libya
08:31gfrlogit's always those two
08:31gfrlogI'm like "which is which?" and I can never remember
08:32fliebelgfrlog: sweden hos no sand, so if you seen sand in the news, it's not sweden
08:32gfrlogwell I hope al-Gaddafi is nice to Mister Assange...
08:33fliebelSo, is Anonymous behind these protest after all?
08:33tscheiblboth of them will need political asylum in the near future
08:33tscheibl.. if they make it before beeing executed
08:34tscheibl..ahhh don't say 'anony....' they will close down irc
08:36gfrlogmaybe we could use queuejure to send Mister Assange a helpful message
08:36gfrlogor a sequence thereof
08:36tscheiblor.. queueball
08:36tscheiblI'm not so jour anymore
08:36fliebelor clueue
08:36tscheiblor jeujeujeu
08:37fliebelAnyway, does anyone know if Clojure runs on Mono yet?
08:37tscheiblwho needs that?
08:37tscheiblI mean... why the hell?
08:38tscheiblI can understand if you are ms fanboy you prefer to run it on the .NET CLR on an MS Platform... but Mono?
08:39Cozey:-) btw. sweden had and has some good music bands: http://www.youtube.com/watch?v=Aq4apgYriXE
08:39fliebelWell, why not? I heard they have some nice stuff on the CLR, plus MonoTouch would be cool :)
08:39tscheibldo they have Clojure in Sweden?
08:40tscheiblI've got a grey import here in Austria
08:40tscheibl;)
08:40tscheiblMonoTouch?
08:40tscheiblI knoe.. goolge is ya...
08:40tscheiblw
08:41fliebel$google monotouch
08:41sexpbotFirst out of 43200 results is: Main Page - MonoTouch from Novell
08:41sexpbothttp://monotouch.net/
08:41gfrlogoh I know why everybody is European...I'm on IRC way too early
08:41gfrlognow it all makes sense
08:42gfrlogthe western hemisphere is still hungover
08:42gfrlog$google gfrlog
08:42sexpbotFirst out of 91 results is: gfrlog:
08:42sexpbothttp://gfredericks.com/
08:43gfrlogI wonder how it is googling...the result count seems low
08:51kencauseyNot everyone is European ;) but point taken and agreed to
08:51gfrlogkencausey: are you also an exception to the hungover-westerner rule?
08:55kencauseyYes
08:55kencauseyhmm, actually I'm not certain what yes and no means to that question...
08:56kencauseyI consumed no alcohol yesterday, I'm a loner geek/nerd of the first order
08:56clojurebotNo entiendo
09:31TimMcgfrlog: Me too.
09:43gfrlogkencausey & TimMc: well good.
09:43gfrlogno wonder this party is so happening
09:43TimMcBoston, USA here.
09:43gfrlogThat is my time zone but not my climate
09:44gfrlogI would love to be there though
09:51gfrlogisn't there a method somewhere that could go by the name 'eval-in-ns?
09:51gfrlogI feel like I heard of it the other day
09:52gfrlog$findfn 'difference clojure.set/difference
09:52sexpbot[]
09:55gfrlogand is (deref (future (expr...))) equivalent to (expr...)?
09:55gfrlogwondering why I used the former...
09:55gfrlogoh it probably has to do with agents waiting on things...
10:06raekgfrlog: modulo costs for thread allocation and that exceptions get wrapped in a ExecutionException, yes
10:11eckrothIs there some idiomatic improvement of the following: (first (filter pred coll)) ?
10:13raekeckroth: (some #(when (pred %) %) coll) is an alternative. when pred is =, it can be written as (some #{x} coll)
10:13kencauseyI prefer the original myself
10:14raekyeah, me too in this case. but #'some can be useful sometimes.
10:14eckrothraek: thanks; seems like this is common enough to have something like (pick-out pred coll)
10:16kencauseyeckroth: so add it, Lisp is all about customization
10:16eckrothwell yeah but then I have my own special function floating around in some duplicated file for all my projects :)
10:16eckrothoh well
10:16kencauseynot an unusual situation
10:16eckrothI suppose so
10:17kencauseyhave you check the contrib libs?
10:17eckrothno; will do now
10:17kencauseyif it's not there maybe you can get it added
10:19msapplerHello I have a question regarding require and loading: http://pastebin.com/NRnLmzaq
10:20raekmsappler: (:require (a.test2)) should be (:require a.test2)
10:20eckrothkencausey: thanks for the push to look in contrib; I found it:
10:20eckroth(clojure.contrib.seq/find-first pred coll)
10:20raek(:require foo.x foo.y foo.z) is the same as (:require (foo x y z))
10:21kencauseyeckroth: excellent
10:21eckrothkencausey: its definition: (first (filter pred coll))
10:21eckrothhaha
10:21raekso (:require (a.test2)) means "require no namspaces starting with a.test"
10:22kencausey:)
10:22msappleroh
10:23msapplerwhy is this not in the require docs?
10:25eckrothdoes anybody already know of an optimization of (second (first coll))?
10:26fliebeleckroth: What is there to optimize?
10:26raekeckroth: (let [[[_ x]] coll] ...)
10:26raeknot an optimization, but another way of writing it
10:26eckrothyeah, ok... I thought maybe something like CL's cadr, caadr, etc.
10:27fliebelthere are a couple of ones named like fnext and such
10:27eckrothyeah
10:27raekI think clojure has fnext and nnext, but destructuring is used more often my gut feeling tells me
10:29gfrlograek: regarding my (deref (future (expr...))) question, you would agree that it has different behavior within an agent, right?
10:30raekgfrlog: how?
10:30fliebel$findfn [[1 2] 3 4] 2
10:30sexpbot[]
10:30gfrlograek: I believe you cannot call (await) within an agent
10:31gfrlogbut you can within a future that the agent derefs
10:31gfrlogso you can get the same behavior, but with the advantage of harder-to-understand code
10:31raekah, now I see what you mean
10:32raekI get the feeling you are using agents for something they weren't designed for (I may be wrong, though)
10:32gfrlogI 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:32gfrlogso it wasn't my idea to make it an agent
10:33gfrlogbut maybe doing the synchronous http is inappropriate; that would require more thinking
10:33raekyeah, agents are meant to be primarily asynchronous
10:33gfrlogwell naively I would say that I want a synchronous http library and there just aren't any
10:34gfrlogso I have to use clojure.contrib.agent and just wait for them
10:34gfrlogbut there's probably a cleaner way to do what I'm doing
10:35raekthere are a lot of other http client libs
10:37raekI would recommend checking them out to see if their api fits better for your usage
10:39bobo_async http client? https://github.com/neotyk/http.async.client
10:54gfrlog,(do (dorun (repeatedly 500 (partial agent 4))) "all those poor unused agents")
10:54clojurebot"all those poor unused agents"
10:56gfrlogI feel like the documentation for the (ns) macro might be wrong...
10:56gfrlogI thought this is not valid: (:require (clojure.contrib sql sql.tests))
10:57gfrlogeither that or the documentation for 'require is wrong: After removing the
10:57gfrlogprefix, the names that remain must not contain any periods.
10:57gfrlogor alternatively, I'm confused
11:05gfrlogis 'for always nicer than using 'map with an anonymous function?
11:05pdkthe intent is clear enough with map and it's more concise
11:05gfrlogit is?
11:05gfrlog(the concise part I mean)
11:06pdkcf. (map anon-fn list) and (for [i list] (anon-fn i))
11:06gfrlogmore like (map #(do-this %) list) and (for [i list] (do-this i))
11:06gfrlogI feel like the second one looks nicer
11:07pdkif do-this takes one argument you only need to write (map do-this list)
11:07Sgeo(map (partial do-this) list)
11:07SgeoOh
11:07gfrlogpdk: I know, but when I say "anonymous function" I'm specifically ruling that out
11:07gfrlogI agree map is nicer when you can just pass a function
11:08gfrlogassuming that that map alternative involves typing #(...) or (fn [_] ...)
11:08gfrlogboth of which seem clunkier
11:08pdkin that case i guess for would be fine
11:10gfrlog,(map for list)
11:10clojurebotjava.lang.Exception: Can't take value of a macro: #'clojure.core/for
12:12sritchie_hey all -- is there a way to bind a vector of all arguments to defn to a variable?
12:12sritchie_like -- (defn read-test [datasets resolutions tiles :as args] ... )
12:12sritchie_I'm not destructuring, I just want to apply a function to all of these arguments
12:17spewnsritchie_: As in (defn foo [& bar] (apply str bar)) ?
12:17sritchie_spewn: yeah, that's true... I just wanted to make it clear what the arguments should be
12:18TimMcYou want individual names and also a name for the whole list?
12:18sritchie_TimMc: yeah, exactly. I think I need to think more about these functions, but I was just curious about that possibility
12:19Sgeo(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:20sritchie_Sgeo: no, that works, that's good
12:21TimMcsritchie_: OK, here we go
12:21TimMc,((fn [& [a b :as e]] [a b e]) 1 2 3)
12:21clojurebot[1 2 (1 2 3)]
12:21SgeoMaybe I'll try Clojure Box
12:21TimMcNote that there is nothing forcing the correct number of arguments.
12:22TimMcSgeo: Your example would be better done as (defn foo [a b c] (str a b c))
12:22sritchie_TimMc: noted -- that makes sense, though, since the :as clause I was thinking about is found in destructuring
12:22sritchie_so we just destructure the variadic arguments
12:22TimMcsritchie_: It still may not be what you want.
12:23sritchie_Sgeo: I'm currently using TimMc's method, of just feeding them through into the next function
12:23sritchie_Sgeo: I was curious about shorthand
12:23TimMc,((fn [& [a b :as e]] [a b e]) 1)
12:23clojurebot[1 nil (1)]
12:28_2x2lhttp://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:29SgeoYay Clojure Box1
12:36SgeoEmacs seems to have some weirdities with []
12:36SgeoI mean I guess that's to be expected
12:36SgeoBut still
12:39TimMcSgeo: I haven't experienced any weirdness with that.
12:39SgeoTyping ] doesn't show the other [
12:39SgeoAnd it indents weirdly
12:39TimMcYou're probably not in the right modes.
12:40Sgeohttp://ideone.com/M96Yh
12:40SgeoI'd expect that println to be further to the left
12:41TimMcRight. You're probably not in the right modes.
12:41TimMcI get the expected behavior in Clojure + Paredit + hl-p
12:43SgeoThis thing came with paredit but it's not enabled by default
12:43SgeoWhat's hl-p?
12:44bennylutwhat am i doing wrong? ^(with-meta '(1) {:x 5}) => #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata must be Symbol,Keyword,String or Map>
12:44TimMcSgeo: highlight-parentheses-mode
12:45TimMc,(with-meta '(1) {:x 5})
12:45clojurebot(1)
12:45TimMcbennylut: Drop the initial caret.
12:46bennylutTimMC: i want to receive the metadata
12:46bennylutwhen i wrote ^(with-meta '(1) {:x 5}) i wanted to get (meta (with-meta '(1) {:x 5}))
12:46TimMc,(meta (with-meta '(1) {:x 5}))
12:47clojurebot{:x 5}
12:47TimMcI don't think ^ does that.
12:47bennyluti see, i have read that writing ^x means (meta x) am i wrong?
12:47bennylutok, thanks!
12:48TimMcbennylut: ^String foo means (with-meta foo {:tag String})
12:49TimMcand ^{:a :b} foo gives you (with-meta foo {:a :b})
12:49bennyluthmm.. i see, thanks
12:52bennylutTimMc: but see that- (def my ^String y) (meta my) => {:line 9} why?
12:54bennylutwhere y is : (def y '(1))
12:54TimMcHmmm. This is where vars start to complicate things and I am out of my depth.
12:55TimMc,(meta ^String (list 3))
12:55clojurebotnil
12:55TimMcOK, ignore the bit I said about :tag, then.
12:56bennylutsee that: (meta #'my) => {:tag String}
12:56TimMcAll I'm sure of is that ^ is for associating metadata, not for reading it.
12:57bennylutok i think that i will use the full methods for metadata cause the reader macros seem to be little awkword
12:59TimMcWhat we're dealing with here is the difference between metadata on a var and metadata on a value.
13:01bennylutso ^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:05TimMc,(do (set! *warn-on-reflection* true)
13:05clojurebotEOF while reading
13:05TimMcbah
13:05TimMc,(do (set! *warn-on-reflection* true) (let [x "foo"] (.length ^String x)))
13:05clojurebotjava.lang.IllegalStateException: Can't change/establish root binding of: *warn-on-reflection* with set
13:05TimMcOK, let me play with my own REPL for a sec.
13:08TimMcbennylut: Anyway, (set! *warn-on-reflection* true) in your REPL and then try (.length (identity "foo")).
13:08TimMcThis will give you a baseline for determining that hinting might be useful.
13:09TimMcidentity here serves to strip any knowledge that the argument to .length is a String.
13:09TimMcThen try different approaches: (.length ^String (identity "foo"))
13:15bennylutTimMc: thanks i will check it and post here
13:15TimMcbennylut: It's the ^String approach, btw.
13:16TimMc,(with-meta (identity "foo"))
13:16clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$with-meta
13:16TimMc,(with-meta (identity "foo") {:tag String})
13:16clojurebotjava.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IObj
13:17TimMcYou can't put Clojure metadata on most Java objects, including strings.
13:17TimMcThat is, (with-meta ...) won't work with most Java values.
13:18bennyluti 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:19TimMcSomething like that. I don't understand it myself yet.
14:11DespiteItAllHmmm, (Boolean. false) is true
14:15TimMc,(Boolean. false)
14:15clojurebotfalse
14:15DespiteItAll,(if (Boolean. false) "true" "false")
14:15clojurebot"true"
14:15TimMcOh, I see.
14:15TimMcYeah.
14:15DespiteItAllI thought clojure false was the same as java's false
14:16TimMc,(if false "true" "false")
14:16clojurebot"false"
14:16Lulu58e2Isn't anything not nil or false is true? (or something)
14:16TimMcIt is.
14:16DespiteItAll,(class false)
14:16clojurebotjava.lang.Boolean
14:16DespiteItAllHmmmm
14:16TimMcDespiteItAll: (Boolean. ...) is an object, which is always true.
14:16danlarkinclojure's false is Boolean/FALSE
14:17Lulu58e2Not same instance though?
14:17DespiteItAllAhh, got it
14:17DespiteItAllI know no java so the distinction is lost on me, but I see that there is one
14:17Lulu58e2I'm not 100% sure, I'm just guessing
14:18TimMc(class) might auto-box the input
14:18TimMcSo, false -> (Boolean. false)
14:18Lulu58e2,(hash (Boolean. false))
14:18clojurebot1237
14:19Lulu58e2,(hash false)
14:19clojurebot1237
14:19Lulu58e2Hmmm
14:19DespiteItAllSo, (Boolean. false) is the same as (Boolean. Boolean/FALSE)
14:19DespiteItAllwhatever that means
14:19TimMc,(identical? false (Boolean/FALSE))
14:19clojurebottrue
14:19TimMc,(identical? false (Boolean. false))
14:19clojurebotfalse
14:20TimMc,(identical? (Boolean. false) (Boolean. false))
14:20clojurebotfalse
14:20mrBliss,(if (Boolean. false) "true" "false")
14:20clojurebot"true"
14:20TimMcThe hash does not tell you about identity.
14:20Lulu58e2lol
14:20mrBliss(if (boolean false) "true" "false")
14:20Lulu58e2Ah, I thought each instance had a unique hash
14:21TimMcNope.
14:21mrBliss(Boolean. false) is evil, use boolean ##(map boolean [false nil 1 () true])
14:21mrBliss,(map boolean [false nil 1 () true])
14:21clojurebot(false false true true true)
14:23TimMc,(type false)
14:23clojurebotjava.lang.Boolean
14:23TimMchrm
14:23TimMcStill auto-boxing. :-)
14:58amalloy&(.getComponentClass (class (into-array [false])))
14:58zippy314Hi 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:58sexpbotjava.lang.IllegalArgumentException: No matching field found: getComponentClass for class java.lang.Class
14:59amalloy&(.getComponentType (class (into-array [false])))
14:59sexpbot⟹ java.lang.Boolean
15:00amalloyzippy314: C-c C-k is transitive. if you compile your "main" file that depends on all the others, they all get compiled
15:00zippy314Cool. Thanks.
15:07jk_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:10amalloyjk_: looks to me like they get GCed
15:12amalloytry this entertaining experiment: (in-ns 'tmp) (def x 1) (in-ns 'user) (def h #'tmp/x) (remove-ns 'tmp) @h
15:13amalloyyields 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:18Null-Alol amalloy
15:24jk_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:24amalloyi don't think so
15:25jk_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:25amalloyshould be fine
15:25jk_thanks, amalloy
15:35rikvaBeginners question: Is it possible to use multiple lines of code within a if form? Or is that not the Clojure way?
15:36no_mindrikva: if you are looking for executing multiple lines inside braces like non-functional programing languages, then I think it is not possible
15:36amalloywhoa slow down
15:36no_mindbut I am no clojure master :)
15:37amalloyrikva: it is possible, and also it is not the clojure way :)
15:37rikvathen, what is the clojure way? :)
15:37rikvamoving the code to a new function?
15:38amalloyrikva: 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:38amalloyif 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:38sexpbot⟹ 1 2 nil
15:40amalloyif 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:40sexpbot⟹ 1 2 nil
15:40amalloyrikva: making any sense yet?
15:41rikvayes, you are making perfect sense. I'll try it the Clojure way ;)
15:45Null-Arikva: (when true (println) (println) ..)
15:45Null-Aer already explained
16:03amalloyNull-A: but you included the ... that i was missing :)
16:03Null-Aheh
16:03gfrlogbest way to check if I have a list or vector?
16:05gfrlogam handling source code
16:08Guest22761gfrlog: (list? x) (vector? x) ?
16:10dsantiagoIt seems like clojure.core/name will cause a null pointer exception when it is passed nil. Why wouldn't it just return nil?
16:13Guest22761dsantiago: that seems like a reasonable thing to do if you don't pass it an actual clojure.lang.Named
16:13Guest22761dsantiago: return nil, i mean.
16:14dsantiagoYeah. 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:14dsantiagoCan'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:15TimMcI can't say I'm too pleased with nil propagation as an idiom.
16:16TimMcMakes it hard to know where the logic bug actually occurred.
16:17dsantiagoBut it's not really a logic bug if nil means "the empty list" or something like that.
16:18Guest22761i like the idea of (name) basically telling you tehre is no name
16:18Guest22761without just blowing up :)
16:21TimMcNil as empty seq (and nil propagation) are problematic for fail-fast programming.
16:21amalloygfrlog: don't use list? for source code. seq? is better
16:21amalloymacros expand into seqs, not lists
16:22dsantiagoamalloy: Is seq? better than sequential? seq? returns true on a map, but sequential? doesn't.
16:22Guest22761amalloy: but that's not telling you that it's a list or vector, right?
16:22amalloy&((juxt seq? sequential?) {})
16:22sexpbot⟹ [false false]
16:23amalloy&(map (juxt list? seq? sequential?) [() [] {} (range 0)])
16:23sexpbot⟹ ([true true true] [false false true] [false false false] [false true true])
16:24amalloynote 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:25Guest22761ok, if it's exclusively one or the other than you have then that's fine
16:25Guest22761s/than you/that you/
16:25sexpbot<Guest22761> ok, if it's exclusively one or the other that you have then that's fine
16:26dsantiagoWeirdly mixed up about that.
16:26amalloyGuest22761: if you need to distinguish scheme-style "atoms" from "listy things", you have coll?
16:26dsantiagoI ran into that same question like 3 days ago, apparently I alredy forgot everything about the differences.
16:30SgeoMaybe I should translate one of my few Haskell programs to Clojure...
16:32gfrlog,(seq? (read-string "(+ 3 4)"))
16:32clojurebottrue
16:33gfrlog,(seq? (read-string "[+ 3 4]"))
16:33clojurebotfalse
16:33gfrlogamalloy: seq? misses vectors
16:33gfrlogguess I gotta go with (or (seq? ..) (vector ..))
16:33amalloygfrlog: it sounded like you wanted to tell seqs and vectors apart, not lump them together
16:34gfrlogamalloy: sorryo, no
16:34amalloysee my juxty thing earlier. you want sequential?
16:34gfrlogwanted to distingush them from other things
16:34gfrlog,(sequential? "hoo ha")
16:34clojurebotfalse
16:34gfrlognice
16:35gfrlog,(map sequential? [[] () (read-string "(+ 3 4)") "okay" :nope 'yeah])
16:35clojurebot(true true true false false false)
16:35gfrlogthat is exactly what I wanted
16:35gfrlogthx amalloy
16:35amalloygfrlog: what's with the read-strings, anyway? '(+ 3 4) seems easier
16:36amalloyhm. i wonder. ##(sequential? (sorted-set []))
16:36sexpbot⟹ false
16:37gfrlogamalloy: strings aren't available till runtime
16:37gfrlogmy strings I mean; wasn't saying something bizarre about strings gin general
16:37amalloylol
16:38gfrlogI'm doing all kinds of disgusting crap with these strings, like doing gsubs with namespace names...
16:38rikvai'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:38SgeoOnce Clojure-in-Clojure is completed, will Clojure be ported to bare metal?
16:39gfrlogamalloy: I wrote my own parser for the (ns) sub-language
16:39amalloyrikva: the a needs to be inside the if
16:39gfrlogjust shake your head slowly
16:39amalloygfrlog: is there a reason not to just steal it from clojure.core source?
16:40gfrlogamalloy: I seriously doubt it. Do you know how that works? i.e., what it parses to?
16:40gfrlogI know it initially goes to (require ...) and (use ...)
16:41gfrlogI did look at the source some
16:41gfrlogwhat I ended up with wasn't too long...
16:41fliebelgfrlog: I'd try macroexpand-all combined with the lisp reader.
16:42gfrlogfliebel: the (ns) macro only transforms to direct calls to require and use
16:43gfrlogdoesn't manipulate the arguments at all
16:43gfrlogI guess there might be more macros underneath...
16:43fliebel(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:44rikvaamalloy: in what way?
16:44amalloy(if (> n 1) (test ...) a)
16:44gfrlogfliebel: heck that probably works
16:44gfrlogthanks
16:45fliebelgfrlog: (macroexpand-all (read-string "(ns test (:use clojure.set))"))
16:45rikvaamalloy: ah wow. Thanks a lot!
16:46fliebelgfrlog: What are you trying to achieve?
16:46amalloyalso 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:47gfrlogfliebel: I'm trying to have several versions of a library loaded at the same time, by transforming the namespace names
16:47fliebelamalloy: Good point, I still tend to think of functions and for loops as blocks, while they work perfecly inline.
16:47gfrlogso the prefix syntax for (require) and (use) cause a problem for naive string substitution
16:49amalloyfliebel: 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:50gfrlogmmm, waffles...
16:50amalloygfrlog: all my code needs more waffles
16:50gfrlogamalloy: lolwaffle.com
16:51fliebelamalloy: Hava you read any of those schemer books? they contain a ot of food code. Much better than foo/bar/baz
16:51amalloyfliebel: 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:52fliebelhm, I forgot to mention the food in my blogpost about it :(
16:54_2x2lis there a way to get meta-point to work in emacs with clojure, i.e., to auto-manipulate the jar?
16:55amalloy_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:56dsantiagoI can't find any docs on what the {:static true} metadata means...
16:56amalloydsantiago: not rebindable
16:56amalloyin 1.3 it's being replaced by {:dynamic true} as the default changes from rebindable to not rebindable
16:56dsantiagoamalloy Ah, OK, is this related to the new semantics for varS?
16:56dsantiagoI see.
16:58rikvaamalloy: thanks!
17:10arohnerI'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:12amalloyarohner: 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:13arohneramalloy: 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:14arohneror rather, building all possible DAGs from the input dataset, and scoring them
17:17amalloyhm. 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:18amalloywhich 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:21arohneramalloy: right, that was my concern. I think I can make it work, just wanted to make sure I wasn't forgetting about something
17:21amalloyarohner: undoubtedly you are forgetting about something, but i don't know what it is either :)
17:52Null-Aarohner: cascalog
18:09_2x2lis there a way to print locals via attaching to a running instance of swank?
18:13amalloy_2x2l: check out george jahad's clojure debugging toolkit
18:45DespiteItAllhahaha, 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:46DespiteItAlland the file is 5.5MB
18:54joshua__Would it be accurate to say that most functions we work with are multivariate functions?
18:54arohnerman, lein uberjar is *slow*
18:55arohnerjoshua__: as in most functions take more than one variable?
18:55joshua__arohner, basically yea
19:07amalloyjoshua__: probably, but bug brehaut and he'll tell you about currying to turn everything into one-argument functions
19:50amalloyin (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:45TimMcamalloy: "f" :-P
20:49TimMcamalloy: Anyway, are you writing documentation, or an instruction manual, or a blog post or what?
20:49amalloyTimMc: blog
20:50TimMcIn that case, you'll be able to change it easily if you find a better name.
20:51amalloyTimMc: sure
20:51TimMcWhy does it matter that the function is anonymous?
20:51TimMcOr is it just part of that example?
20:51amalloyTimMc: it doesn't, i suppose. you're suggesting i could write (reduce (fn some-name [a b] ...))?
20:52TimMcMost of the reduce expressions I've written have used a def'd function from elsewhere.
20:52amalloythe function can't be a top-level def, because i need it closing around some stuff
20:52TimMcThat probably means I'm not using reduce enough. >_<
20:52TimMcah
20:55amalloyanyway TimMc i'm done with the text now, just need to do some linking and tidying
21:45sritchie_hey all, quick question about a function I'm writing to generate timeseries
21:45sritchie_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:45sritchie_https://gist.github.com/845855
21:47sritchie_would it be better to sacrifice the second transpose call, and bring it up to the map-indexed step level?
21:52amalloywhew, 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:25TimMchah, cool
22:25TimMcInteresting point about application logic vs. bookkeeping code.
22:25amalloyTimMc: not my original idea, though. i found it in a 1969ish paper about why functional programming is the hot new thing
22:26TimMc:-)
22:28amalloyTimMc: found it! http://www.stanford.edu/class/cs242/readings/backus.pdf
22:28clojurebot#<RuntimeException java.lang.RuntimeException: java.lang.Exception: 503>
22:30TimMcThanks!
22:30amalloy5.1 was the section i was thinking of when i wrote that section
22:31amalloyhiredman: clojurebot has been doing a lot of barfing when some (but not all) URLs are pasted into the channel. any idea why?
22:33TimMchttp://www.stanford.edu/class/cs242/readings/
22:33TimMcDidn't barf there.
22:34TimMchttp://www.stanford.edu/class/cs242/readings/backus.pdf
22:34SgeoTimMc: found it! http://www.stanford.edu/class/cs242/readings/backus.pdf
22:35TimMcIt sure looks like a 503 Service Unavailable, which would be a transient error if that's what's really going on.
22:35SgeoNo barfing?
22:35TimMcWe need to find a page that always returns a 503 error. :-)
22:36SgeoI know of one!
22:36TimMcCould certainly just write one.
22:36SgeoOr, 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:36Sgeohttp://zzo38computer.cjb.net/errors/error.php?code=503
22:37amalloySgeo: it's an actual 503
22:37TimMcIt really does give a 503, but clojurebot didn't...
22:37TimMcYeah.
22:37amalloywow Sgeo that's an old page. php 4.4.0
22:38SgeoThe person behind that site is a bit.. strange
22:38amalloyand apache on windows, i see
22:38amalloywhich seems like a weird combo, but who am i to judge
22:38TimMcMan, that's great! I can get an HTTP 493 error on command!
22:38TimMcNo wait, it's a 500. Drat.
22:38SgeoHe wrote a custom IRC client where he types in the PRIVMSG command, iirc
22:38Sgeoerm, MSG?
22:39SgeoI forget the IRC protocol now
22:40sritchie_more specific question, for anyone interested, about the timeseries question -- https://gist.github.com/845855 -- why is my second version of timeseries lazy?
22:43amalloysritchie_: 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:44sritchie_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:44sritchie_s/first/
22:44sexpbot<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:45sritchie_amalloy: oh, I see. my transpose method had a wrapping call to vec.
22:45amalloyright
22:46sritchie_amalloy: I'm finding that the second version is about 20% faster
22:46amalloyinteresting. i wonder why
22:47amalloymemory 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:48sritchie_amalloy: even when I take that wrapping call to vec out, it retains the advantage
22:48sritchie_Here's how I'm doing my micro-benchmark -- (time (dotimes [n 10] (count (timeseries tester))))
22:48sritchie_test-chunks, rather, as defined in the gist
22:49amalloy$source cons
22:49sexpbotcons is http://is.gd/nKzkPw
22:49sritchie_I get about 24 seconds for the first version, 20 for the second
22:49sritchie_over multiple runs
22:49amalloyi'm thinking your map-indexed call may be lazily consing onto a list without computing the whole list?
22:49amalloybut i dunno
22:51sritchie_this is for a hadoop job, so the faster one wins, but the first one describes more clearly what's going on
22:51sritchie_interesting stuff
22:53amalloyi 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:54amalloyso 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:56amalloybut 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:57amalloysritchie_: ^, and afk for a bit
22:57sritchie_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:57sritchie_amalloy: that seems like a good approach to thinking about it, though
23:15jcromartieis there any solution to printing/reading defrecords?
23:16amalloyjcromartie: 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:16jcromartieamalloy: you mean to convert to/from maps?
23:17jcromartiemaybe have a :_recordname key or something
23:17amalloyjcromartie: that's a possibility
23:17taliosYou could just seralize to yaml/json etc.
23:18amalloytalios: why? serializing to a map will be at least as easy and we're in a lisp
23:19taliosfor the "print" side of things.
23:19amalloytalios: (print (into {} my-record-object))
23:19jcromartieyeah that's easy enough... now go the other way :P
23:19amalloyjcromartie: but serializing to json won't make the other direction any easier
23:20jcromartieI wouldn't go to JSON
23:20jcromartiethe constructor is the problem
23:20jcromartiethere's no empty constructor
23:20jcromartieis there any function that returns the arity of a constructor?
23:20amalloyjcromartie: i assume the set of record types is limited?
23:20jcromartieyeah I mean it could just be handled in logic
23:22amalloy(defmulti build-a-record :_type) (defmethod build-a-record ::person [{:keys [name age]}] (Person. name age))?
23:23jcromartienot bad
23:23amalloythen (build-a-record {:type ::person :name "dave" :age 30}) should work
23:23jcromartiebetter than what I just came up with :P
23:23jcromartie(defn read-car [s] (let [c (Car. nil nil nil) m (read-string s)] (merge c m)))
23:23jcromartie(defrecord Car [year make model])
23:24sattviksritchie_: 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:24jcromartiebut 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:24amalloysomewhere i have a def-record-with-constructor macro that creates a make-myobj function
23:25amalloybut defrecord2 surely does a better job of it than i did
23:25sritchie_sattvik: but my first function doesn't use more than 4
23:25sritchie_sattvik: it uses four
23:25jcromartieyeah defrecord2 looks good
23:25jcromartieit should become defrecord at some point
23:25amalloysattvik: also what you said is false in every way i can think of. vectors are not at all lazy
23:26sattvik$source vector
23:26sexpbotvector is http://is.gd/rHjtsJ
23:27sattvikFor more than four args: ([a b c d & args] (. clojure.lang.LazilyPersistentVector (create (cons a (cons b (cons c (cons d args))))))))
23:28amalloysattvik: 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:30jcromartiewell I can get the arity of a record constructor
23:31jcromartie(count (.getParameterTypes (first (.getDeclaredConstructors klass))))
23:31jcromartieeasy enough
23:31jcromartieand apply the constructor with the right number of nil args
23:31sattvikamalloy: Now that I look at it in detail, you are right.
23:31jcromartieso it's slow
23:31sattvikMy mistake.
23:31jcromartiebut it works for generic printing and reading of records
23:31jcromartieyay
23:32amalloyjcromartie: record classes have two constructors. are you *sure* the right one will always be first? i guess it doesn't matter though
23:32amalloysince you're just giving nil args
23:32jcromartieyeah
23:33amalloywhy are you using records to begin with?
23:35sritchie_amalloy, sattvik: the only difference between the two is the place where I apply the vector operation
23:36sritchie_I think it's slower when map-indexed does the job, than when I put it inside map
23:36jcromartieamalloy: why? I dunno, I am just getting into protocols and records
23:36jcromartieand this is something interesting
23:36sritchie_but that's handwaving, I don't know the source well enough to back that up with any real reason
23:37amalloyi mean, this is causing you great pain, so if you're not desperate for performance you can just use hashmaps
23:38amalloy(even if you are desperate for performance, verify that this is the bottleneck)
23:39jcromartieyeah I'm not there yet :)
23:40jcromartiehash-maps and multimethods would probably be fine
23:40jcromartieit's just a data access layer
23:40jcromartiebasically an interface to a nasty ol' database
23:40jcromartie10 years old
23:40jcromartieno design
23:40jcromartiebuilt mostly in MS Access
23:40jcromartieand most of our apps are bolted directly to the database (or at the most through stored procedures)
23:41amalloyoh, the irony: clojure 1.2, powered by ms access
23:41jcromartieso 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:42jcromartieand a RESTful API on top of that for web apps and such
23:42jcromartieanyway that's my plan
23:42amalloyjcromartie: 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:43amalloyno need to change the client api
23:43jcromartiegood point
23:44amalloyi 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:44jcromartieman 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:44jcromartie:P
23:44jcromartieyup
23:44jcromartiegreat minds think (or fail to think) alike
23:44amalloyremember what OOP practiced backwards is
23:46jcromartieheh
23:46jcromartiethe thing is, I love Smalltalk to
23:46jcromartietoo
23:46jcromartieOK so here's a generic record print/read
23:46jcromartiehttps://gist.github.com/845906
23:48jcromartie(now with docstrings!)
23:48amalloyjcromartie: you can make this substantially faster by memoizing the class-name=>base-record function
23:48jcromartietrue
23:49amalloyand (to-array (repeat arity nil)) is fine i guess, but i like (make-array Object arity)
23:50jcromartieah yes that's better
23:51amalloynot sure why you're using into in one case, and merge in the other
23:51amalloythey're basically the same
23:51jcromartienot sure either
23:52jcromartiewell merge is for maps, into is generic
23:52jcromartiemight as well use merge for both
23:52amalloy*shrug* i usually use into but it doesn't matter
23:53jcromartieI've used merge and merge-with for specific situations before
23:53jcromartiecan't recall though
23:53amalloysure
23:53jcromartieanyway thanks for all the feedback
23:53amalloywelcome. i'ma go kill some zombies now, but ping me whenever