#clojure logs

2012-12-25

00:19callenmuhoo: I wasn't aware he had kids.
00:19callenmuhoo: somebody that tall must have a hell of a time bending underneath a Christmas tree.
00:20callenRaynes: it amuses me that all the companies that build on Amazon don't bother build in cross-region failover
00:20callenbother to build in*
00:24muhooyikes, now googlecode is giving me 40s
00:24muhoo404s
00:25muhooheh, if googlecode was giving me 40s, i'd be spilling them on the ground in honor of all the fallen servers, yo
00:25RaynesHahaha
00:26muhoodoes googlecode use.... amazon?
00:26RaynesWhenever refheap goes down, netflix goes down, so I'm like "Yo, netflix is down too, yo."
00:26RaynesThey have a team. I have a me.
00:26muhooOK, WHO BROKE THE INTERNET?
00:27muhooseriously, there are some pissed off ops guys all over the world right now getting SMS's at a time they definitely don't want them
00:28RaynesFunfact: mics work better if you remember to plug them into the pramp.
00:28Raynespreamp*
00:28muhooRaynes: setting up for a gig?
00:28RaynesSure
00:28RaynesI've got a crowd of one person. Me in the mirror.
00:29muhoocheck 1, 2, check 1, 2. 2. 2. 2
00:32muhoohttp://online.wsj.com/article/SB10001424127887324660404578200383908151240.html yep, netflix out too
00:41RaynesThat awkward moment when you finish a massive vocal performance and realize you weren't recording it.
00:46bbloomRaynes: took a shower?
00:46Raynes?
00:47Sgeobbloom was thinking you were singing in the shower.
00:47RaynesI don't think I'd take a preamp into the shower.
00:59Raynesmuhoo: Want some Raynesong for Christmas?
01:00muhoosure!
01:00muhoodidn't know you were a musician
01:00RaynesI'm not, really.
01:00RaynesI just like to sing.
01:01RaynesAnd some people tell me I'm pretty good at it.
01:01RaynesSo yey
01:59ibdknoxRaynes: I got annoyed with entitlement http://www.reddit.com/r/Clojure/comments/15cspw/luminus_my_attempt_at_a_clojure_web_framework/c7ltq2b
02:01yediyou tell em
02:01asina12i am using emacs+nrepl....how do people use it to navigate clojure source code?
02:02yediibdknox: on a somewhat related note: did you get to check out luminus at all?
02:03ibdknoxyedi: Raynes and yogthos were talking about it earlier. The template is something he was intending to do anyways and it sounds like the few things that are in luminus right now will get merged into lib-noir
02:14muhooyep, with free software "if it breaks you keep both peices"
02:20muhoothe person to fix it can be found by looking in the nearest mirror
02:48Raynesibdknox: Excellent.
02:50Raynesibdknox: Loved every second of it.
02:51RaynesWould read again
02:51ibdknoxlol
02:51ibdknoxI've been getting this crap a lot lately, and it makes me sad.
02:51ibdknoxI really, really try to help
02:51ibdknoxbut there's just only so much I can do
02:51clojurebotPardon?
02:51yedieven clojurebot is givin you shit
02:52ibdknoxlol
02:52Raynesibdknox: Don't worry about it. I'll fight the good fight.
02:54Raynesibdknox: I don't blame you for anything. By time you stopped maintaining Noir, I had already switched to Compojure for unrelated reasons.
02:55RaynesI maintained Noir (as much as I could) entirely as a service to the community.
02:55ibdknoxI know, and thanks for that :)
02:55RaynesBut it just got to be silly.
02:55RaynesThe batteries included thing doesn't mean much when there are only three batteries.
02:56ibdknoxand like I said, that whole thing is just a matter of a template
02:56RaynesI'm honestly surprised that having to add three deps instead of one is really upsetting people.
02:56ibdknoxat that point they really are basically equivalent
02:56bbloomstop worrying about it guys
02:56RaynesExactly.
02:56bbloomthere will always be people who love frameworks
02:56bbloomthey are wrong
02:56bbloombut they will always be wrong
02:56bbloomand once they learn better, there will be lines of framework lovers right behind them
02:56bbloomyou'll never win
02:57bbloomso just bite your tongues and turn the other cheek and some other cheese sayings... then you'll be happier
02:58RaynesI think this template is going to go a long way.
02:58ibdknoxyeah
02:58RaynesI'm going to try to help him with it and get info out there about it.
02:58bbloombasically just a lein newnew plugin? :-P
02:58bblooma new newnew?
02:58RaynesI'm going to merge his lib with lib-noir in a few days after I look it over.
02:59RaynesGonna be legendary.
02:59Raynesbbloom: Just a template for lein-newnew.
02:59Rayneslein-newnew is extensible.
02:59bbloomright, a new newnew template
02:59RaynesYes.
02:59bbloomheh
02:59ibdknoxthe new newnew's new template for the new lib-noir style of writing new websites
03:02Raynesibdknox: You know, both 4clojure and refheap use lib-noir+compojure
03:02RaynesHave for quite a while.
03:02RaynesIt's pretty great.
03:02ibdknox:)
03:02RaynesNoir really had some great libraries.
03:03ibdknoxeh, they're very simple :)
03:03RaynesThey're still great though.
03:03RaynesI'm happy to replace sandbar's stateful sessions.
03:04ibdknoxyeah, he dropped that a *long* time ago
03:04ibdknoxit hadn't really been touched by the time I even started Noir
03:05Raynesbbloom: https://groups.google.com/d/msg/clj-noir/AbAvQuikjGk/mlYuC8ChW44J This sort of thing scares me though, man.
03:05RaynesLook at the planned features. At the end, he even lists "??? What else would you like this to do."
03:06RaynesShould have named it kitchen-sink
03:06bbloomRaynes: hey man, i get it. i built a serious app on rails
03:06bbloomit was *fucking awesome*
03:06bbloomuntil about 6 months later
03:06bbloomthen it was *not so fucking awesome*
03:06bbloomall-in-one can be really really attractive if you're in a hurry
03:06bbloomparticularly if it's popular
03:06ibdknoxI don't think you have to sacrifice that ease though
03:07bbloomfor all the absolutely horrible, evil, black magic fucking terrible unholy things that rails does
03:07bbloomi love rails
03:07bbloomit's absurdly productive....
03:07bbloom.....at first
03:07bbloomand if you're a contract crud web app sort of guy
03:07Raynesbbloom: The worst part is the guy replying to the guy I linked said "It's nice to see the Clojure web stack maturing"
03:08RaynesI die a little inside when people correlate the library approach to immaturity.
03:08bbloomRaynes: like i said: probably better to ignore those people
03:08RaynesI want to educate these people. Violently.
03:08bbloomhowever, one of the nice things about the clj community is the refusal to do the dumb things that other communities do
03:08Raynes$dict brainwash
03:08lazybotRaynes: verb-transitive: To subject to brainwashing.
03:09Raynes$dict brainwashing
03:09lazybotRaynes: noun: Intensive, forcible indoctrination, usually political or religious, aimed at destroying a person's basic convictions and attitudes and replacing them with an alternative set of fixed beliefs.
03:09yediwhat are some of the not so nice things about the clj community
03:09ibdknoxwe don't focus on beginners in any reasonable way
03:09ibdknoxwhich is what Noir was originally about
03:10SgeoDoes Factor's Furnace count as a "framework"?
03:10SgeoOr as a library?
03:11ibdknoxyedi: the benefits of Clojure are non-obvious to most and so it ended up drawing a very intellectual and seasoned crowd of people to it
03:11ibdknoxfor most of the guys here, picking up something new is fairly trivial
03:11muhooeveryone who doesn't get this topic should watch rhickey's "simple vs. easy" presentation
03:12muhoo"i love rails! it's so easy!" .... simple != easy
03:12Sgeohttp://re-factor.blogspot.com/2010/08/hello-web.html (might be slightly old)
03:12Anderkenthttps://gist.github.com/4372203 has oneone written this before? Macroexpand that does not crash on not-yet-loaded classes
03:12SgeoHmm, there's a way to make actions besides subclassing :/
03:13SgeoAnderkent, does it work with macros that use &env?
03:13Anderkentit passes anything that's actually a macro on to (macroexpand)
03:13Anderkentonly handles java interop itself
03:13SgeoDoes it do the right thing with '(quote ..... oh
03:13SgeoIt's not supposed to recursively macroexpand? Ok.
03:14Anderkentno, does the same thing as macroexpand :) Recursive macroexpansion is a bit more difficult, you have to track the lexical scope yourself etc
03:15muhoobbloom: actually i'm writing contract crud web apps in clojure. takes me 50 hours to do stuff i could do in 10 hours in rails or PHP, and i only get to bill for 10.
03:16muhoobut i get to write in a language i actually like, so, win.
03:16yedimuhoo: really? it's that bad?
03:16yediwhy..?
03:17muhoonot bad, i'm just new to clojure.
03:17muhooand, there are so many slap-it-together cut-and-paste libraries available for, say yii or rails, but in clj i have to roll stuff on my own.
03:18yedii c
03:18muhoowhen it comes to boilerplate apps, working in a language that has lots of boilerplate libraries is an advantage.
03:22amalloyAnderkent: your implementation of macroexpand-1 seems to delegate to macroexpand, not to macroexpand-1
03:23SgeoAnderkent, I only know one person who got recursive macroexpansion in Clojure right, and for some reason it doesn't seem to be very plug-and-playable into clojail
03:24SgeoAlthough I guess it could be argued that it is not in fact right.
03:25PudgePacketCan anyone explain why this doesn't work ? http://pastebin.com/4d2JmL7D
03:25PudgePacketseems like it should, returning a list of string from the str function
03:26amalloy,("a" "b" "b")
03:26clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>
03:26PudgePacketoh
03:26PudgePacketi forgot to quote the list
03:26amalloy,["a" "b" "b"] ;; or, (list "a" "b" "c")
03:26clojurebot["a" "b" "b"]
03:26PudgePacketsiiiiiiiiiigh
03:26muhooyedi: but i recently had to transform some oddball XML RDP-ish tuples from one service into a completely diffrent JSON format for consumption by a different service, and i was able to do that faster and way more fun in clojure than in anything else i knew.
03:26amalloyor, as you say, quote it
03:26PudgePacketthanks anyway :P
03:28muhoook, enjoy your holidaze, all
04:10dimovichhello ppl
04:10dimovichis there a better way to do (into (into array1 array2) array3)
04:10dimovich?
04:10bbloomdimovich: by arrayN do you mean a java array? or a clojure sequence?
04:10dimovichclojure sequence
04:11bbloom(doc into)
04:11clojurebot"([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."
04:11bbloom,(into [] (concat (range 5) (range 10 15) (range 20 25)))
04:11clojurebot[0 1 2 3 4 ...]
04:12bbloomdimovich: does that help?
04:12dimovichyes, thanks :)
04:12dimovichforgot about concat :)
04:12bbloomdimovich: you can skip the into, if you don't need a vector
04:12bbloomie just leave it as a lazy seq
04:12dimovichok
04:13bbloomor you can use vec
04:13bbloom(doc vec)
04:13clojurebot"([coll]); Creates a new vector containing the contents of coll."
05:11francisHello all, I'm having an issue figuring out how to quote a form - https://gist.github.com/4372506
05:12francisI'd like to accept any arbitrary form, (including quoted) and then use a quoted form in my fn, but I'm not sure how to do that
05:12francisthoughts?
05:14bbloom(doc symbol?)
05:14clojurebot"([x]); Return true if x is a Symbol"
05:14bbloom,'x
05:14clojurebotx
05:15bbloom,''x
05:15clojurebot(quote x)
05:15bbloom,(map class ''x)
05:15clojurebot(clojure.lang.Symbol clojure.lang.Symbol)
05:15bbloom,(map name ''x)
05:15clojurebot("quote" "x")
05:15bbloomfrancis: does that help?
05:16francisbbloom: I think so, though I need to try it out first
05:17francisthanks
05:17bbloomfrancis: also realize that quoting behaves differently on symbols than it does on other types
05:17bbloom,'5
05:17clojurebot5
05:17bbloom,''5
05:17clojurebot(quote 5)
05:17bbloom,inc ; a function
05:17clojurebot#<core$inc clojure.core$inc@166248d>
05:18bbloom,(map class [5 '5 inc 'inc])
05:18clojurebot(java.lang.Long java.lang.Long clojure.core$inc clojure.lang.Symbol)
05:18bbloomnotice how 5 and '5 are the same, but inc and 'inc are not
05:19bbloom,(map class [5 '5 ''5 inc 'inc ''inc])
05:19clojurebot(java.lang.Long java.lang.Long clojure.lang.PersistentList clojure.core$inc clojure.lang.Symbol ...)
05:19bbloom,(map class [5 '5 ''5)
05:19clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: )>
05:19bbloom,(map class [5 '5 ''5])
05:19clojurebot(java.lang.Long java.lang.Long clojure.lang.PersistentList)
05:19bbloom,(map class [inc 'inc ''inc])
05:19clojurebot(clojure.core$inc clojure.lang.Symbol clojure.lang.PersistentList)
05:19francisbbloom: interesting
05:20bbloomnote that is two apostrophes, not a quotation mark
05:20francisnoted
05:21dimovichhey guys, in enlive, how can I select all nodes with a specific property value of itemprop: (enlive/select html [:div.desc (enlive/attr? :itemprop)]))
05:21dimovichhow do I specify the itemprop value?
05:25francis(when (and
05:25francis (= :itemprop (enlive/attr? your-html))
05:25francis (= "myvalue" (enlive/get-value your-html)))
05:25francis ;; do stuff
05:25francis )
05:25francisdimovich: do mean like that?
05:25bbloomfrancis: please use refheap for multiline snippets
05:25francisI'm not sure of the exact enlive fn, but is that what you mean in general sense?
05:26dimovichno
05:26dimovich<div.desc itemprop="somevalue"> some text </div>
05:26dimovichselect all nodes that have itemprop=somevalue
05:27francissorry, so you want to use a select with an `and` clause if I'm not mistaken
05:27francishitting docs for exact source
05:27dimovichyes
05:27francisone min
05:33Raynesbbloom: Hahaha
05:33Raynesbbloom: He can't use refheap.
05:33Raynes:P
05:33bbloomdown?
05:33bbloomheh.
05:33bbloomheroku?
05:33bbloom*sigh*
05:33Raynesbbloom: It's been down for hours because Heroku because AWS.
05:33RaynesIt's pretty awful.
05:34RaynesNetflix is down too IIRC.
05:34bbloombecause Heroku because AWS .... because EBS?
05:34RaynesHeroku going down for 12 hours at a time is starting to outweigh the benefits of using heroku.
05:35bbloomRaynes: i gave up on heroku after 6mo of using it
05:35bbloomit's nice, but it's not nice enough
05:35RaynesI did it because Heroku would handle DDOS attacks which pastebins are prone to.
05:35bbloomheh
05:35RaynesBut it's almost not worth it anymore.
05:35RaynesI pay $20 for SSL that I could have for free on my VPS.
05:35AnderkentWell hopefully they'll move to multiple avail. zones eventually
05:35RaynesI expect uptime.
05:36RaynesI'm okay with a little downtime every once in a while, but yikes, it has been like 12 hours or more.
05:37Anderkentbut the point of heroku is not the performance, it's the ease of development. Prototyping/beta on heroku then moving directly onto AWS seems like the best bet for me
05:37bbloomhmm seems like ELB this time, not EBS
05:37bbloomit's usually EBS
05:37bbloomsince EBS is a terrible idea.
05:38Anderkentwhy do you think so?
05:39bbloomAnderkent: the same reasons NFS is a terrible idea
05:39bbloomthe posix/unix filesystem system api is not designed to be distributed
05:39bbloomthere are system calls that just don't make sense for a distributed file system
05:39bbloomhence the design of plan9's 9p protocol
05:41bbloomhttp://joyent.com/blog/magical-block-store-when-abstractions-fail-us
05:42bbloomhttp://en.wikipedia.org/wiki/9P
05:58francisdimovich: I would just filter by keys unless you have some other reason to use `attrs?` see: https://gist.github.com/4372608
06:02dimovichfrancis: thanks
06:03dimovichI suppose enlive has some built in stuff for this... but this should work too :)
06:05francisdimovich: I would imagine it does, but I didn't see anything just quickly looking it over, I don't use it personally and don't know it well enough
06:56callenbbloom: good luck telling HN EBS is a bad idea.
06:56callenbbloom: they love their fragile magic.
06:56callenthey get mad if you mention that AWS hasn't been the most reliable thing on the planet.
06:57RaynesOh no, callen's awake.
06:57callenRaynes: :(
06:58Anderkentso what's the thing that's more reliable than AWS? Self-hosting?
06:58callenAnderkent: it's almost more of an architectural question than where your physical machines live.
06:58callenAnderkent: one thing is to avoid networked filesystems that aren't very application specific (like EBS)
06:59callenanother is to mistrust magical load balancing, queueing, or database services (ELB, SQS, RDS)
06:59callenfurther, keeping your machines heterogenous in *where* they're deployed, with actual procedures in place for cross-geo failover is important
07:00Anderkentwell, aws does give you different zones for that
07:00callenhaha, yeah, that tends not to work.
07:00callennice try though. That's been a joke for a long time.
07:00Anderkentdo tell>
07:01callenwhenever EBS has gone down, all the sub-zones or whatever of say, US-EAST go down together.
07:01AnderkentI mean I havent used AWS on anything large, so I'm really being curious, not attacking you
07:01callenthere's no apparent separation/damage control
07:01callenother downtimes have been datacenter-scale network related, so again, their separation stuff hasn't helped anything
07:01callenwhen I say cross-geo failover, I mean from one end of the world to the other.
07:02callenyou'd need to have an architecture that is prepared to failover from Virginia to California
07:02callenif you're not prepared to do that, have another East Coast provider that isn't AWS
07:02callenand failover between those two.
07:03callenbut going back to my original point, the customers of the companies using AWS (Netflix, Heroku) haven't started getting punished by their customers, so they haven't been incentivized to fix the downtime.
07:03Anderkentwell that's what I was thinking about, host stuff on EU + one US region, that hopefully gives you something to fail over to>
07:03callenI have to say though, Netflix downtime on Christmas Eve is pretty choice.
07:03callenAnderkent: hypothetically yes, in practice, nobody takes advantage of that sort of thing.
07:04callenwhich I thought was the original point of AWS, but w/e
07:04callenself-hosting *could* be more reliable. at the very least, Google, Facebook, and Twitter have for the last couple years had considerably less downtime than AWS US-EAST
07:05callenit's just that for most companies it wouldn't be because they wouldn't be able to invest in the infrastructure properly.
07:05Anderkentmost of us aren't google, facebook or twitter though, and building our own datacenters is usually not an option
07:05callenthat's what I said, yes.
07:05Anderkentyeah I type a little slow :P
07:05Raynescallen: I think I've already decided to move refheap back to my VPS. It has been down for around 12 hours because of this shit.
07:05RaynesUnacceptable.
07:05RaynesHeroku's benefits aren't worth this. This is the second time this has happened.
07:06RaynesBut yeah, going to bed for real now.
07:06Anderkentso I don't see any alternatives for middle-size companies, where the app is too large to self-host, but too small to warrant branching into infrastructure
07:06callenRaynes: incidentally, I have 3 accounts on Heroku, 2 of the 3 have been HTTP 500'ing on login for the past week.
07:06callenAnderkent: I see plenty of alternatives.
07:07Anderkentwell, there's Rackspace, but i'd rather handle aws occasionally going down...
07:08callenAnderkent: Rackspace acquired Cloudkick, so they have a lot of the same tooling now.
07:08callenAnderkent: there's a ton of damn decent VPS providers, there's Joyent, etc.
07:08callenAnderkent: Joyent is pretty price/performance competitive with AWS and doesn't seem to have the ritualized tri-monthly downtime.
07:09callenAnderkent: it may not matter for you to have downtime, but it's a pretty serious matter in my day-to-day to have sustained downtime like this.
07:10callenAnderkent: I've gotten intensely unpleasant phone calls in the past over 2-3 minute blips before.
07:10callenif I was responsible for a product that'd been down for 12+ hours, I would've started the human sacrifices by now.
07:11Anderkentyeah, I haven't seen joyent before, will look into that. I'm rather awerse to rackspace after trying to debug kernel panics with them and finding out their support staff has almost no familarity with red hat, while they enforce the os on anyone using managed hosting
07:12callenAnderkent: I use a mixture of Linode, Rackspace, Softlayer, and AWS.
07:12callenbut nothing "live" to any customers goes on AWS.
07:12callenI don't trust them and likely never will.
07:12callenonly backups, batch work, etc go on AWS.
07:15Anderkentheroku are on n. virginia too? That's the region having most issues, isn't it?
07:15callenAnderkent: it's almost always NVA that has issues.
07:15callenAnderkent: that's also where like 90% of the customers are.
07:15callenthe secret to using AWS is to never ever use US-EAST :P
07:16callenthe first time anything is going to break, it'll happen there first
07:16callenmy AWS stuff is US-WEST
07:17callenmostly Oregon
09:16xeqiAnderkent, Raynes: you could try openshift
09:26wkellyxeqi: have you run anything production on openshift?
09:27xeqinope, I'm weary of a service without prices
09:28xeqiwkelly: ^
09:29wkellyunderstandable
09:29xeqithough if jcrossley3 or tcrawley|away get openshift auto-clustering working on it I might be really tempted
09:29xeqiwell.. I'm already really tempted
09:29xeqi* immutant auto-clustering
09:30wkellyI haven't met anyone who has really kicked the tires on it, but I enjoyed playing with it
09:30wkellyit was nice and easy to deploy clojure to!
09:31wkellyI don't know what kind of guarantees you can get about running on different physical hosts and so on for proper clustering
09:39xeqiwkelly: thanks, glad to hear from someone whos tried it out
09:41theadminHello. I want to learn Clojure, but I can't seem to find any decent starters tutorial anywhere. Any kind of LISP is entirely new for me, my only functional language was Haskell
09:42gfrederickstheadmin: 4clojure.com
09:43theadmingfredericks: Hm, interesting. Thanks.
09:46wkellytheadmin: if you are familiar with java, http://java.ociweb.com/mark/clojure/article.html can be helpful
09:46wkellyprobably even if you are not
09:46theadminwkelly: Am not
09:57theadmingfredericks: Hm, well, I'm messing with http://www.4clojure.com/problem/16 and my solution is: (fn hai [firstName] (str "Hello, " firstName)) but it fails. Can't quite see why.
10:01teromtheadmin: note rhe "!" at the end
10:01theadminterom: Oh durr
10:06theadminOk this started to get very confusing
10:37Anderkentremind me, bindings are thread local?
10:37si14__is it a bug, guys? (name (keyword "/foobar/:baz/bar")) => "bar"
10:38Bronsa,(namespace (keyword "/foobar/:baz/bar"))
10:38clojurebot"/foobar/:baz"
10:39si14__looks like a bug to me.
10:39bawrWhat would you expect?
10:39Bronsawhy so?
10:39si14__I would expect that (name (keyword x)) == x
10:39Bronsa(name :foo/bar)
10:39Bronsa,(name :foo/bar)
10:39clojurebot"bar"
10:40Bronsa,(namespace :foo/bar)
10:40clojurebot"foo"
10:40Bronsa,(str :foo/bar)
10:40clojurebot":foo/bar"
10:40Bronsa,(name (keyword "foo/bar"))
10:40clojurebot"bar"
10:40Bronsa,(namespace (keyword "foo/bar"))
10:40clojurebot"foo"
10:41si14__it's an abstraction leak, isn't it?
10:41Bronsaactually is a wanted feature
10:41AnderkentLooks more like non-conforming keyword to me? You want to be able to refer to keywords from other namespaces, which you do with a /
10:42si14__"keyword" that doesn't escape it's argument?
10:42si14__yeah
10:42si14__definitely a feature :)
10:43Anderkent,(namespace (keyword "Foo" "bar"))
10:43clojurebot"Foo"
10:43Bronsaerr? think about it / is used to separate the namespace from the name
10:43Bronsaif "foo/bar" was a valid name, there would be no way to safely parse :foo/bar/baz
10:43Bronsais the name bar/baz or is it baz?
10:44Bronsais the namespace foo/bar or is it foo?
10:44Anderkentuh no :foo/bar/baz is pretty easy to parse, :<whatever><space> parses to keyword with name = whatever ?
10:46si14__Bronsa: I think Anderkent is right
10:46bawrAnd what about namespaces?
10:46Anderkentbawr: name.space/:keyword ?
10:47Bronsai think you may have misunderstood what i was trying to say
10:47Bronsasi14__: you are complaining of the fact that in clojure there is no way for "foo/bar" to be parsed as a name
10:48Bronsaand I'm telling you that there is a reason why that CAN'T be done
10:48AnderkentBronsa: and the reason is?
10:48Bronsaok, suppose you want a keyword with namespace "foo" and name "bar/baz"
10:49Bronsathat would print out as :foo/bar/baz
10:49Anderkentoh okay didn't know it puts the : before the ns
10:49Bronsayeah
10:49Anderkentweird
10:49Anderkentbut ok
10:50Bronsaif it was the case that a namespaced keyword prited as ns/:bar then it would be possible
10:50Bronsaprinted*
10:50Bronsabut i don't think that'd be a good idea anyway
10:51si14__ok, thanks.
10:52Bronsaso, the current behaviour of the reader is to take until the last / and consider that the namespace part, and the rest the name
10:56AnderkentAny suggestions for large-ish clojure libraries to try my test coverage library on? For now tried incanter and ring, anything else?
11:05xeqiAnderkent: could try it on the leiningen source
11:07Anderkentnice idea, thanks
11:08xeqior chesire, clojail, compojure, etc. not sure those would be "large" though
11:13Anderkentlein master branch is a dev or release branch? Can't run the tests there it seems..
11:15Bronsalein master branch is dev
11:15xeqiAnderkent: there is some minor steps required to bootstrap lein atm, https://github.com/technomancy/leiningen#building
11:16xeqithough it does require lein1
11:16xeqithough I think the tests are failing on master
11:17Anderkenti get failures at preview as well ;/
11:17xeqiyeah, might bee better to come back to that one :p
11:18Anderkentwell I should be able to run coverage even with failures, so I'll try and see what happens :P
11:28xeqiAnderkent: I wouldn't mind seeing stats on https://github.com/xeqi/peridot or https://github.com/xeqi/kerodon
11:37Anderkentthink I need to give up on lein as it seems to just call System/exit if I do clojure.test/run-tests instead of running it from via lein test ...
11:37Anderkentoh, I suppose I can just not run compilation tests ;p
12:15AnderkentHow can I add a dependency to a lein project from a lein plugin?
12:16yedipostgres and redis seems like a winning duo
12:17Anderkentah, found it, nvm
12:19BaughnDoes clojure have a different notion of classpath than java?
12:20BaughnI ask because.. well:
12:20gfredericksno
12:20Baughn$ java -cp . -jar ../../lib/clojure-1.4.0.jar
12:20Baughnuser=> (compile 'boom.core)
12:20BaughnFileNotFoundException Could not locate boom/core__init.class or boom/core.clj on classpath: clojure.lang.RT.load (RT.java:432)
12:20Baughn$ ls boom/core.clj
12:20Baughnboom/core.clj
12:20clojurebotnstools is a library to reduce repetition in your ns clauses: http://code.google.com/p/clj-nstools/
12:23AnderkentBaughn: try printing the classpath, see if the dir is on the list?
12:23BaughnAnderkent: Sure.. how?
12:23Anderkent,(println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))
12:23clojurebot#<AccessControlException java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader)>
12:23Anderkentwell, it will work for you :P
12:24BaughnHm, that gives just the clojure .jar
12:24BaughnOdd.
12:28Anderkenttry `java -cp '.:../../lib/clojure-1.4.0.jar' clojure.main`
12:28Anderkenti'm not sure how -cp and -jar interact
12:28BaughnYeah, that's the trick. They don't.
12:31yogthosoh hey I ran into this yesterday
12:31yogthos-cp doesn't like jars not being in the same folder
12:32BaughnI figured it out. I just need to not use -jar.
12:32BaughnNot nice of java to just swallow the -cp, though
12:32yogthosno it's not ;)
12:33yogthosthe way classpath works is not terribly intuitive
12:45sveduboisHow I can translate this line in java to clojure?
12:45sveduboisfilter.setSigma( Double.valueOf( sigma ).doubleValue() );
12:46sveduboisIs this OK? (.setSigma filter (Double/valueOf (sigma) doubleValue))
12:48yogthoslooks reasonable
12:49yogthoserr
12:50yogthos(.setSigma filter (Double.valueOf (.doubleValue sigma)))
12:52edlothiolstill not right, (.setSigma filter (.doubleValue (Double/valueOf sigma)))
12:52edlothiolalthough Double.valueOf(sigma).doubleValue() can be simplified to Double.parseDouble(sigma), I think
12:53edlothioli.e. (.setSigma filter (Double/parseDouble sigma))
12:53yogthosyou could also thread it, eg: (->> sigma .doubleValue Double/valueOf (.setSigma filter))
12:55yogthosI find the threading syntax is a bit easier to follow, since it flattens the expression
12:56sveduboisIt seems that works, but I get an exception:
12:56sveduboisException in thread "main" java.lang.IllegalArgumentException: No matching field found: doubleValue for class java.lang.String
12:56sveduboisI need to import something for doubleValue?
12:57edlothiolit should be (->> sigma Double/valueOf .doubleValue (.setSigma filter)), but you should really just use Double/parseDouble
12:58kovasanyone doing some xmas coding?
12:59yogthosyeah if sigma starts out as a string
12:59sveduboisThanks it works!
12:59yogthoscool
13:00Anderkentkovas: yes :P
13:00kovasAnderkent: best present: time to code on fun projects :0
13:01yogthos:)
13:02jonasenkovas: I'm working on the Java Codeq analyzer.. that's a lot of fun!
13:03kovasjonasen: cool! is there a github?
13:03kovasI'm working on session
13:04Anderkenthah, I'm hacking on a code coverage tool : https://github.com/JacekLach/cloverage . Should be ready for a beta test... :P
13:04jonasenkovas: It's at https://github.com/jonase/codeq/tree/java
13:05kovasnice. i am ready for the next level of tooling
13:06ibdknoxrelatedly, I'm working on LT :)
13:07jonasenkovasb: here's a query https://gist.github.com/4374467
13:12jonasenkovas: Session looks awesome! Would love to help out on that project
13:12kovasjonasen: thanks!
13:12kovasjonasen: theres a bunch of stuff to do :) I think I'm gonna spend some time opening tickets and improving the documentation right now..
13:14sveduboisI have translate this java code to clojure:
13:14sveduboisJava:
13:14svedubois ImageFileReader reader = new ImageFileReader();
13:14svedubois reader.setFileName(input);
13:14svedubois Image img = reader.execute();
13:14sveduboisClojure:
13:14svedubois(defn main [input]
13:14svedubois (let [reader ( ImageFileReader.)
13:14svedubois img (Image.)]
13:14svedubois (.setFileName reader input)
13:14svedubois (def img (.execute reader))))
13:14sveduboisI have problems to convert "img" from java to clojure.
13:14sveduboisI am not sure that:
13:14sveduboisImage img = reader.execute();
13:14sveduboisIs the same that (or even valid):
13:14svedubois(def img (.execute reader))))
13:15Anderkentit is (assuming it's a top level declaration, otherwise probably (let [img (.execute reader)] ...) is what you want)
13:15Anderkentoh, didn't see your earlier example
13:16Anderkentwhat you want is something like
13:16yedisession looks sweet
13:16yediis there a demo up somewhere?
13:17Anderkent(let [img (-> (ImageFileReader.) (.setFileName input) .execute)] <do something to img or return it>)
13:19kovasyedi: will try to get a screencast up in the next few days
13:25yedikovas: let me know when you finish documenting/ticketing
13:27kovasyedi: sweet, will do :)
13:32miloshadzicis there a recommended test framework for clojure?
13:32ziltiAnderkent: Wouldn't it be more clear to use .. instead of -> to chain java stuff?
13:33ziltimiloshadzic: There's the official one built in, and there are several others, but the most mature is probably midje.
13:34Anderkentzilti: .. has different semantics - .. chains the results, -> chains the first expression through all statements
13:35ziltiAnderkent: Oh. Yes, right.
13:35miloshadziczilti, I guess the builtin one will do for now
13:36miloshadziczilti, (thanks)
13:37ziltimiloshadzic: no problem. But I'd really recommend at least taking a look at both before deciding.
13:38Anderkentmidje is pretty cool, though I still wrap midje tests in (deftest) so anything that works with clojure.test will work with my tests
13:38Anderkent(for example the mvn plugins)
13:38miloshadziczilti, I'm kinda new to Clojure. I use RSpec most of the time in ruby
14:48ziltiWhat would be the better variant to search for a function you added in a list with a bunch of functions - to store additional metadata at the fn when adding it or to store the fn at a second place to compare?
14:50zilti...or probably even better, to work with hash values.
14:51sveduboisIs this java to clojure conversion correct?
14:51sveduboisimage = new Image ( 256, 128, 64, PixelIDValueEnum.sitkInt16 );
14:51svedubois(def image (Image. (256 128 64 PixelIDValueEnum/sitkInt16)))
14:52ziltisvedubois: "new" exists in clojure, too.
14:53sveduboisI get this error: clojure.lang.Compiler$CompilerException: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn, compiling:(Image.clj:7:20)
14:53bbloomsvedubois: you're trying to call (256 128...)
14:53bbloomyou have extra parens
14:53zilti(new java.awt.Image 256 128 64)
14:53zilti,(new java.awt.Image 256 128 64 PixelIDValueEnum.sitkInt16)
14:53clojurebot#<CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: PixelIDValueEnum.sitkInt16, compiling:(NO_SOURCE_PATH:0)>
14:54sveduboisThanks, it works: (def image (Image. 256 128 64 PixelIDValueEnum/sitkInt16))
14:54bbloomsvedubois: for the record, (Foo. x y z) is just shorthand for (new Foo x y z)
14:59ziltiHow ugly is this?
14:59zilti(defn remove [arg] (if-not (= (class java.lang.Integer) (class arg)) (remove (hash arg)) (...code...)))
14:59clojurebotmarg is 1
15:00zilti(and what is "marg is 1"?)
15:00bbloomzilti: what are you trying to accomplish?
15:02ziltibbloom: making a function that removes an entry from a list, and if the argument is not an Integer/hash-value, calc the hash and retry.
15:02bbloom(doc remove)
15:02clojurebot"([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns false. pred must be free of side-effects."
15:03ziltiBut since Clojure is dynamically typed.
15:03bbloom,(map (comp class hash) [1 2.0 "3"])
15:03clojurebot(java.lang.Integer java.lang.Integer java.lang.Integer)
15:03ziltiYes, I know remove.
15:03bbloomok all integers rather than longs
15:03zilti(hash remove)
15:03zilti&(hash remove)
15:03lazybot⇒ 21755981
15:04bbloomso you wish there was some sort of hash-value? predicate?
15:04bbloomwhy are you working with hash values directly?
15:05ziltibbloom: I thought it's cheaper to keep only the hash-value of a function instead of the whole function, for when I later want to remove that function from the list.
15:06bbloomzilti: have you profiled and found that optimization to be worthwhile? is that even an optimization. with boxing of integers, i wouldn't be so sure
15:08ziltibbloom: No, I didn't do that. But I thought it's "ugly" to keep the whole function lying around and all that. But it's probably not worth the effort.
15:09bbloomalso what are the collision characteristics of clojure's hash function? since it's an integer and not like a 128 secure hash, you need to worry about that
15:09bbloomwhat would be ugly about it? you're not keeping anything "lying around" that's what garbage collection is for
15:09zilti&(= (hash (fn[x](* 2 x))) (hash (fn[x](* 2 x))))
15:09lazybot⇒ false
15:09bosies it possible that midje's provided only works on calls for the very last function?
15:09sveduboisHow I can obtain the value of image (instead of #<Vector...)?
15:09svedubois(.getSize image)
15:09svedubois#<VectorUInt32 org.itk.simple.VectorUInt32@3a432ed2>
15:10bosieanything i call prior to the last function seems to not get mocked, somehow.
15:10ziltisvedubois: (. image getSize)
15:10bbloomzilti: that's precisely the same as (.getSize image)
15:11bbloomsvedubois: the vector you're getting back is a java object
15:11bbloomyou can inspect it with interop, if the itk library doesn't provide a decent toString
15:18sveduboisUsing toString, I obtain this:
15:18svedubois(.toString (.getSize image))
15:19svedubois"org.itk.simple.VectorUInt32@52c9f3c7"
15:19bbloomsvedubois: right, the default printing behavior in clojure is to call toString and wrap it in those #<...> things
15:20bbloomsvedubois: in this case, there isn't a good toString for that function, so you need to inspect the object's fields directly with (.getX vector) or whatever the functions are called
15:22sveduboisWhen I use this:
15:22svedubois(.toString image)
15:22sveduboisIt prints a long text:
15:22svedubois"Image (0x7fc51c0047b0)\n RTTI typeinfo: itk::Image<short, 3u>\n ... Size: [256, 128, 64]\n ... Size: 2097152\n ...
15:23bbloomIf you want, you can define a print behavior for a foreign type by doing (defmethod print-method VectorUInt32 [obj writer] (print-simple (str obj) writer))
15:23bbloomsvedubois: what exactly are you trying to accomplish?
15:51Seba51Happy Christmas to all of you.
15:52Seba51I am learning clojure and have issues to understand a specific problem with macros.
15:52bbloomSeba51: ask away
15:54Seba51The book uses the following sample for a macro: (defmacro unless [expr form] (list 'if expr nil form)). I am wondering why they do not use (defmacro unless [e f] if e nil f) which seem to work as well
15:54Seba51What is the motivation to use list?
15:54gfredericksyours seems to work?
15:55Seba51Sorry brackets were missing around if
15:55gfrederickseven so
15:55Seba51(defmacro unless [expr form] (if expr nil form))
15:56gfredericksah ha
15:56gfredericksthat's a little more understandable
15:56Seba51(unless true (println "x"))
15:57gfrederickstry (unless (= 1 2) 42)
15:58RaynesBodil: Worst thing ever is hearing "I tried it, but it didn't work." :p
15:58RaynesI'm not currently aware of any bugs in conch, so definitely need reports when people find them.
15:59Seba51(unless 1 2) prints nothing
15:59Seba51nil
15:59gfrederickswhich you want
15:59gfredericksbut (unless (= 1 2) 42) should give you 42
15:59sveduboisWhen I try to print the Size of an image:
15:59svedubois (.getSize image)
15:59sveduboisI get this:
15:59svedubois #<VectorUInt32 org.itk.simple.VectorUInt32@31ac8cf3>
15:59sveduboisAnd using toString:
16:00svedubois (.toString (.getSize image))
16:00sveduboisI get this:
16:00svedubois "org.itk.simple.VectorUInt32@981f674"
16:00sveduboisLooking the class getSize is inside VectorUInt:
16:00svedubois public VectorUInt32 getSize()
16:00svedubois {
16:00svedubois return new VectorUInt32(SimpleITKJNI.Image_getSize(swigCPtr, this), true);
16:00svedubois }
16:00sveduboisIs there any easy way to print the numbers of getSize?
16:00gfrederickssvedubois: refheap.com
16:00bbloomsvedubois: like i tried to say: you need to call accessor functions on that VectorUInt object
16:01Seba51* need a moment to understand the answer *
16:01bbloomconsult the javadocs or something for the library you're using
16:01RaynesOh great, refheap is actually up now?
16:01RaynesI've got moving that thing off of Heroku on my todo list.
16:03bbloomi have a bunch of helper functions for working with zippers. i use the main zipper library (require '[clojure.zip :as zip]) but want to move all my helper functions into a separate namespace too
16:03bbloomi kinda wish i could do (require '[bbloom.zip :as zip]) and have the zip alias just be like an extended version of the clojure.zip namespace
16:04bbloomis there anyway to do that other than to loop over ns-publics and call intern on each?
16:04Seba51Having (defmacro unless_ [expr form] (list 'if expr nil form)) and (defmacro unless [expr form] (if expr nil form)), both print the same for (unlessl 1 2) 42
16:05bbloomSeba51: consider side effects: (unless true (print "omg!"))
16:05jonasenkovas: I've got session running and started to read through some of the code.
16:05kovasjonasen: nice. let me know if u have any questions
16:05jonasenkovas: I updated to latest clojure/clojurescript/datomic/cljsbuild and it seems to work still
16:06kovasjonasen: i just created a bunch of tickets, working on cleaning up / commenting the code
16:06kovasjonasen: great, if u make a pull request I'll just update it
16:08gfredericksSeba51: what is your understanding about the difference between a macro and a function?
16:08jonasenkovas: I also made some trivial clean-up of session.datomic. I'll send you a pull request
16:09kovasjonasen: awesome, thanks!
16:10Seba51Functions are evaluated immediately
16:11gfredericksSeba51: macros are functions on code. Their input is code, and their output is code.
16:11gfredericksthe definition in the book uses list because it wants to return an if expression, but if expressions are lists that begin with the 'if symbol
16:12gfredericksyour definition, instead of returning an if expression, either returns the second argument or nil
16:12gfredericksand it decides how to do that based on the truthiness of the first argument (expr)
16:12gfredericksbut that argument is unevaluated code
16:13gfredericksso if it is an expression such as (= 1 2), even though it would evaluate to false, as code it is truthy
16:13gfredericks(because it is a list)
16:13gfredericks,(boolean '(= 1 2))
16:13clojurebottrue
16:16bawrgfredericks: it's only appropriate :)
16:17gfrederickshttps://twitter.com/gfredericks_/status/283581072237789185
16:17Seba51I found out, that the smiley (caused by ( = was actually code, but give me a moment to understand
16:17gfredericksoh dear smileys
16:17Anderkent(=
16:17gfredericksI bet that means my counterexample from earlier got missed
16:18Seba51yep
16:18Seba51;-)
16:18gfredericksit was (unless ( = 1 2) 42)
16:18Seba51I assumed that you were in happy mood while typing ;-)
16:19bawrSeba51: but erh, yeah, what you want to take away from this is that macros are really supposed to emit code. ;P
16:19bawr:>
16:19Seba51I got it
16:19gfredericksbawr: are you trying to condense my ramblings to a helpfully digestable size?
16:20bawrgfredericks: I'm distilling them, I guess.
16:20Seba51Thanks a lot
16:20bawrBut that's some good rambling, 10/10 would distill again.
16:20gfrederickslerlz
16:22Anderkentstyle question: how do I do nested map/reduce right? example http://pastebin.com/QQdLiv5Z
16:22jonasenkovas: thanks for the merge. I might be able to pull of #20 also. Codeq only checks if some known schema attribute is already in the db and otherwise it transacts the schema. Is this what you had in mind?
16:23kovasjonasen: i thought it did something more sophisticated with annotating the transaction.. lemme take a look
16:25gfredericksAnderkent: besides breaking something out into a separate function, I can't think of a simpler way to do that
16:26Rayneshttp://dl.dropbox.com/u/23745600/Screenshots/6uOy.png
16:26RaynesWrong window.
16:30kovasjonasen: you're right, it does something very simple for the base codeq schema. I thought I saw something for the analyzer-specific schemas, which also need to be transacted
16:31bbloomlet me try my question again.... is there any way to turn (:require [clojure.zip :as zip] [bbloom.zip-util :as zipx]) into some similar to this magic fake syntax (:require [(clojure.zip bbloom.zip-util) :as zip])
16:31bbloomor even better, do that on the supply side: inside the zip-util namespace
16:31bbloomsomewhat similar to how python provides __ALL__ that you can fill in
16:31jonasenkovas: The analyzers supports schema revisions and when you run codeq it figures out which versions has been transacted
16:32kovasjonasen: in any case, i think my plan was to just copy exactly what codeq did in terms of those conventions
16:32yogthosmaybe you could make a macro which makes a new namespace that uses both and then require it as whatever?
16:32Anderkentbbloom: I don't think your magic fake syntax would do what it does (can't have both of them required for one name, can you?)
16:33yogthosoh nm it won't be exposed that way
16:33yogthosit's too bad you can't cascade dependencies
16:33AnderkentI'm not sure what we're trying to do - have one zip namespace with all the functions in it?
16:33Raynesbbloom: I'd probably hate you if you did that.
16:34bbloomyogthos: yeah, you'd need the macro to expand to a bunch of def forms, which is totally doable
16:34bbloomAnderkent: basically
16:34bbloomRaynes: why? i have a dozen or so zipper functions that i always use
16:34bbloomi keep forgetting which are in zip and which are in zip-utils :-P
16:34bbloomit's driving me nuts
16:34Anderkentbbloom: how about doing magic in zip-util that reexposes all zip vars under its own ns?
16:34Raynesbbloom: The problem is how does the person reading your code know where things come from?
16:34RaynesWhich namespace?
16:35RaynesAnyways, if it is ridiculous namespace magic, it's probably in potemkin somewhere.
16:35Raynes$google clojure potemkin
16:35lazybot[ztellman/potemkin · GitHub] https://github.com/ztellman/potemkin
16:35amalloyyes, potemkin contains exactly the magic bbloom wants to make his code easy to write and hard to read
16:35Raynesamalloy: o/
16:36bbloomheh: https://github.com/ztellman/potemkin/blob/master/src/potemkin/namespace.clj
16:36kovasjonasen: ok. I guess its not a big functionality improvement to change that then, other than to maybe rename the functions i have
16:36Anderkentimport-fn seems like the thing bbloom wants to do
16:36kovasjonasen: I'm also gonna open some tickets on codeq and lein that might be interesting for you
16:36kovas:)
16:36bbloomRaynes & amalloy: you really thing it would be bad to have at the top of zip-util a big list of things that are copied from clojure.zip ? doesn't seem like it would make reading it that hard
16:36jonasenkovas: except that you'll be able to run the free transactor
16:37Anderkentbbloom: that's okay, as for the user they all seem to come from zip-util
16:37bbloomyou are in myapp.core and you navigate to zip-util and see that zipper is defined as clojure.zip/zipper
16:37Anderkentthe bad case is where you would have the two namespaces somehow merged in the user ns
16:37bbloomyeah, Anderkent i agree
16:37jonasenkovas: right now it'll try to transact the schema every time
16:38Raynesbbloom: In my experience, it a) makes it difficult to find where vars originate for people reading the code b) makes error messages have ridiculous stacktraces because you're trying to change where something is c) is not worth it.
16:38kovasjonasen: not optimal
16:39amalloybbloom: i suggest you read through the source of gloss, trying to track down the original definition point of a few functions randomly chosen while reading the source. if you don't have trouble with that, your users won't have trouble with your zip-util thing
16:39amalloyand, you might not. potemkin drives me nuts, but beyond what is rational really
16:40RaynesAnd I think amalloy and I share generally exactly the same opinion on potemkin.
16:41kovasjonasen: I've run the free transactor with session, seems to work OK
16:42jonasenkovas: sorry, I misread your code. You do check for a schema attribute in connect-database
16:42kovasjonasen: ok, I think I had both at one point.. forgetting my own code :)
16:42mpenetflatland.useful.ns/alias-ns feels better, it's a good tradeoff between potemkin import-fn and tons of require declarations, as long as you don't abuse that stuff
16:43bbloomRaynes & amalloy: i dunno, doesn't seem *too evil* to me.... although it breaks down when you have bbloom.zip-util and amalloy.zip-util
16:43amalloyugh, alias-ns is worse
16:43mpenetoh ?
16:43Raynesbbloom: Look at what it takes to make this crap happen.
16:43RaynesIt might turn you off of it.
16:43amalloyit makes it actually-impossible to track down where a function came from
16:44bbloomRaynes: i looked at it. it's an ugly copy paste of metadata
16:44amalloyi forget the syntax, but: (alias-ns useful.seq) (alias-ns useful.map) (map-vals m f) ;; where does map-vals come from?
16:47bbloomi agree with you guys that all of these solutions leave something to be desired, but i think that there is a legitimate use case for composing namespaces....
16:47bbloomdo you have a better proposal?
16:48kovasjonasen: I'm gonna take off for a while, will be on IRC later
16:48kovas(hopefully)
16:52bbloomthere are two use cases: 1) organize the backing code for some public api into multiple files, but preserve one namespace
16:52bbloomand 2) alias names locally in a union/merge fashion
16:53bbloomthe former falls down when you want to extend somebody else's namespace
16:53bbloomthe latter is slightly more effort
16:53bbloomi guess i'll just deal with zip and zipx for now
16:53bbloombut i don't have to like it :-P
16:54Raynesbbloom: I guess we wont change your mind. I'm just expressing my own hatred for potemkin, because I personally have had a lot of trouble with libraries that use it.
16:54bbloomRaynes: and i'm going to trust you on that, but i'm saying that the shortcomings are probably implementation failings, not something inherent
16:54bbloomie the stacktraces suck
16:55bbloomor something similar
16:55bbloomno?
16:55clojurebotno is tufflax: there was a question somewhere in there, the answer
16:55amalloyRaynes: it sounds like you did just change his mind
16:58Raynesbbloom: I really don't like the goal, even with a perfect implementation. I prefer knowing exactly where things come from. It's a similar problem to :use
16:58AnderkentRaynes: with a good implementation you'll know where stuff came from anyway, it's one extra find-def press more...
16:59RaynesLook
16:59RaynesI'm right. You're wrong. Just let it go.
16:59Raynes:P
16:59AnderkentI don't really care if something comes from my.project.internal.maths.discrete most of the time, I just want it under my.project.core
17:00RaynesIt's easier if you guys stop having conflicting opinions!
17:00bbloomRaynes: you're only right because i have bigger fish to fry :-P like making this damn library work at all
17:00clojurebothttp://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png
17:01bbloomRaynes: also, i think that many of the problems with it are due to some rough ugly spots in clojure's var/symbol/etc handling
17:01bbloomRaynes: the biggest issue is: when do top level forms run inside a file? at compile time or at runtime? on the jvm, there isn't a difference really, but it's a big issue for clojurescript
17:02bbloomconsider (when false (def x 1))
17:02bbloomobviously a stupid edge case
17:02bbloombut illustrates the issue
17:02gfrederickson cljs that happens at code-load-time, right?
17:03bbloomgfredericks: in cljs x would be defined unconditionally
17:03gfredericksif(false){_.x = 1}
17:03gfrederickswat
17:03bbloomwat indeed.
17:03gfredericksjust because that's how def is handled?
17:03bbloomyeah
17:03gfrederickssweet
17:05technomancyI think nstools addresses most of the problems immigrate is designed to handle, but in a much more elegant way
17:06bbloomgfredericks: notice how parsing 'def unconfiditionally modifies the current namespace: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/analyzer.clj#L324
17:06bbloomtechnomancy: what's your opinion on the namespace discussion?
17:07gfredericksbbloom: I notice!
17:08bbloomgfredericks: it makes me sad, but to fix it, you'd need to have a -main function or something
17:08gfredericksbbloom: because gclosure doesn't like top-level code?
17:08bbloomgfredericks: no, b/c the top level of clojure complects run and compile time
17:09bbloomgfredericks: it's too bad that clojure.core isn't divided up into clojure.core and clojure.compiler or something like that
17:09gfredericksso we could do it but we don't want to?
17:09bbloomgfredericks: it would be a pretty big breaking change, so not gonna happen
17:10gfrederickswhat would it break? people who rely on (if false (def something))?
17:10bbloomgfredericks: it would break any side-effectual code at the top level of a module
17:11bbloomthe issue is that the environments are different. consider the *warn-on-reflection* var, which is often set! to true
17:11bbloomthat var doesn't exist/matter outside the compiler at runtime
17:12gfrederickswe're talking about fixing (if false (def something)), right?
17:12technomancybbloom: I don't like immigrate. I agree that it can be awkward sometimes, but I think nstools takes care of the awkwardness in a much more straightforward way.
17:13bbloomtechnomancy: are you referring to http://code.google.com/p/clj-nstools/ ?
17:13technomancyyeah
17:13Raynesgoogle code
17:13Raynesevil one
17:13technomancymaybe it's worse if you use a lot of protocols, but the solution to that is easy: use fewer protocols
17:13technomancyRaynes: well the project dates from the days that Clojure was on Google Code
17:13technomancyso they get a pass
17:14bbloomi use damn near zero protocols :-P
17:14Raynestechnomancy: I fixeded the bug in laser and I've got a decent test suite that passes. Once I get refheap mostly moved to it, I'll be announcing it on a wider scale.
17:14RaynesI'll overthrow the Enlive militia if it kills me.
17:14technomancyRaynes: cool. if I find myself needing HTML at some point in the future I'll give it a look.
17:15Rayneso/
17:15technomancy\o
17:15Raynestechnomancy: So, after last night I might be moving refheap back to my VPS when I get a bit of time. Don't hate me if I do. :(
17:15RaynesI know it isn't all Heroku's fault, but man, 10+ hour downtime...
17:16technomancyyeah, can't blame you
17:16amalloythose poor folks who wanted to wrap up a paste for their children...
17:16technomancyI don't imagine refheap would be much administrative overhead on a VPS anyway
17:17Raynesamalloy: It was truly heartbreaking.
17:17Raynestechnomancy: I moved to Heroku just because of how prone pastebins are to DDOS attacks.
17:17RaynesI don't know how to handle that crap.
17:17RaynesI could of pastebins have shut down over it.
17:18amalloyRaynes: actually i found a christmas present on refheap: https://www.refheap.com/paste/7851
17:18Anderkentthat last sentence didn't parse
17:18clojurebotthe previous sentence is false
17:18Raynesamalloy: o/
17:20silasdavishow can I require an java module from a local jar file
17:20silasdavisI have tried copying it to lib
17:20gfrederickslein doesn't like that
17:20gfrederickslein really wants that jar to be in a maven repo
17:21silasdavisah
17:21silasdavisI'll do that then
17:22silasdavishow do wildcard requires? zephyr.android.HxMBT.*
17:23gfredericksyou can't. (:import [zephyr.android.HxMBT OneClass AnotherClass OneMoarClass ...])
17:23TolstoyTrying to get the lein-cljsbuild working, but keep seeing this in by browser log: TypeError: 'null' is not an object (evaluating 'parentElm.appendChild'). Anyone know what's up with that?
17:24TolstoyOtherwise, the clojurescript stuff works.
17:28TolstoyMaybe the instructions have left out a critical assumption. I'm assuming you can do this via an index.html page (as per the ClojureScript wiki doc).
17:29AnderkentCan I use memoize to speed up a self-recursive function? How do I refer to the memoized version?
17:31technomancyAnderkent: memoization would require stack-consuming recursion; `recur` skips it
17:31Anderkenttechnomancy: not tail recursive I'm afraid
17:31gfredericksAnderkent: alter-var-root should work
17:31bbloomwouldn't (def f (memoize (fn [x] ... (f y))) be fine?
17:32gfredericksbbloom: that too
17:32technomancysure
17:32gfrederickswait does it?
17:32gfredericksI guess so.
17:33Anderkentthanks, that does it
17:33gfredericksbut we need to use alter-var-root more for technomancy's sake
17:33technomancyso I can yell at you more?
17:33gfredericksit's what I wake up for
17:34Anderkentit's how you wake up
17:34Anderkent:)
17:34technomancybut I'm fine with non-runtime use of it
17:34technomancy~gourds
17:34clojurebotSQUEEZE HIM!
17:39ziltiI'll never understand how clojurebot decides when to come up with a random-yet-fitting phrase. There must be a human locked up in that bot's JVM.
18:21Rich_MorinIn "(fn foo [] ...)", is foo only used to allow recursion?
18:21danlarkinsometimes also to allow for easier-to-read stacktraces
18:22Rich_Morinpoint; tnx
18:22yogthosit's also what defn does under the covers
18:22bbloomRich_Morin: to clarify, it's very different from (let [foo (fn [] ...
18:22yogthos(macroexpand '(defn foo [])) => (def foo (clojure.core/fn ([])))
18:23yogthoslol not quite I guess :)
18:23yogthosshould've read it first lol
18:23Rich_Morintnx all!
18:24bawr(macroexpand '(defn foo [x y] x))
18:24ziltibbloom: In what is it that different from (let [foo (fn ?
18:24bawr&(macroexpand '(defn foo [x y] x))
18:24lazybot⇒ (def foo (clojure.core/fn ([x y] x)))
18:24yogthosoh nice
18:24bbloomzilti: the let establishes a binding available to all future bindings and to the body of the let. where as (fn foo ...) establishes a binding only available inside the fn
18:25bawrbbloom: what do you mean "to all future bindings"?
18:25yogthosI guess if you rebind it later inside the let?
18:25bbloom,(let [f (fn [x] x) g f] (g 1))
18:25clojurebot1
18:26bbloom,(let [z (fn f [x] x) g f] (g 1))
18:26clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: f in this context, compiling:(NO_SOURCE_PATH:0)>
18:26bbloomi mean later bindings in the same let
18:26bawrAah.
18:26bawrI see.
18:26bbloomlets occur in series
18:26yogthos&(let [x 1] (let [x (inc x)] (println x)))
18:26lazybot⇒ 2 nil
18:26yogthosis that what you meant?
18:28bbloomwhat i mean is that let bindings occur in series, such that each pair is available in the lexical context of the initialization expression, or if the last binding, in the body of the let
18:28yogthosah ok
18:29yogthoslike let* in cl
18:29bbloomyogthos: right
18:29bbloomif you need parallel let, like in cl, you can use letfn
18:29bbloomwhich allows for mutually recursive definitions
18:30yogthosah I haven't considered that
18:30ziltiBy parallel let do you mean being able to call functions defined later in the letfn?
18:30yogthosI always took clojure style let for granted
18:30bbloomzilti: in a letfn, all bindings occur simultaneously and are available in each other's lexical scopes
18:31ziltibbloom: Good to know, didn't know that.
18:31bbloomyeah, it's very intentional: you only need parallel bindings for mutual recursion. mutual recursion doesn't make sense in data structures, only with delayed evaluation, like in the case of functions: hence letfn
18:32bbloomdoesn't make sense in PERSISTENT/IMMUTABLE data structures, i mean
18:32yogthostoday I learned :P
18:32yogthosI wondered about letfn before, this makes perfect sense though
18:33bbloomin CL, where most of the data structures are mutable, it makes some sense to be able to have mutually recursive pointers occuring. the bindings are established in parallel, but the init expressions are evaluated in series
18:33ziltiI always thought it to be a "convenience function" but never figured why that very slight gain in characters would justify it :)
18:33yogthosditto
18:33yogthosas always it turns out there's a deeper meaning there
18:36gfredericks(doc letfn*)
18:36clojurebotExcuse me?
18:36gfredericks,(doc letfn*)
18:36clojurebotHuh?
18:36bbloomno *
18:36bbloom(doc letfn)
18:36clojurebot"([fnspecs & body]); fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+) Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body."
18:36zilti,(doc letfn)
18:36clojurebot"([fnspecs & body]); fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+) Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body."
18:36gfredericksbbloom: letfn* is the special form I think
18:37gfredericks,(macroexpand '(letfn [(a [] 2)] 42))
18:37clojurebot(letfn* [a (clojure.core/fn a [] 2)] 42)
18:37ziltiDoes that * have a special meaning in Clojure/Lisp? I noticed it being used for the composable variants of functions in sqlkorma and Lamina.
18:37bbloomgfredericks: the true underlying special forms are an implementation detail :-)
18:37gfrederickszilti: it gets used to mean several different things
18:37bbloomzilti: x* just means "like x but slightly different"
18:38bbloomsimilar to x' which means "a new value of x"
18:38bbloomand *x* means "x is a dynamic var"
18:38bbloombut these are just conventions, not enforced
18:38gfredericksbbloom: I thought doc responded to special forms though
18:38gfredericks,(doc var)
18:38clojurebotHuh?
18:38gfredericks&(doc var)
18:38lazybot⇒ ------------------------- var (var symbol) Special Form The symbol must resolve to a var, and the Var object itself (not its value) is returned. The reader macro #'x expands to (var x). Please see http://clojure.org/special_forms#var nil
18:39gfredericks&(doc letfn*)
18:39lazybot⇒ nil
18:39gfrederickshrm
18:40bbloomgfredericks: it's a hardcoded hack: https://github.com/clojure/clojure/blob/master/src/clj/clojure/repl.clj#L18
18:43tpopebbloom: I have a proof of concept stacktrace parser. I'm struggling with how to reliably get my hands on the stack trace
18:43ziltiHell, we have 2012 and copying files does not ensure them being consistent
18:43bbloomtpope: do you ever make anything for clients/employers/etc? or do you just only make awesome stuff for those of us who stalk your github profile?
18:44yogthoshaha
18:44tpopebbloom: I make vim plugins till I'm broke, then take the first shitty rails contract I can get my hands on :/
18:44yogthosmy trick is to make a project first and then use it at work :P
18:45tpopewith any luck I'll be able to change that to "first shitty clojure contract" soon enough
18:45bbloomtpope: enjoying clojure?
18:45tpopeso far so good
18:45bbloomcool
18:45tpopesometimes I feel it's like 5 times too smart for me
18:46bbloomok well what's the stack trace issue? my stack trace skills are weak, but i might be able to provide some insight
18:46RaynesI'm of the opinion that if you can do vimscript, you're smart enough for Clojure
18:46bbloomtpope: nah, you just need to unlearn so many things you take for granted. it's just different
18:46yogthosit is for sure
18:46yogthosbut it's really self consistent which helps a lot
18:46tpopebbloom: I want to make it so that if evaling something gives an error, the stack trace is prepopulated into the location list
18:46yogthosyou learn one concept and you can just apply it everywhere :)
18:47tpopemakes sense, right?
18:48tpopeRaynes: I remain optimistic
18:48tpopebbloom: biggest challenge. how do I get the stack trace out of nrepl?
18:49tpopeI can eval (.getStackTrace *e), but then I've stepped on *1, etc
18:50Raynestpope: (def temp *1) (.getStackTrace *e) (def *1 temp)
18:50bbloomRaynes: that would modify *2 and *3 :-P
18:50tpopeyeah
18:50RaynesFix them all.
18:50RaynesRawr.
18:50tpopeplus now I've dumped a temp var in the user's repl
18:50bbloomtpope: probably should ask cemerick, since *e etc are repl features
18:50bbloomnot evaluator features
18:51Raynestpope: That's what gensyms are for.
18:51tpopeI could gensym it or something, but this is starting to get hairy
18:51RaynesHacks are hack.
18:51bbloomnrepl provides multiple different commands other than "eval" right?
18:51tpopeyes
18:51tpopeI haven't exhaustively searched them
18:51bbloomis there a "get-var" command?
18:52tpopeI guess I should
18:53bbloomhttps://github.com/clojure/tools.nrepl/blob/master/doc/ops.md
18:53tpopeyeah just remembered where it was
18:53tpopeI don't see anything
18:54bbloomtpope: you could clone the session and then eval whateve ryou want
18:54tpopeooh, cloning might work
18:54bbloomclone, eval, close
18:54tpopeconvoluted, but cleaner
18:54bbloommmm immutability :-)
18:54bbloomcheap clones
18:54bbloomno idea what *actually* happens when cloning
18:55bbloombut i assume clone works
18:55yogthospresumably just a reference ;)
18:55yogthosand then it modifies its own tree from there right
18:55bbloomyogthos: right, my concern would be what happens with :stdin and :stdout
18:55yogthosmmm good point
18:58bbloomhmmm tpope, actually clone may not help
18:58bbloom,#'*1
18:58clojurebot#'clojure.core/*1
18:58tpopewhat are the odds on that may?
18:58bbloomthey *might* be dynamically rebound, such that each session gets their own
18:59bbloombut otherwise they are global mutable cells, rather than session data
18:59bbloomwhich seems odd, i'd assume nrepl needs to support multiple different *1
18:59bbloomso i'd say it has like an 85% chance of working :-)
18:59tpopeI estimate a half hour of bumbling around just to try it :/
18:59bbloom,(:dynamic (meta #'*1))
18:59clojurebottrue
19:00bbloomok, 92% chance of success
19:00bbloom:-)
19:03tpopecool, foreplay shits itself on the nrepl source
19:04bbloommmm metacircular
19:44tpopebbloom: doesn't work
19:44bbloomsad day :-(
19:44bbloomwhy not?
19:44tpopebbloom: also found https://github.com/clojure/tools.nrepl/blob/9b1fc6807cf87ad487887b1701abd1462028f635/src/test/clojure/clojure/tools/nrepl/sanity_test.clj#L113-134 :(
19:45tpope*e is nil in the cloned session
19:45bbloomtpope: seems like a bug
19:46tpopeI suppose I could open an issue. A nice little xmas gift for cemerick
19:46bbloomtpope: tools.nrepl is tracked w/ jira
19:46tpopeoh boy!
19:46bbloomdev.clojure.org
19:47bbloomi think you need a signed contributor agreement to open an issue there
19:47bbloommight be best to just email him :-P
19:47tpopeI'll grab him in the channel sometime
19:47bbloomk
19:54hyPiRionbbloom tpope: No need to sign a CA for issue reporting
19:54bbloomah ok thanks hyPiRion
19:54tpopecheers
19:54hyPiRionJust create an account there, and describe the issue :)
19:54bbloomhyPiRion: but you still do need to deal with jira :-P
19:55tpopethis is less an issue and more a question anyways
19:55hyPiRionAh
19:57ravsterhello everyone
19:57hyPiRionhey
20:11ziltiHere's my first "production-ready" micro-library: https://github.com/zilti/cynomys
20:28mindbender1library authors, is there a significant perf diff in using sth
20:28mindbender1 like (foo {:bar ["baz"]}) as opposed to (foo :bar ["baz"])
20:29yogthosdepends on how you use it I find
20:29yogthosif you want to pass in some parameters I'd use it the second way
20:30mindbender1yogthos: so what has been your finding cos I see a pervasice use of (foo :bar ["baz"]) among many clojure authors
20:30mindbender1whereas I expect idiomatic usage of (foo {:bar ["baz"])
20:30yogthoswell for example in my markdown-clj lib I do this for allowing specifying a code style tag (md-to-html "```code```" :code-style #(str "class=\"" % "\"")))
20:31yogthosif it's something that specifies the environment options for example
20:31yogthosI find people tend to use the :flag foo notation
20:31RaynesBahahaha
20:32Raynesyogthos: I forgot that you're the dude who did markdown-clj.
20:32yogthos:P
20:33RaynesSo now I have to explain myself.
20:33yogthoshehe
20:33yogthoslol you opened a couple of bugs on it too :)
20:34Raynesyogthos: So, I complained about you using markdown-clj in lib-luminus.
20:34yogthosyeah you said you use pegdown for refheap right?
20:35Raynesyogthos: The primary reason why is because pegdown is just so great. It supports a whole bunch of extensions. It isn't that markdown-clj is bad as much as pegdown does more and is concisely used from Clojure. I'm not even sure it'd be worth writing a wrapper library for it, but it might be because extensions are calculated using bit-or which might confuse Clojure people not coming from Java.
20:36RaynesIs there a big reason for markdown-clj? Some reason pegdown wasn't sufficient?
20:36yogthosmain motivation was to make something that runs both in clojure and clojurescript :)
20:36yogthosfor example in my blog I want to preview posts/comments
20:36yogthosand if you have a different js implementation of markdown it's not guaranteed to look the same when the server renders it
20:37yogthosbut yeah it's not nearly as featureful as pegdown
20:37RaynesThat makes sense.
20:37yogthosthanks :)
20:37yogthoslol originally I did it for lulz
20:38mindbender1yogthos: what would have been the difficulty if you have chosen the other implementation because that is stillgoing against Rich Hickey's I don't know I don't want to know
20:38yogthosI read a post from Brian Carper about how he used a rhyno to run js interpreter for his blog to make sure md rendered the same
20:38Raynesyogthos: Anyways, I just wanted to explain my reasoning, since I was pretty mean about it yesterday.
20:38yogthosso I was like can't be that bad to parse md, turns out it's not trivial to do it right :P
20:39yogthosno prob dude, I'm actually surprised it got as popular as it did
20:39yogthosall of a sudden people started starring it on ghub and I was like ok I guess I should fix it up so it's not completely lame :P
20:39mindbender1Same question goes to others
20:40mindbender1all these is still not heloing with the order problem
20:40mindbender1helping
20:40Raynesyogthos: I think I'll throw together a little wrapper library for pegdown.
20:40yogthosyeah that'd be cool
20:40RaynesAnd perhaps use that in lib-noir, adding an optional extensions arg to md->html
20:40yogthospegdown is pretty slick for sure
20:41yogthosthat'd be nice, I moved the function to the template for now btw
20:41RaynesWell that'd be fine too.
20:41yogthosbut yeah I was thinking about it
20:41yogthosI think it'd be best to keep libs in lib-noir and config in the template
20:42yogthosthis way it makes updating libraries easier
20:42RaynesA pegdown wrapper would still be useful though. I had an issue with it and numbers a while back that I had to fix by explicitly wrapping something in (int ..) but most people would just give up and not use pegdown, thinking it broken.
20:42yogthosif too much stuff gets into template, then people are gonna have a hell of a time upgrading their apps
20:42RaynesSo I'll still do that either way.
20:42yogthosyeah let's get a pegdown wrapper in lib-noir and I'll move md->html back there after :)
20:43ibdknoxa pegdown wrapper should be its own lib
20:43Raynesibdknox: Duh.
20:43yogthosright yeah, we include the lib in lib-noir :)
20:43Raynesibdknox: Always planned for a separate library.
20:43ibdknoxyogthos: in terms of using md in cljs, I just use some the JS markdown things
20:43ibdknoxrighto
20:43Raynesibdknox: Go back to light table and leave the lib-noring to me.
20:44Raynes:P
20:44Raynesibdknox: (totally kidding)
20:44ibdknoxlol
20:44yogthoshehe
20:44ibdknoxsee.. Raynes is mean.
20:44Raynesibdknox: His reasoning for having a lib that works in both places is so that markdown renders the same.
20:44RaynesThe problem is that markdown sucks because it doesn't have a standard that everyone follows.
20:44ibdknoxah
20:44RaynesOtherwise this wouldn't be a problem.
20:44ibdknoxindeed
20:44yogthosthe whole thing stemmed from this http://briancarper.net/blog/415/clojure-and-markdown-and-javascript-and-java-and
20:45yogthosthat's the beauty of md it's such a loose "standard" :)
20:45yogthosevery implementation does it a bit different
20:45ibdknoxwell maybe Jeff Atwood 's quest will succeed
20:45yogthoshaha
20:45RaynesYou see beauty in strange things, sir.
20:45ibdknoxIt would be nice if it did
20:46yogthosmindbender1: what was the question btw?
20:46RaynesIt sure would.
20:46yogthosthe worst thing about md is that it has redundant syntax for no apparent reason, like stwo eparate heading declarations
20:47ibdknoxyeah
20:47yogthosand list behavior is largely undefined
20:47yogthoswhat can go inside lists, how the spacing works, etc
20:47ibdknoxI love doing things with GFM though
20:47yogthosbtw could also link this in lib-noir :) https://github.com/yogthos/clj-pdf
20:48yogthosI was looking through django features
20:48yogthosand they have a pdf renderer
20:48yogthoscan be nice for some stuff like reporting
20:49ibdknoxI wonder if it just makes sense to point to these sorts of things in some canonical up-to-date place on webnoir
20:49ibdknoxthat's largely the problem
20:49ibdknoxit's impossible to find this stuff
20:49yogthosyeah I know
20:49yogthosactually I heard from clojars guys that they plan to add number of downloads stats for libs
20:49yogthosthat would help a lot
20:49ibdknoxyes it would
20:49yogthoscause then you can see which libs people are using and what the health status is
20:50yogthosmaybe could also show the frequency of updates
20:50yogthosand then you could sort by that :P
20:50yogthosI really think this has to be some automated feature not people aggregating libs by hand on some site
20:50yogthosthat's just not sustainable
20:50bbloomyogthos: i wish github would bring back traffic stats too!
20:50ibdknoxbbloom: me too
20:50yogthosyeah I know!
20:51bbloomthe one down side to the automated approach is that it benefits incumbents
20:51yogthosbut yeah seing how lein is the pretty much defacto standard it makes sense to track it through clojars
20:52yogthostrue, but you could have different filters too, like activity
20:52yogthosnew libs will have more activity than mature ones for example
20:52yogthosand it could give a combined weighted score too when sorting
20:53bbloomyogthos: i'd want to sort by the first differential of the number of new projects depending on that lib :-)
20:53bbloomie show me what people are switching to
20:53yogthosthat's a good idea
20:55mindbender1yogthos: I'm just saying work hard to hide implementation details
20:56yogthosyeah that I definitely agree with
20:56yogthoswhat's the context though?
20:57mindbender1It's just that when I see that form of order I ask myself why couldn't amap work here
20:59yogthosah
20:59mindbender1like they say eventual consistency is hard for programmers
21:00yogthosI don't think it's that bad in this particular context though, optional flags come at the end is not a bad convention
21:00mindbender1those can work in maps too
21:00yogthosand it does make it a bit more readable I find, but admittedly not that much
21:00mindbender1they are very open
21:01mindbender1it allows your code to work in a threaded program
21:02yogthosI think it does mostly come down to aesthetics
21:02yogthosand realistically, you still have to read the docs to know what to pass in
21:02yogthosso it's not that using a map is going to make that any better
21:03mindbender1but then you remove the order
21:03mindbender1and save users the headache of syntac
21:03mindbender1syntax
21:03yogthostrue, but I think the headache is mostly perceived in this case no?
21:04mindbender1when it builds up with other programs
21:05yogthoscan you give an example of what you mean?
21:05mindbender1when I think of your syntax with a gazillion other syntax I have to think about
21:06yogthosbut there's not much syntax in clojure to being with to be fair
21:06yogthosI keenly feel that point when working with scala for example
21:06yogthosevery 5 min or so I end up googling how to do this or that correctly
21:06mindbender1actually I was reading pallet before I came here to whine
21:06yogthoshehe
21:07mindbender1so? clojure authors seem to want to make sure it arrives
21:08mindbender1Actully I don't even know why project.clj adopted a similar syntax
21:09mindbender1maybe we should stop using maps
21:09yogthoswell you kind of need actual maps in most cases
21:10yogthosthing that bothers me more is the cons/conj behavior :)
21:10mindbender1have you listened to stu's data oriented programming
21:11yogthosyup
21:11mindbender1I think he shared some luv there
21:24gfredericksit disappoints me sometimes that clojure maps aren't Comparable
21:24gfredericksis no comparator better than an arbitrary one?
21:25gfredericksI always enjoyed erlang's built-in total-ordering-over-all-types
21:25gfredericksI guess there could be no efficient ordering
21:26gfrederickserlang doesn't have maps :)
21:26hyPiRionhow would you compare them?
21:26yogthoswell you could check how many keys match?
21:26yogthosbut that's definitely expensive
21:27gfredericksignoring the efficiency question, it could be anything.
21:27hyPiRionWell then, what's the value of sorting them?
21:27yogthosso the more keys match the closer they are to each other, there's definitely situations where that can be useful
21:27yogthosany sort of fuzzy logic
21:27gfrederickshyPiRion: I'm often interested in canonical representatives in sets of maps that aren't in a particular order
21:28gfrederickse.g., from a db query
21:28yogthosthat's actually a good example, say you have users in db and you want to find duplicates
21:28gfredericksyogthos: first compare (sort (keys m1)) with (sort (keys m2)), then if those are equal do the same with the values; that depends on both keys and values being comparable though
21:29yogthosyeah it's not hard to implement ;)
21:29bbloomi think the fact that it's not obvious how to compare them implies that, yes, no comparer is better than an arbitrary one
21:29gfredericksbut I imagine that a vector's comparability depends on its entries as well
21:29gfredericks,(sort [[] [2] [4]])
21:29clojurebot([] [2] [4])
21:29gfredericks,(sort [[] [{2 2}] [{}]])
21:29clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Comparable>
21:29gfredericksyep
21:30gfredericksbbloom: well if it were obvious how to compare them then there'd be no reason to suggest an arbitrary one; my point was that an arbitrary ordering can have utility, even if it's an inscrutible black box
21:31yogthosI suspect that could lead to some hard to track down errors too though
21:31hyPiRionIt's more evident to write, say
21:31hyPiRion,(sort-by count [{} {:a 4} {:a :b :c :d}])
21:31clojurebot({} {:a 4} {:a :b, :c :d})
21:31hyPiRionthan just sort.
21:32hyPiRionI guess that's why, mostly.
21:32gfrederickshyPiRion: certainly in situations where you care how it's sorted, yes
21:33gfredericksoh wait wouldn't c.c/hash allow a usually-efficient ordering?
21:33hyPiRiongfredericks: I was just thinking about that
21:34hyPiRionIt's consistent, as long you don't have mutables within the maps
21:34gfrederickswhich is lame to begin with
21:34hyPiRionAND it's totally ordered, sans collisions.
21:34gfrederickson collisions you just do some difficult slow thing
21:35hyPiRionanother hashing
21:35hyPiRionwith different algorithm
21:35gfredericksor just compare (sort m1) with (sort m2)
21:36gfrederickshaha would that be (sort-by sort my-maps)? :D
21:36gfredericks,(sort-by sort [{:a 12} {:b 17 :c 15} {} {:a 12}])
21:36clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.ArraySeq cannot be cast to java.lang.Comparable>
21:36hyPiRionnope, more like..
21:37gfredericksconsarnit
21:37gfredericks,(sort-by (comp vec sort) [{:a 12} {:b 17 :c 15} {} {:a 12}])
21:37clojurebot({} {:a 12} {:a 12} {:c 15, :b 17})
21:37gfredericksthere it goes
21:37hyPiRionGosh darnit, I need two maps with the same hash to test it out
21:38hyPiRion,(sort-by (comp vec sort) [{:a 12} {:b 17 :c 15} {} {1 12}])
21:38clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.Keyword>
21:38gfredericksoh the hashing does give you more flexibility about types doesn't it
21:38hyPiRion,(mapv hash [{:a 0} {:a nil}])
21:38clojurebot[1013910569 1013910569]
21:38hyPiRionright.
21:39gfredericks(def other-hash (comp hash pr-str))
21:39hyPiRionBlugh, hahah.
21:39hyPiRion,(sort-by (comp hash pr-str) [{:a 12} {:b 17 :c 15} {} {1 12}])
21:39clojurebot({:a 12} {1 12} {} {:c 15, :b 17})
21:40hyPiRionActually, god damnit
21:40hyPiRion,(sort-by pr-str [{:a 12} {:b 17 :c 15} {} {1 12}])
21:40clojurebot({1 12} {:a 12} {:c 15, :b 17} {})
21:40gfrederickslerlz
21:40hyPiRionThat's totally ordered, too.
21:41hyPiRion,(sort-by pr-str [{2 12} {:b 17 :c 15} {1 13} {1 12}])
21:41clojurebot({1 12} {1 13} {2 12} {:c 15, :b 17})
21:41gfredericksunless you want it to distinguish between types that print the same
21:41hyPiRionWell, if you're that guy, then fuck you.
21:41gfredericksyeah fuck him
21:41hyPiRionBecause this is good enough
21:41gfredericksalright go commit it to core so we can make it into 1.5
21:42gfrederickswe've hammock'd enough
21:42hyPiRionYeah, rhickey would surely add this in
21:42yogthosrofl
21:42hyPiRionFoolproof.
21:43gfredericksit doesn't have the erlang elegance where the ordering of X and Y where X and Y are different types is dependent only on the types
21:43gfredericksI think couchdb does that too
21:43hyPiRionI'm working on a patch now
21:43gfredericksit helps to have a closed set of types
21:44gfredericksif we get into class names then we'll conflict with clojure's multiple-classes-per-datastructure approach
21:46bbloomthere is no mutually exclusive list of protocols, which is on purpose
21:46bbloomyou can have a map that is also a vector, if you really wanted to
21:46bbloomin fact, vectors already are maps....
21:46gfrederickssorta?
21:46gfredericks,(map? [3 4])
21:46clojurebotfalse
21:46gfredericksso not in every sense at least
21:46hyPiRionVectors aren't maps
21:47bbloom(doc map)
21:47clojurebot"([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & ...]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."
21:47bbloom(doc map?)
21:47clojurebot"([x]); Return true if x implements IPersistentMap"
21:47bbloom,(instance? IAssoc [3 4])
21:47clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: IAssoc in this context, compiling:(NO_SOURCE_PATH:0)>
21:47bbloom,(instance? IAssocative [3 4])
21:47clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: IAssocative in this context, compiling:(NO_SOURCE_PATH:0)>
21:47gfredericksbbloom: clojure.lang maybe
21:47bbloom,(instance? IAssociative [3 4])
21:47clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: IAssociative in this context, compiling:(NO_SOURCE_PATH:0)>
21:47bbloom,(instance? clojure.lang.IAssociative [3 4])
21:47clojurebot#<CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.lang.IAssociative, compiling:(NO_SOURCE_PATH:0)>
21:47hyPiRionVectors has an ordering, whereas maps have no ordering
21:48gfrederickshyPiRion: that's not a convincing argument
21:48bbloomdur, no I
21:48bbloom,(instance? clojure.lang.Associative [3 4])
21:48clojurebottrue
21:48bbloom,(instance? clojure.lang.Associative {3 4})
21:48clojurebottrue
21:48bbloom,(assoc [0 1 2 3] 2 :omg)
21:48clojurebot[0 1 :omg 3]
21:48gfrederickshyPiRion: vectors behave similarly to maps in some cases, as bbloom is demonstrating
21:49gfredericks,(dissoc '[a b c d] 3)
21:49clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap>
21:49hyPiRionClearly.
21:49gfrederickshyPiRion: sorted-maps are also ordered
21:50bbloomthe point i'm making is that you can't sort by type like you can in erlang b/c erlang has a closed set of mutually exclusive types
21:50gfredericksbbloom: yeah, I was sort of realizing the same thing
21:50bbloomeffectively there is one type: a discriminated union of each of the primitive types
21:50gfredericksabout fifteen inches up
21:51bbloomhonesly, if i had my way, it wouldn't be possible to compare two things of different types at all. at least not without first promoting them to some other type that can represent all possible values for the types of both arguments
21:53bbloomwhich is sorta what happens defacto anyway
21:53hyPiRionYou got what you wanted then, hurray
21:53bbloom,(compare :foo 'foo)
21:53clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.Keyword>
21:53bbloom,(compare 'foo :foo)
21:53clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.Symbol>
21:54gfredericks,(compare [1 2 3] (subvec [1 2 3] 1))
21:54clojurebot1
21:54bbloomgfredericks: logically speaking, you're promoting to sequences
21:55gfredericks,(compare (seq [1 2 3]) (seq (subvec [1 2 3] 1)))
21:55clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to java.lang.Comparable>
21:55gfredericksgotcha
21:55hyPiRionHuh
21:55hyPiRion"throw Util.sneakyThrow(e);" <<-- Within Clj source
21:55hyPiRionThat guy, he's sneaky.
21:56bbloomgfredericks: heh, i'm actually surprised by that
21:56bawrXD
21:56gfredericksbbloom: phew. I thought I would get accused of ignoring your word "logically"
21:57bbloomgfredericks: ok fine, logically promoted to clojure.lang.Sequential
21:57bbloomwhich apparently isn't comparable either lol
21:57gfrederickswell it's an interface
21:57gfredericksI guess it could extend comparable, eh?
21:58bbloomnow i wonder: why aren't seqs comparable?
21:58gfredericksmaybe the idea was that potentially infinite types shouldn't be comparable
21:58hyPiRionbbloom: They may be lazy and infinite.
21:58hyPiRionHave fun comparing that
21:58bbloomhyPiRion: dur. of course that makes perfect sense
21:58gfredericks,(compare (range) (rest (range)))
21:58clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Comparable>
21:58gfredericks,(compare (vec (range)) (vec (rest (range))))
21:59hyPiRionhah.
21:59bbloomgfredericks: poor little clojurebot
21:59bbloomhe works so hard
21:59gfrederickswhat does an eval server do for timeouts? Isn't killing a thread supposed to be unsafe?
21:59bbloomgfredericks: java have timeout security context feature thinggies
22:00gfredericksslick
22:00bbloom&(compare (vec (range)) (vec (rest (range))))
22:00lazybotExecution Timed Out!
22:01gfredericks,(println "yo?")
22:01clojurebotyo?
22:01gfredericksphew
22:01bbloomyou didn't kill it :-P
22:02gfrederickswe have had 0 days since the last (println "yo?")
22:07hyPiRiongfredericks: https://github.com/hyPiRion/clojure/commit/4ef68dc957efa8fb4ade95260cade47a93880ddf
22:08hyPiRionNow you have sortable maps
22:08hyPiRionToo bad it killed sorted-map though, all the sorted-map tests failed it seems.
22:08gfredericksif you're not breaking sorted-map you're not doing real work
22:08gfredericksthat's what my grandma always used to say
22:09hyPiRionGood thing I'm doing real work then!
22:09gfrederickshaha I love that commit message
22:10hyPiRionIt sounds like that's a feature, not a bug
22:11hyPiRion"1.5: sorted maps are now not only deprecated, they also have completely undefined behaviour"
22:14gfredericks"1.5: the syntactic role of parentheses and square-brackets have been swapped everywhere."
22:14gfredericksI wonder how much change in the java code that would require
22:15hyPiRion[let ((a b) (2 3)) [+ a b]] => 5
22:15hyPiRiongfredericks: Probably two lines
22:15gfrederickshyPiRion: and then a gsub or something over all the clj files
22:15hyPiRionWell, four,
22:15hyPiRionOh lordy
22:16hyPiRionThat's my new goal
22:16yogthosfork clojure and swap square brackets and parens? :P
22:17gfrederickshyPiRion: name in Dlojure
22:17bawrWhy are sorted maps deprecated? :<
22:17yogthosI think we're on to something here :P
22:17bbloombawr: they aren't. these guys are just joking around
22:18bawrGo deeper. ()->{}->[]->||
22:18bawrELIMINATE PARENS ALTOGETHER.
22:18yogthosor you could just do what scheme does and make them interchangable :P
22:19hyPiRionbawr: Sweet idea
22:19bawrOh, the wonderful ambiguities of trying to swap [] with one token. xD
22:19gfredericks(defmacro with-silly-delimeters [& forms] `(do ~@(map (partial wk/postwalk #(cond (vector? %) (list %) (seq? %) (vec %) :else %)) forms)))
22:19yogthosyou could name it dylan :)
22:19yogthoshttp://en.wikipedia.org/wiki/Dylan_(programming_language)
22:20hyPiRiongfredericks: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L91-94
22:20amalloygfredericks: you probly want list*
22:20bawrhyPiRion: But once that proves to be impossible, hey. []-><> can work, too.
22:20yogthos4 lines it is
22:20gfredericksamalloy: ah that's why it doesn't work
22:20gfredericksthat did it
22:21hyPiRionIt's amazing that all these Clojure things I just joke around with makes me so knowledgeable around the internals
22:21gfredericksamalloy is the only person who reads my macros
22:22hyPiRion,(list* ())
22:22clojurebotnil
22:22bawrgfredericks: Oh I read it, I just didn't parse it. ;)
22:22hyPiRionit's not as easy as you'd like it to be
22:22gfrederickshyPiRion: maybe seq is better
22:22hyPiRion,(seq ())
22:22clojurebotnil
22:23hyPiRion:p
22:23gfrederickswhoops
22:23gfredericksof course
22:23gfredericks(or (seq %) ()) then
22:23hyPiRionSurely that's the best way of doing this.
22:23hyPiRionWait.
22:24hyPiRionyeah, that's the best way
22:24hyPiRionmust be.
22:39gfredericksman this reader code is so OO
22:39ibdknoxdo it with blind
22:41gfredericksokay with the power of google I cannot figure out what that cryptic comment meant
22:42ibdknoxsoon to be tools.reader: https://github.com/Bronsa/blind
22:43gfrederickseventually replacing the core reader? or what's the utility of making it a core lib?
22:45bbloomgfredericks: will probably become the reader for clojurescript
22:46bbloomand via that channel, will eventually replace the core reader.... at about the same speed pypy is replacing cpython :-P
22:46gfredericksclojurescript gets to have all the fun
22:46ibdknoxit's very useful for tools guys :)
22:47gfredericksclojure: a good language for building clojurescripts in
23:24amalloygfredericks, hyPiRion: ##(doc sequence)
23:24lazybot⇒ ------------------------- clojure.core/sequence ([coll]) Coerces coll to a (possibly empty) sequence, if it is not already one. Will not force a lazy seq. (sequence nil) yields () nil
23:25gfrederickswoah it's like the opposite of seq
23:43hyPiRionAll these core nuggets
23:43hyPiRion,(#'clojure.core/>1? 2)
23:43clojurebottrue
23:59technomancyslamhound is back ladies and gents