2012-12-25
| 00:19 | callen | muhoo: I wasn't aware he had kids. |
| 00:19 | callen | muhoo: somebody that tall must have a hell of a time bending underneath a Christmas tree. |
| 00:20 | callen | Raynes: it amuses me that all the companies that build on Amazon don't bother build in cross-region failover |
| 00:20 | callen | bother to build in* |
| 00:24 | muhoo | yikes, now googlecode is giving me 40s |
| 00:24 | muhoo | 404s |
| 00:25 | muhoo | heh, if googlecode was giving me 40s, i'd be spilling them on the ground in honor of all the fallen servers, yo |
| 00:25 | Raynes | Hahaha |
| 00:26 | muhoo | does googlecode use.... amazon? |
| 00:26 | Raynes | Whenever refheap goes down, netflix goes down, so I'm like "Yo, netflix is down too, yo." |
| 00:26 | Raynes | They have a team. I have a me. |
| 00:26 | muhoo | OK, WHO BROKE THE INTERNET? |
| 00:27 | muhoo | seriously, 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:28 | Raynes | Funfact: mics work better if you remember to plug them into the pramp. |
| 00:28 | Raynes | preamp* |
| 00:28 | muhoo | Raynes: setting up for a gig? |
| 00:28 | Raynes | Sure |
| 00:28 | Raynes | I've got a crowd of one person. Me in the mirror. |
| 00:29 | muhoo | check 1, 2, check 1, 2. 2. 2. 2 |
| 00:32 | muhoo | http://online.wsj.com/article/SB10001424127887324660404578200383908151240.html yep, netflix out too |
| 00:41 | Raynes | That awkward moment when you finish a massive vocal performance and realize you weren't recording it. |
| 00:46 | bbloom | Raynes: took a shower? |
| 00:46 | Raynes | ? |
| 00:47 | Sgeo | bbloom was thinking you were singing in the shower. |
| 00:47 | Raynes | I don't think I'd take a preamp into the shower. |
| 00:59 | Raynes | muhoo: Want some Raynesong for Christmas? |
| 01:00 | muhoo | sure! |
| 01:00 | muhoo | didn't know you were a musician |
| 01:00 | Raynes | I'm not, really. |
| 01:00 | Raynes | I just like to sing. |
| 01:01 | Raynes | And some people tell me I'm pretty good at it. |
| 01:01 | Raynes | So yey |
| 01:59 | ibdknox | Raynes: I got annoyed with entitlement http://www.reddit.com/r/Clojure/comments/15cspw/luminus_my_attempt_at_a_clojure_web_framework/c7ltq2b |
| 02:01 | yedi | you tell em |
| 02:01 | asina12 | i am using emacs+nrepl....how do people use it to navigate clojure source code? |
| 02:02 | yedi | ibdknox: on a somewhat related note: did you get to check out luminus at all? |
| 02:03 | ibdknox | yedi: 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:14 | muhoo | yep, with free software "if it breaks you keep both peices" |
| 02:20 | muhoo | the person to fix it can be found by looking in the nearest mirror |
| 02:48 | Raynes | ibdknox: Excellent. |
| 02:50 | Raynes | ibdknox: Loved every second of it. |
| 02:51 | Raynes | Would read again |
| 02:51 | ibdknox | lol |
| 02:51 | ibdknox | I've been getting this crap a lot lately, and it makes me sad. |
| 02:51 | ibdknox | I really, really try to help |
| 02:51 | ibdknox | but there's just only so much I can do |
| 02:51 | clojurebot | Pardon? |
| 02:51 | yedi | even clojurebot is givin you shit |
| 02:52 | ibdknox | lol |
| 02:52 | Raynes | ibdknox: Don't worry about it. I'll fight the good fight. |
| 02:54 | Raynes | ibdknox: I don't blame you for anything. By time you stopped maintaining Noir, I had already switched to Compojure for unrelated reasons. |
| 02:55 | Raynes | I maintained Noir (as much as I could) entirely as a service to the community. |
| 02:55 | ibdknox | I know, and thanks for that :) |
| 02:55 | Raynes | But it just got to be silly. |
| 02:55 | Raynes | The batteries included thing doesn't mean much when there are only three batteries. |
| 02:56 | ibdknox | and like I said, that whole thing is just a matter of a template |
| 02:56 | Raynes | I'm honestly surprised that having to add three deps instead of one is really upsetting people. |
| 02:56 | ibdknox | at that point they really are basically equivalent |
| 02:56 | bbloom | stop worrying about it guys |
| 02:56 | Raynes | Exactly. |
| 02:56 | bbloom | there will always be people who love frameworks |
| 02:56 | bbloom | they are wrong |
| 02:56 | bbloom | but they will always be wrong |
| 02:56 | bbloom | and once they learn better, there will be lines of framework lovers right behind them |
| 02:56 | bbloom | you'll never win |
| 02:57 | bbloom | so just bite your tongues and turn the other cheek and some other cheese sayings... then you'll be happier |
| 02:58 | Raynes | I think this template is going to go a long way. |
| 02:58 | ibdknox | yeah |
| 02:58 | Raynes | I'm going to try to help him with it and get info out there about it. |
| 02:58 | bbloom | basically just a lein newnew plugin? :-P |
| 02:58 | bbloom | a new newnew? |
| 02:58 | Raynes | I'm going to merge his lib with lib-noir in a few days after I look it over. |
| 02:59 | Raynes | Gonna be legendary. |
| 02:59 | Raynes | bbloom: Just a template for lein-newnew. |
| 02:59 | Raynes | lein-newnew is extensible. |
| 02:59 | bbloom | right, a new newnew template |
| 02:59 | Raynes | Yes. |
| 02:59 | bbloom | heh |
| 02:59 | ibdknox | the new newnew's new template for the new lib-noir style of writing new websites |
| 03:02 | Raynes | ibdknox: You know, both 4clojure and refheap use lib-noir+compojure |
| 03:02 | Raynes | Have for quite a while. |
| 03:02 | Raynes | It's pretty great. |
| 03:02 | ibdknox | :) |
| 03:02 | Raynes | Noir really had some great libraries. |
| 03:03 | ibdknox | eh, they're very simple :) |
| 03:03 | Raynes | They're still great though. |
| 03:03 | Raynes | I'm happy to replace sandbar's stateful sessions. |
| 03:04 | ibdknox | yeah, he dropped that a *long* time ago |
| 03:04 | ibdknox | it hadn't really been touched by the time I even started Noir |
| 03:05 | Raynes | bbloom: https://groups.google.com/d/msg/clj-noir/AbAvQuikjGk/mlYuC8ChW44J This sort of thing scares me though, man. |
| 03:05 | Raynes | Look at the planned features. At the end, he even lists "??? What else would you like this to do." |
| 03:06 | Raynes | Should have named it kitchen-sink |
| 03:06 | bbloom | Raynes: hey man, i get it. i built a serious app on rails |
| 03:06 | bbloom | it was *fucking awesome* |
| 03:06 | bbloom | until about 6 months later |
| 03:06 | bbloom | then it was *not so fucking awesome* |
| 03:06 | bbloom | all-in-one can be really really attractive if you're in a hurry |
| 03:06 | bbloom | particularly if it's popular |
| 03:06 | ibdknox | I don't think you have to sacrifice that ease though |
| 03:07 | bbloom | for all the absolutely horrible, evil, black magic fucking terrible unholy things that rails does |
| 03:07 | bbloom | i love rails |
| 03:07 | bbloom | it's absurdly productive.... |
| 03:07 | bbloom | .....at first |
| 03:07 | bbloom | and if you're a contract crud web app sort of guy |
| 03:07 | Raynes | bbloom: The worst part is the guy replying to the guy I linked said "It's nice to see the Clojure web stack maturing" |
| 03:08 | Raynes | I die a little inside when people correlate the library approach to immaturity. |
| 03:08 | bbloom | Raynes: like i said: probably better to ignore those people |
| 03:08 | Raynes | I want to educate these people. Violently. |
| 03:08 | bbloom | however, one of the nice things about the clj community is the refusal to do the dumb things that other communities do |
| 03:08 | Raynes | $dict brainwash |
| 03:08 | lazybot | Raynes: verb-transitive: To subject to brainwashing. |
| 03:09 | Raynes | $dict brainwashing |
| 03:09 | lazybot | Raynes: 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:09 | yedi | what are some of the not so nice things about the clj community |
| 03:09 | ibdknox | we don't focus on beginners in any reasonable way |
| 03:09 | ibdknox | which is what Noir was originally about |
| 03:10 | Sgeo | Does Factor's Furnace count as a "framework"? |
| 03:10 | Sgeo | Or as a library? |
| 03:11 | ibdknox | yedi: 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:11 | ibdknox | for most of the guys here, picking up something new is fairly trivial |
| 03:11 | muhoo | everyone who doesn't get this topic should watch rhickey's "simple vs. easy" presentation |
| 03:12 | muhoo | "i love rails! it's so easy!" .... simple != easy |
| 03:12 | Sgeo | http://re-factor.blogspot.com/2010/08/hello-web.html (might be slightly old) |
| 03:12 | Anderkent | https://gist.github.com/4372203 has oneone written this before? Macroexpand that does not crash on not-yet-loaded classes |
| 03:12 | Sgeo | Hmm, there's a way to make actions besides subclassing :/ |
| 03:13 | Sgeo | Anderkent, does it work with macros that use &env? |
| 03:13 | Anderkent | it passes anything that's actually a macro on to (macroexpand) |
| 03:13 | Anderkent | only handles java interop itself |
| 03:13 | Sgeo | Does it do the right thing with '(quote ..... oh |
| 03:13 | Sgeo | It's not supposed to recursively macroexpand? Ok. |
| 03:14 | Anderkent | no, does the same thing as macroexpand :) Recursive macroexpansion is a bit more difficult, you have to track the lexical scope yourself etc |
| 03:15 | muhoo | bbloom: 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:16 | muhoo | but i get to write in a language i actually like, so, win. |
| 03:16 | yedi | muhoo: really? it's that bad? |
| 03:16 | yedi | why..? |
| 03:17 | muhoo | not bad, i'm just new to clojure. |
| 03:17 | muhoo | and, 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:18 | yedi | i c |
| 03:18 | muhoo | when it comes to boilerplate apps, working in a language that has lots of boilerplate libraries is an advantage. |
| 03:22 | amalloy | Anderkent: your implementation of macroexpand-1 seems to delegate to macroexpand, not to macroexpand-1 |
| 03:23 | Sgeo | Anderkent, 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:24 | Sgeo | Although I guess it could be argued that it is not in fact right. |
| 03:25 | PudgePacket | Can anyone explain why this doesn't work ? http://pastebin.com/4d2JmL7D |
| 03:25 | PudgePacket | seems like it should, returning a list of string from the str function |
| 03:26 | amalloy | ,("a" "b" "b") |
| 03:26 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn> |
| 03:26 | PudgePacket | oh |
| 03:26 | PudgePacket | i forgot to quote the list |
| 03:26 | amalloy | ,["a" "b" "b"] ;; or, (list "a" "b" "c") |
| 03:26 | clojurebot | ["a" "b" "b"] |
| 03:26 | PudgePacket | siiiiiiiiiigh |
| 03:26 | muhoo | yedi: 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:26 | amalloy | or, as you say, quote it |
| 03:26 | PudgePacket | thanks anyway :P |
| 03:28 | muhoo | ok, enjoy your holidaze, all |
| 04:10 | dimovich | hello ppl |
| 04:10 | dimovich | is there a better way to do (into (into array1 array2) array3) |
| 04:10 | dimovich | ? |
| 04:10 | bbloom | dimovich: by arrayN do you mean a java array? or a clojure sequence? |
| 04:10 | dimovich | clojure sequence |
| 04:11 | bbloom | (doc into) |
| 04:11 | clojurebot | "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined." |
| 04:11 | bbloom | ,(into [] (concat (range 5) (range 10 15) (range 20 25))) |
| 04:11 | clojurebot | [0 1 2 3 4 ...] |
| 04:12 | bbloom | dimovich: does that help? |
| 04:12 | dimovich | yes, thanks :) |
| 04:12 | dimovich | forgot about concat :) |
| 04:12 | bbloom | dimovich: you can skip the into, if you don't need a vector |
| 04:12 | bbloom | ie just leave it as a lazy seq |
| 04:12 | dimovich | ok |
| 04:13 | bbloom | or you can use vec |
| 04:13 | bbloom | (doc vec) |
| 04:13 | clojurebot | "([coll]); Creates a new vector containing the contents of coll." |
| 05:11 | francis | Hello all, I'm having an issue figuring out how to quote a form - https://gist.github.com/4372506 |
| 05:12 | francis | I'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:12 | francis | thoughts? |
| 05:14 | bbloom | (doc symbol?) |
| 05:14 | clojurebot | "([x]); Return true if x is a Symbol" |
| 05:14 | bbloom | ,'x |
| 05:14 | clojurebot | x |
| 05:15 | bbloom | ,''x |
| 05:15 | clojurebot | (quote x) |
| 05:15 | bbloom | ,(map class ''x) |
| 05:15 | clojurebot | (clojure.lang.Symbol clojure.lang.Symbol) |
| 05:15 | bbloom | ,(map name ''x) |
| 05:15 | clojurebot | ("quote" "x") |
| 05:15 | bbloom | francis: does that help? |
| 05:16 | francis | bbloom: I think so, though I need to try it out first |
| 05:17 | francis | thanks |
| 05:17 | bbloom | francis: also realize that quoting behaves differently on symbols than it does on other types |
| 05:17 | bbloom | ,'5 |
| 05:17 | clojurebot | 5 |
| 05:17 | bbloom | ,''5 |
| 05:17 | clojurebot | (quote 5) |
| 05:17 | bbloom | ,inc ; a function |
| 05:17 | clojurebot | #<core$inc clojure.core$inc@166248d> |
| 05:18 | bbloom | ,(map class [5 '5 inc 'inc]) |
| 05:18 | clojurebot | (java.lang.Long java.lang.Long clojure.core$inc clojure.lang.Symbol) |
| 05:18 | bbloom | notice how 5 and '5 are the same, but inc and 'inc are not |
| 05:19 | bbloom | ,(map class [5 '5 ''5 inc 'inc ''inc]) |
| 05:19 | clojurebot | (java.lang.Long java.lang.Long clojure.lang.PersistentList clojure.core$inc clojure.lang.Symbol ...) |
| 05:19 | bbloom | ,(map class [5 '5 ''5) |
| 05:19 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: )> |
| 05:19 | bbloom | ,(map class [5 '5 ''5]) |
| 05:19 | clojurebot | (java.lang.Long java.lang.Long clojure.lang.PersistentList) |
| 05:19 | bbloom | ,(map class [inc 'inc ''inc]) |
| 05:19 | clojurebot | (clojure.core$inc clojure.lang.Symbol clojure.lang.PersistentList) |
| 05:19 | francis | bbloom: interesting |
| 05:20 | bbloom | note that is two apostrophes, not a quotation mark |
| 05:20 | francis | noted |
| 05:21 | dimovich | hey 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:21 | dimovich | how do I specify the itemprop value? |
| 05:25 | francis | (when (and |
| 05:25 | francis | (= :itemprop (enlive/attr? your-html)) |
| 05:25 | francis | (= "myvalue" (enlive/get-value your-html))) |
| 05:25 | francis | ;; do stuff |
| 05:25 | francis | ) |
| 05:25 | francis | dimovich: do mean like that? |
| 05:25 | bbloom | francis: please use refheap for multiline snippets |
| 05:25 | francis | I'm not sure of the exact enlive fn, but is that what you mean in general sense? |
| 05:26 | dimovich | no |
| 05:26 | dimovich | <div.desc itemprop="somevalue"> some text </div> |
| 05:26 | dimovich | select all nodes that have itemprop=somevalue |
| 05:27 | francis | sorry, so you want to use a select with an `and` clause if I'm not mistaken |
| 05:27 | francis | hitting docs for exact source |
| 05:27 | dimovich | yes |
| 05:27 | francis | one min |
| 05:33 | Raynes | bbloom: Hahaha |
| 05:33 | Raynes | bbloom: He can't use refheap. |
| 05:33 | Raynes | :P |
| 05:33 | bbloom | down? |
| 05:33 | bbloom | heh. |
| 05:33 | bbloom | heroku? |
| 05:33 | bbloom | *sigh* |
| 05:33 | Raynes | bbloom: It's been down for hours because Heroku because AWS. |
| 05:33 | Raynes | It's pretty awful. |
| 05:34 | Raynes | Netflix is down too IIRC. |
| 05:34 | bbloom | because Heroku because AWS .... because EBS? |
| 05:34 | Raynes | Heroku going down for 12 hours at a time is starting to outweigh the benefits of using heroku. |
| 05:35 | bbloom | Raynes: i gave up on heroku after 6mo of using it |
| 05:35 | bbloom | it's nice, but it's not nice enough |
| 05:35 | Raynes | I did it because Heroku would handle DDOS attacks which pastebins are prone to. |
| 05:35 | bbloom | heh |
| 05:35 | Raynes | But it's almost not worth it anymore. |
| 05:35 | Raynes | I pay $20 for SSL that I could have for free on my VPS. |
| 05:35 | Anderkent | Well hopefully they'll move to multiple avail. zones eventually |
| 05:35 | Raynes | I expect uptime. |
| 05:36 | Raynes | I'm okay with a little downtime every once in a while, but yikes, it has been like 12 hours or more. |
| 05:37 | Anderkent | but 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:37 | bbloom | hmm seems like ELB this time, not EBS |
| 05:37 | bbloom | it's usually EBS |
| 05:37 | bbloom | since EBS is a terrible idea. |
| 05:38 | Anderkent | why do you think so? |
| 05:39 | bbloom | Anderkent: the same reasons NFS is a terrible idea |
| 05:39 | bbloom | the posix/unix filesystem system api is not designed to be distributed |
| 05:39 | bbloom | there are system calls that just don't make sense for a distributed file system |
| 05:39 | bbloom | hence the design of plan9's 9p protocol |
| 05:41 | bbloom | http://joyent.com/blog/magical-block-store-when-abstractions-fail-us |
| 05:42 | bbloom | http://en.wikipedia.org/wiki/9P |
| 05:58 | francis | dimovich: I would just filter by keys unless you have some other reason to use `attrs?` see: https://gist.github.com/4372608 |
| 06:02 | dimovich | francis: thanks |
| 06:03 | dimovich | I suppose enlive has some built in stuff for this... but this should work too :) |
| 06:05 | francis | dimovich: 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:56 | callen | bbloom: good luck telling HN EBS is a bad idea. |
| 06:56 | callen | bbloom: they love their fragile magic. |
| 06:56 | callen | they get mad if you mention that AWS hasn't been the most reliable thing on the planet. |
| 06:57 | Raynes | Oh no, callen's awake. |
| 06:57 | callen | Raynes: :( |
| 06:58 | Anderkent | so what's the thing that's more reliable than AWS? Self-hosting? |
| 06:58 | callen | Anderkent: it's almost more of an architectural question than where your physical machines live. |
| 06:58 | callen | Anderkent: one thing is to avoid networked filesystems that aren't very application specific (like EBS) |
| 06:59 | callen | another is to mistrust magical load balancing, queueing, or database services (ELB, SQS, RDS) |
| 06:59 | callen | further, keeping your machines heterogenous in *where* they're deployed, with actual procedures in place for cross-geo failover is important |
| 07:00 | Anderkent | well, aws does give you different zones for that |
| 07:00 | callen | haha, yeah, that tends not to work. |
| 07:00 | callen | nice try though. That's been a joke for a long time. |
| 07:00 | Anderkent | do tell> |
| 07:01 | callen | whenever EBS has gone down, all the sub-zones or whatever of say, US-EAST go down together. |
| 07:01 | Anderkent | I mean I havent used AWS on anything large, so I'm really being curious, not attacking you |
| 07:01 | callen | there's no apparent separation/damage control |
| 07:01 | callen | other downtimes have been datacenter-scale network related, so again, their separation stuff hasn't helped anything |
| 07:01 | callen | when I say cross-geo failover, I mean from one end of the world to the other. |
| 07:02 | callen | you'd need to have an architecture that is prepared to failover from Virginia to California |
| 07:02 | callen | if you're not prepared to do that, have another East Coast provider that isn't AWS |
| 07:02 | callen | and failover between those two. |
| 07:03 | callen | but 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:03 | Anderkent | well that's what I was thinking about, host stuff on EU + one US region, that hopefully gives you something to fail over to> |
| 07:03 | callen | I have to say though, Netflix downtime on Christmas Eve is pretty choice. |
| 07:03 | callen | Anderkent: hypothetically yes, in practice, nobody takes advantage of that sort of thing. |
| 07:04 | callen | which I thought was the original point of AWS, but w/e |
| 07:04 | callen | self-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:05 | callen | it's just that for most companies it wouldn't be because they wouldn't be able to invest in the infrastructure properly. |
| 07:05 | Anderkent | most of us aren't google, facebook or twitter though, and building our own datacenters is usually not an option |
| 07:05 | callen | that's what I said, yes. |
| 07:05 | Anderkent | yeah I type a little slow :P |
| 07:05 | Raynes | callen: 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:05 | Raynes | Unacceptable. |
| 07:05 | Raynes | Heroku's benefits aren't worth this. This is the second time this has happened. |
| 07:06 | Raynes | But yeah, going to bed for real now. |
| 07:06 | Anderkent | so 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:06 | callen | Raynes: incidentally, I have 3 accounts on Heroku, 2 of the 3 have been HTTP 500'ing on login for the past week. |
| 07:06 | callen | Anderkent: I see plenty of alternatives. |
| 07:07 | Anderkent | well, there's Rackspace, but i'd rather handle aws occasionally going down... |
| 07:08 | callen | Anderkent: Rackspace acquired Cloudkick, so they have a lot of the same tooling now. |
| 07:08 | callen | Anderkent: there's a ton of damn decent VPS providers, there's Joyent, etc. |
| 07:08 | callen | Anderkent: Joyent is pretty price/performance competitive with AWS and doesn't seem to have the ritualized tri-monthly downtime. |
| 07:09 | callen | Anderkent: 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:10 | callen | Anderkent: I've gotten intensely unpleasant phone calls in the past over 2-3 minute blips before. |
| 07:10 | callen | if I was responsible for a product that'd been down for 12+ hours, I would've started the human sacrifices by now. |
| 07:11 | Anderkent | yeah, 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:12 | callen | Anderkent: I use a mixture of Linode, Rackspace, Softlayer, and AWS. |
| 07:12 | callen | but nothing "live" to any customers goes on AWS. |
| 07:12 | callen | I don't trust them and likely never will. |
| 07:12 | callen | only backups, batch work, etc go on AWS. |
| 07:15 | Anderkent | heroku are on n. virginia too? That's the region having most issues, isn't it? |
| 07:15 | callen | Anderkent: it's almost always NVA that has issues. |
| 07:15 | callen | Anderkent: that's also where like 90% of the customers are. |
| 07:15 | callen | the secret to using AWS is to never ever use US-EAST :P |
| 07:16 | callen | the first time anything is going to break, it'll happen there first |
| 07:16 | callen | my AWS stuff is US-WEST |
| 07:17 | callen | mostly Oregon |
| 09:16 | xeqi | Anderkent, Raynes: you could try openshift |
| 09:26 | wkelly | xeqi: have you run anything production on openshift? |
| 09:27 | xeqi | nope, I'm weary of a service without prices |
| 09:28 | xeqi | wkelly: ^ |
| 09:29 | wkelly | understandable |
| 09:29 | xeqi | though if jcrossley3 or tcrawley|away get openshift auto-clustering working on it I might be really tempted |
| 09:29 | xeqi | well.. I'm already really tempted |
| 09:29 | xeqi | * immutant auto-clustering |
| 09:30 | wkelly | I haven't met anyone who has really kicked the tires on it, but I enjoyed playing with it |
| 09:30 | wkelly | it was nice and easy to deploy clojure to! |
| 09:31 | wkelly | I don't know what kind of guarantees you can get about running on different physical hosts and so on for proper clustering |
| 09:39 | xeqi | wkelly: thanks, glad to hear from someone whos tried it out |
| 09:41 | theadmin | Hello. 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:42 | gfredericks | theadmin: 4clojure.com |
| 09:43 | theadmin | gfredericks: Hm, interesting. Thanks. |
| 09:46 | wkelly | theadmin: if you are familiar with java, http://java.ociweb.com/mark/clojure/article.html can be helpful |
| 09:46 | wkelly | probably even if you are not |
| 09:46 | theadmin | wkelly: Am not |
| 09:57 | theadmin | gfredericks: 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:01 | terom | theadmin: note rhe "!" at the end |
| 10:01 | theadmin | terom: Oh durr |
| 10:06 | theadmin | Ok this started to get very confusing |
| 10:37 | Anderkent | remind me, bindings are thread local? |
| 10:37 | si14__ | is it a bug, guys? (name (keyword "/foobar/:baz/bar")) => "bar" |
| 10:38 | Bronsa | ,(namespace (keyword "/foobar/:baz/bar")) |
| 10:38 | clojurebot | "/foobar/:baz" |
| 10:39 | si14__ | looks like a bug to me. |
| 10:39 | bawr | What would you expect? |
| 10:39 | Bronsa | why so? |
| 10:39 | si14__ | I would expect that (name (keyword x)) == x |
| 10:39 | Bronsa | (name :foo/bar) |
| 10:39 | Bronsa | ,(name :foo/bar) |
| 10:39 | clojurebot | "bar" |
| 10:40 | Bronsa | ,(namespace :foo/bar) |
| 10:40 | clojurebot | "foo" |
| 10:40 | Bronsa | ,(str :foo/bar) |
| 10:40 | clojurebot | ":foo/bar" |
| 10:40 | Bronsa | ,(name (keyword "foo/bar")) |
| 10:40 | clojurebot | "bar" |
| 10:40 | Bronsa | ,(namespace (keyword "foo/bar")) |
| 10:40 | clojurebot | "foo" |
| 10:41 | si14__ | it's an abstraction leak, isn't it? |
| 10:41 | Bronsa | actually is a wanted feature |
| 10:41 | Anderkent | Looks 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:42 | si14__ | "keyword" that doesn't escape it's argument? |
| 10:42 | si14__ | yeah |
| 10:42 | si14__ | definitely a feature :) |
| 10:43 | Anderkent | ,(namespace (keyword "Foo" "bar")) |
| 10:43 | clojurebot | "Foo" |
| 10:43 | Bronsa | err? think about it / is used to separate the namespace from the name |
| 10:43 | Bronsa | if "foo/bar" was a valid name, there would be no way to safely parse :foo/bar/baz |
| 10:43 | Bronsa | is the name bar/baz or is it baz? |
| 10:44 | Bronsa | is the namespace foo/bar or is it foo? |
| 10:44 | Anderkent | uh no :foo/bar/baz is pretty easy to parse, :<whatever><space> parses to keyword with name = whatever ? |
| 10:46 | si14__ | Bronsa: I think Anderkent is right |
| 10:46 | bawr | And what about namespaces? |
| 10:46 | Anderkent | bawr: name.space/:keyword ? |
| 10:47 | Bronsa | i think you may have misunderstood what i was trying to say |
| 10:47 | Bronsa | si14__: you are complaining of the fact that in clojure there is no way for "foo/bar" to be parsed as a name |
| 10:48 | Bronsa | and I'm telling you that there is a reason why that CAN'T be done |
| 10:48 | Anderkent | Bronsa: and the reason is? |
| 10:48 | Bronsa | ok, suppose you want a keyword with namespace "foo" and name "bar/baz" |
| 10:49 | Bronsa | that would print out as :foo/bar/baz |
| 10:49 | Anderkent | oh okay didn't know it puts the : before the ns |
| 10:49 | Bronsa | yeah |
| 10:49 | Anderkent | weird |
| 10:49 | Anderkent | but ok |
| 10:50 | Bronsa | if it was the case that a namespaced keyword prited as ns/:bar then it would be possible |
| 10:50 | Bronsa | printed* |
| 10:50 | Bronsa | but i don't think that'd be a good idea anyway |
| 10:51 | si14__ | ok, thanks. |
| 10:52 | Bronsa | so, the current behaviour of the reader is to take until the last / and consider that the namespace part, and the rest the name |
| 10:56 | Anderkent | Any suggestions for large-ish clojure libraries to try my test coverage library on? For now tried incanter and ring, anything else? |
| 11:05 | xeqi | Anderkent: could try it on the leiningen source |
| 11:07 | Anderkent | nice idea, thanks |
| 11:08 | xeqi | or chesire, clojail, compojure, etc. not sure those would be "large" though |
| 11:13 | Anderkent | lein master branch is a dev or release branch? Can't run the tests there it seems.. |
| 11:15 | Bronsa | lein master branch is dev |
| 11:15 | xeqi | Anderkent: there is some minor steps required to bootstrap lein atm, https://github.com/technomancy/leiningen#building |
| 11:16 | xeqi | though it does require lein1 |
| 11:16 | xeqi | though I think the tests are failing on master |
| 11:17 | Anderkent | i get failures at preview as well ;/ |
| 11:17 | xeqi | yeah, might bee better to come back to that one :p |
| 11:18 | Anderkent | well I should be able to run coverage even with failures, so I'll try and see what happens :P |
| 11:28 | xeqi | Anderkent: I wouldn't mind seeing stats on https://github.com/xeqi/peridot or https://github.com/xeqi/kerodon |
| 11:37 | Anderkent | think 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:37 | Anderkent | oh, I suppose I can just not run compilation tests ;p |
| 12:15 | Anderkent | How can I add a dependency to a lein project from a lein plugin? |
| 12:16 | yedi | postgres and redis seems like a winning duo |
| 12:17 | Anderkent | ah, found it, nvm |
| 12:19 | Baughn | Does clojure have a different notion of classpath than java? |
| 12:20 | Baughn | I ask because.. well: |
| 12:20 | gfredericks | no |
| 12:20 | Baughn | $ java -cp . -jar ../../lib/clojure-1.4.0.jar |
| 12:20 | Baughn | user=> (compile 'boom.core) |
| 12:20 | Baughn | FileNotFoundException Could not locate boom/core__init.class or boom/core.clj on classpath: clojure.lang.RT.load (RT.java:432) |
| 12:20 | Baughn | $ ls boom/core.clj |
| 12:20 | Baughn | boom/core.clj |
| 12:20 | clojurebot | nstools is a library to reduce repetition in your ns clauses: http://code.google.com/p/clj-nstools/ |
| 12:23 | Anderkent | Baughn: try printing the classpath, see if the dir is on the list? |
| 12:23 | Baughn | Anderkent: Sure.. how? |
| 12:23 | Anderkent | ,(println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader)))) |
| 12:23 | clojurebot | #<AccessControlException java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader)> |
| 12:23 | Anderkent | well, it will work for you :P |
| 12:24 | Baughn | Hm, that gives just the clojure .jar |
| 12:24 | Baughn | Odd. |
| 12:28 | Anderkent | try `java -cp '.:../../lib/clojure-1.4.0.jar' clojure.main` |
| 12:28 | Anderkent | i'm not sure how -cp and -jar interact |
| 12:28 | Baughn | Yeah, that's the trick. They don't. |
| 12:31 | yogthos | oh hey I ran into this yesterday |
| 12:31 | yogthos | -cp doesn't like jars not being in the same folder |
| 12:32 | Baughn | I figured it out. I just need to not use -jar. |
| 12:32 | Baughn | Not nice of java to just swallow the -cp, though |
| 12:32 | yogthos | no it's not ;) |
| 12:33 | yogthos | the way classpath works is not terribly intuitive |
| 12:45 | svedubois | How I can translate this line in java to clojure? |
| 12:45 | svedubois | filter.setSigma( Double.valueOf( sigma ).doubleValue() ); |
| 12:46 | svedubois | Is this OK? (.setSigma filter (Double/valueOf (sigma) doubleValue)) |
| 12:48 | yogthos | looks reasonable |
| 12:49 | yogthos | err |
| 12:50 | yogthos | (.setSigma filter (Double.valueOf (.doubleValue sigma))) |
| 12:52 | edlothiol | still not right, (.setSigma filter (.doubleValue (Double/valueOf sigma))) |
| 12:52 | edlothiol | although Double.valueOf(sigma).doubleValue() can be simplified to Double.parseDouble(sigma), I think |
| 12:53 | edlothiol | i.e. (.setSigma filter (Double/parseDouble sigma)) |
| 12:53 | yogthos | you could also thread it, eg: (->> sigma .doubleValue Double/valueOf (.setSigma filter)) |
| 12:55 | yogthos | I find the threading syntax is a bit easier to follow, since it flattens the expression |
| 12:56 | svedubois | It seems that works, but I get an exception: |
| 12:56 | svedubois | Exception in thread "main" java.lang.IllegalArgumentException: No matching field found: doubleValue for class java.lang.String |
| 12:56 | svedubois | I need to import something for doubleValue? |
| 12:57 | edlothiol | it should be (->> sigma Double/valueOf .doubleValue (.setSigma filter)), but you should really just use Double/parseDouble |
| 12:58 | kovas | anyone doing some xmas coding? |
| 12:59 | yogthos | yeah if sigma starts out as a string |
| 12:59 | svedubois | Thanks it works! |
| 12:59 | yogthos | cool |
| 13:00 | Anderkent | kovas: yes :P |
| 13:00 | kovas | Anderkent: best present: time to code on fun projects :0 |
| 13:01 | yogthos | :) |
| 13:02 | jonasen | kovas: I'm working on the Java Codeq analyzer.. that's a lot of fun! |
| 13:03 | kovas | jonasen: cool! is there a github? |
| 13:03 | kovas | I'm working on session |
| 13:04 | Anderkent | hah, I'm hacking on a code coverage tool : https://github.com/JacekLach/cloverage . Should be ready for a beta test... :P |
| 13:04 | jonasen | kovas: It's at https://github.com/jonase/codeq/tree/java |
| 13:05 | kovas | nice. i am ready for the next level of tooling |
| 13:06 | ibdknox | relatedly, I'm working on LT :) |
| 13:07 | jonasen | kovasb: here's a query https://gist.github.com/4374467 |
| 13:12 | jonasen | kovas: Session looks awesome! Would love to help out on that project |
| 13:12 | kovas | jonasen: thanks! |
| 13:12 | kovas | jonasen: theres a bunch of stuff to do :) I think I'm gonna spend some time opening tickets and improving the documentation right now.. |
| 13:14 | svedubois | I have translate this java code to clojure: |
| 13:14 | svedubois | Java: |
| 13:14 | svedubois | ImageFileReader reader = new ImageFileReader(); |
| 13:14 | svedubois | reader.setFileName(input); |
| 13:14 | svedubois | Image img = reader.execute(); |
| 13:14 | svedubois | Clojure: |
| 13:14 | svedubois | (defn main [input] |
| 13:14 | svedubois | (let [reader ( ImageFileReader.) |
| 13:14 | svedubois | img (Image.)] |
| 13:14 | svedubois | (.setFileName reader input) |
| 13:14 | svedubois | (def img (.execute reader)))) |
| 13:14 | svedubois | I have problems to convert "img" from java to clojure. |
| 13:14 | svedubois | I am not sure that: |
| 13:14 | svedubois | Image img = reader.execute(); |
| 13:14 | svedubois | Is the same that (or even valid): |
| 13:14 | svedubois | (def img (.execute reader)))) |
| 13:15 | Anderkent | it is (assuming it's a top level declaration, otherwise probably (let [img (.execute reader)] ...) is what you want) |
| 13:15 | Anderkent | oh, didn't see your earlier example |
| 13:16 | Anderkent | what you want is something like |
| 13:16 | yedi | session looks sweet |
| 13:16 | yedi | is there a demo up somewhere? |
| 13:17 | Anderkent | (let [img (-> (ImageFileReader.) (.setFileName input) .execute)] <do something to img or return it>) |
| 13:19 | kovas | yedi: will try to get a screencast up in the next few days |
| 13:25 | yedi | kovas: let me know when you finish documenting/ticketing |
| 13:27 | kovas | yedi: sweet, will do :) |
| 13:32 | miloshadzic | is there a recommended test framework for clojure? |
| 13:32 | zilti | Anderkent: Wouldn't it be more clear to use .. instead of -> to chain java stuff? |
| 13:33 | zilti | miloshadzic: There's the official one built in, and there are several others, but the most mature is probably midje. |
| 13:34 | Anderkent | zilti: .. has different semantics - .. chains the results, -> chains the first expression through all statements |
| 13:35 | zilti | Anderkent: Oh. Yes, right. |
| 13:35 | miloshadzic | zilti, I guess the builtin one will do for now |
| 13:36 | miloshadzic | zilti, (thanks) |
| 13:37 | zilti | miloshadzic: no problem. But I'd really recommend at least taking a look at both before deciding. |
| 13:38 | Anderkent | midje is pretty cool, though I still wrap midje tests in (deftest) so anything that works with clojure.test will work with my tests |
| 13:38 | Anderkent | (for example the mvn plugins) |
| 13:38 | miloshadzic | zilti, I'm kinda new to Clojure. I use RSpec most of the time in ruby |
| 14:48 | zilti | What 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:50 | zilti | ...or probably even better, to work with hash values. |
| 14:51 | svedubois | Is this java to clojure conversion correct? |
| 14:51 | svedubois | image = new Image ( 256, 128, 64, PixelIDValueEnum.sitkInt16 ); |
| 14:51 | svedubois | (def image (Image. (256 128 64 PixelIDValueEnum/sitkInt16))) |
| 14:52 | zilti | svedubois: "new" exists in clojure, too. |
| 14:53 | svedubois | I 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:53 | bbloom | svedubois: you're trying to call (256 128...) |
| 14:53 | bbloom | you have extra parens |
| 14:53 | zilti | (new java.awt.Image 256 128 64) |
| 14:53 | zilti | ,(new java.awt.Image 256 128 64 PixelIDValueEnum.sitkInt16) |
| 14:53 | clojurebot | #<CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: PixelIDValueEnum.sitkInt16, compiling:(NO_SOURCE_PATH:0)> |
| 14:54 | svedubois | Thanks, it works: (def image (Image. 256 128 64 PixelIDValueEnum/sitkInt16)) |
| 14:54 | bbloom | svedubois: for the record, (Foo. x y z) is just shorthand for (new Foo x y z) |
| 14:59 | zilti | How ugly is this? |
| 14:59 | zilti | (defn remove [arg] (if-not (= (class java.lang.Integer) (class arg)) (remove (hash arg)) (...code...))) |
| 14:59 | clojurebot | marg is 1 |
| 15:00 | zilti | (and what is "marg is 1"?) |
| 15:00 | bbloom | zilti: what are you trying to accomplish? |
| 15:02 | zilti | bbloom: 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:02 | bbloom | (doc remove) |
| 15:02 | clojurebot | "([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:03 | zilti | But since Clojure is dynamically typed. |
| 15:03 | bbloom | ,(map (comp class hash) [1 2.0 "3"]) |
| 15:03 | clojurebot | (java.lang.Integer java.lang.Integer java.lang.Integer) |
| 15:03 | zilti | Yes, I know remove. |
| 15:03 | bbloom | ok all integers rather than longs |
| 15:03 | zilti | (hash remove) |
| 15:03 | zilti | &(hash remove) |
| 15:03 | lazybot | ⇒ 21755981 |
| 15:04 | bbloom | so you wish there was some sort of hash-value? predicate? |
| 15:04 | bbloom | why are you working with hash values directly? |
| 15:05 | zilti | bbloom: 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:06 | bbloom | zilti: 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:08 | zilti | bbloom: 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:09 | bbloom | also 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:09 | bbloom | what would be ugly about it? you're not keeping anything "lying around" that's what garbage collection is for |
| 15:09 | zilti | &(= (hash (fn[x](* 2 x))) (hash (fn[x](* 2 x)))) |
| 15:09 | lazybot | ⇒ false |
| 15:09 | bosie | s it possible that midje's provided only works on calls for the very last function? |
| 15:09 | svedubois | How I can obtain the value of image (instead of #<Vector...)? |
| 15:09 | svedubois | (.getSize image) |
| 15:09 | svedubois | #<VectorUInt32 org.itk.simple.VectorUInt32@3a432ed2> |
| 15:10 | bosie | anything i call prior to the last function seems to not get mocked, somehow. |
| 15:10 | zilti | svedubois: (. image getSize) |
| 15:10 | bbloom | zilti: that's precisely the same as (.getSize image) |
| 15:11 | bbloom | svedubois: the vector you're getting back is a java object |
| 15:11 | bbloom | you can inspect it with interop, if the itk library doesn't provide a decent toString |
| 15:18 | svedubois | Using toString, I obtain this: |
| 15:18 | svedubois | (.toString (.getSize image)) |
| 15:19 | svedubois | "org.itk.simple.VectorUInt32@52c9f3c7" |
| 15:19 | bbloom | svedubois: right, the default printing behavior in clojure is to call toString and wrap it in those #<...> things |
| 15:20 | bbloom | svedubois: 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:22 | svedubois | When I use this: |
| 15:22 | svedubois | (.toString image) |
| 15:22 | svedubois | It prints a long text: |
| 15:22 | svedubois | "Image (0x7fc51c0047b0)\n RTTI typeinfo: itk::Image<short, 3u>\n ... Size: [256, 128, 64]\n ... Size: 2097152\n ... |
| 15:23 | bbloom | If 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:23 | bbloom | svedubois: what exactly are you trying to accomplish? |
| 15:51 | Seba51 | Happy Christmas to all of you. |
| 15:52 | Seba51 | I am learning clojure and have issues to understand a specific problem with macros. |
| 15:52 | bbloom | Seba51: ask away |
| 15:54 | Seba51 | The 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:54 | Seba51 | What is the motivation to use list? |
| 15:54 | gfredericks | yours seems to work? |
| 15:55 | Seba51 | Sorry brackets were missing around if |
| 15:55 | gfredericks | even so |
| 15:55 | Seba51 | (defmacro unless [expr form] (if expr nil form)) |
| 15:56 | gfredericks | ah ha |
| 15:56 | gfredericks | that's a little more understandable |
| 15:56 | Seba51 | (unless true (println "x")) |
| 15:57 | gfredericks | try (unless (= 1 2) 42) |
| 15:58 | Raynes | Bodil: Worst thing ever is hearing "I tried it, but it didn't work." :p |
| 15:58 | Raynes | I'm not currently aware of any bugs in conch, so definitely need reports when people find them. |
| 15:59 | Seba51 | (unless 1 2) prints nothing |
| 15:59 | Seba51 | nil |
| 15:59 | gfredericks | which you want |
| 15:59 | gfredericks | but (unless (= 1 2) 42) should give you 42 |
| 15:59 | svedubois | When I try to print the Size of an image: |
| 15:59 | svedubois | (.getSize image) |
| 15:59 | svedubois | I get this: |
| 15:59 | svedubois | #<VectorUInt32 org.itk.simple.VectorUInt32@31ac8cf3> |
| 15:59 | svedubois | And using toString: |
| 16:00 | svedubois | (.toString (.getSize image)) |
| 16:00 | svedubois | I get this: |
| 16:00 | svedubois | "org.itk.simple.VectorUInt32@981f674" |
| 16:00 | svedubois | Looking the class getSize is inside VectorUInt: |
| 16:00 | svedubois | public VectorUInt32 getSize() |
| 16:00 | svedubois | { |
| 16:00 | svedubois | return new VectorUInt32(SimpleITKJNI.Image_getSize(swigCPtr, this), true); |
| 16:00 | svedubois | } |
| 16:00 | svedubois | Is there any easy way to print the numbers of getSize? |
| 16:00 | gfredericks | svedubois: refheap.com |
| 16:00 | bbloom | svedubois: like i tried to say: you need to call accessor functions on that VectorUInt object |
| 16:01 | Seba51 | * need a moment to understand the answer * |
| 16:01 | bbloom | consult the javadocs or something for the library you're using |
| 16:01 | Raynes | Oh great, refheap is actually up now? |
| 16:01 | Raynes | I've got moving that thing off of Heroku on my todo list. |
| 16:03 | bbloom | i 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:03 | bbloom | i 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:04 | bbloom | is there anyway to do that other than to loop over ns-publics and call intern on each? |
| 16:04 | Seba51 | Having (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:05 | bbloom | Seba51: consider side effects: (unless true (print "omg!")) |
| 16:05 | jonasen | kovas: I've got session running and started to read through some of the code. |
| 16:05 | kovas | jonasen: nice. let me know if u have any questions |
| 16:05 | jonasen | kovas: I updated to latest clojure/clojurescript/datomic/cljsbuild and it seems to work still |
| 16:06 | kovas | jonasen: i just created a bunch of tickets, working on cleaning up / commenting the code |
| 16:06 | kovas | jonasen: great, if u make a pull request I'll just update it |
| 16:08 | gfredericks | Seba51: what is your understanding about the difference between a macro and a function? |
| 16:08 | jonasen | kovas: I also made some trivial clean-up of session.datomic. I'll send you a pull request |
| 16:09 | kovas | jonasen: awesome, thanks! |
| 16:10 | Seba51 | Functions are evaluated immediately |
| 16:11 | gfredericks | Seba51: macros are functions on code. Their input is code, and their output is code. |
| 16:11 | gfredericks | the 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:12 | gfredericks | your definition, instead of returning an if expression, either returns the second argument or nil |
| 16:12 | gfredericks | and it decides how to do that based on the truthiness of the first argument (expr) |
| 16:12 | gfredericks | but that argument is unevaluated code |
| 16:13 | gfredericks | so if it is an expression such as (= 1 2), even though it would evaluate to false, as code it is truthy |
| 16:13 | gfredericks | (because it is a list) |
| 16:13 | gfredericks | ,(boolean '(= 1 2)) |
| 16:13 | clojurebot | true |
| 16:16 | bawr | gfredericks: it's only appropriate :) |
| 16:17 | gfredericks | https://twitter.com/gfredericks_/status/283581072237789185 |
| 16:17 | Seba51 | I found out, that the smiley (caused by ( = was actually code, but give me a moment to understand |
| 16:17 | gfredericks | oh dear smileys |
| 16:17 | Anderkent | (= |
| 16:17 | gfredericks | I bet that means my counterexample from earlier got missed |
| 16:18 | Seba51 | yep |
| 16:18 | Seba51 | ;-) |
| 16:18 | gfredericks | it was (unless ( = 1 2) 42) |
| 16:18 | Seba51 | I assumed that you were in happy mood while typing ;-) |
| 16:19 | bawr | Seba51: but erh, yeah, what you want to take away from this is that macros are really supposed to emit code. ;P |
| 16:19 | bawr | :> |
| 16:19 | Seba51 | I got it |
| 16:19 | gfredericks | bawr: are you trying to condense my ramblings to a helpfully digestable size? |
| 16:20 | bawr | gfredericks: I'm distilling them, I guess. |
| 16:20 | Seba51 | Thanks a lot |
| 16:20 | bawr | But that's some good rambling, 10/10 would distill again. |
| 16:20 | gfredericks | lerlz |
| 16:22 | Anderkent | style question: how do I do nested map/reduce right? example http://pastebin.com/QQdLiv5Z |
| 16:22 | jonasen | kovas: 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:23 | kovas | jonasen: i thought it did something more sophisticated with annotating the transaction.. lemme take a look |
| 16:25 | gfredericks | Anderkent: besides breaking something out into a separate function, I can't think of a simpler way to do that |
| 16:26 | Raynes | http://dl.dropbox.com/u/23745600/Screenshots/6uOy.png |
| 16:26 | Raynes | Wrong window. |
| 16:30 | kovas | jonasen: 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:31 | bbloom | let 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:31 | bbloom | or even better, do that on the supply side: inside the zip-util namespace |
| 16:31 | bbloom | somewhat similar to how python provides __ALL__ that you can fill in |
| 16:31 | jonasen | kovas: The analyzers supports schema revisions and when you run codeq it figures out which versions has been transacted |
| 16:32 | kovas | jonasen: in any case, i think my plan was to just copy exactly what codeq did in terms of those conventions |
| 16:32 | yogthos | maybe you could make a macro which makes a new namespace that uses both and then require it as whatever? |
| 16:32 | Anderkent | bbloom: 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:33 | yogthos | oh nm it won't be exposed that way |
| 16:33 | yogthos | it's too bad you can't cascade dependencies |
| 16:33 | Anderkent | I'm not sure what we're trying to do - have one zip namespace with all the functions in it? |
| 16:33 | Raynes | bbloom: I'd probably hate you if you did that. |
| 16:34 | bbloom | yogthos: yeah, you'd need the macro to expand to a bunch of def forms, which is totally doable |
| 16:34 | bbloom | Anderkent: basically |
| 16:34 | bbloom | Raynes: why? i have a dozen or so zipper functions that i always use |
| 16:34 | bbloom | i keep forgetting which are in zip and which are in zip-utils :-P |
| 16:34 | bbloom | it's driving me nuts |
| 16:34 | Anderkent | bbloom: how about doing magic in zip-util that reexposes all zip vars under its own ns? |
| 16:34 | Raynes | bbloom: The problem is how does the person reading your code know where things come from? |
| 16:34 | Raynes | Which namespace? |
| 16:35 | Raynes | Anyways, if it is ridiculous namespace magic, it's probably in potemkin somewhere. |
| 16:35 | Raynes | $google clojure potemkin |
| 16:35 | lazybot | [ztellman/potemkin · GitHub] https://github.com/ztellman/potemkin |
| 16:35 | amalloy | yes, potemkin contains exactly the magic bbloom wants to make his code easy to write and hard to read |
| 16:35 | Raynes | amalloy: o/ |
| 16:36 | bbloom | heh: https://github.com/ztellman/potemkin/blob/master/src/potemkin/namespace.clj |
| 16:36 | kovas | jonasen: ok. I guess its not a big functionality improvement to change that then, other than to maybe rename the functions i have |
| 16:36 | Anderkent | import-fn seems like the thing bbloom wants to do |
| 16:36 | kovas | jonasen: I'm also gonna open some tickets on codeq and lein that might be interesting for you |
| 16:36 | kovas | :) |
| 16:36 | bbloom | Raynes & 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:36 | jonasen | kovas: except that you'll be able to run the free transactor |
| 16:37 | Anderkent | bbloom: that's okay, as for the user they all seem to come from zip-util |
| 16:37 | bbloom | you are in myapp.core and you navigate to zip-util and see that zipper is defined as clojure.zip/zipper |
| 16:37 | Anderkent | the bad case is where you would have the two namespaces somehow merged in the user ns |
| 16:37 | bbloom | yeah, Anderkent i agree |
| 16:37 | jonasen | kovas: right now it'll try to transact the schema every time |
| 16:38 | Raynes | bbloom: 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:38 | kovas | jonasen: not optimal |
| 16:39 | amalloy | bbloom: 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:39 | amalloy | and, you might not. potemkin drives me nuts, but beyond what is rational really |
| 16:40 | Raynes | And I think amalloy and I share generally exactly the same opinion on potemkin. |
| 16:41 | kovas | jonasen: I've run the free transactor with session, seems to work OK |
| 16:42 | jonasen | kovas: sorry, I misread your code. You do check for a schema attribute in connect-database |
| 16:42 | kovas | jonasen: ok, I think I had both at one point.. forgetting my own code :) |
| 16:42 | mpenet | flatland.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:43 | bbloom | Raynes & 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:43 | amalloy | ugh, alias-ns is worse |
| 16:43 | mpenet | oh ? |
| 16:43 | Raynes | bbloom: Look at what it takes to make this crap happen. |
| 16:43 | Raynes | It might turn you off of it. |
| 16:43 | amalloy | it makes it actually-impossible to track down where a function came from |
| 16:44 | bbloom | Raynes: i looked at it. it's an ugly copy paste of metadata |
| 16:44 | amalloy | i forget the syntax, but: (alias-ns useful.seq) (alias-ns useful.map) (map-vals m f) ;; where does map-vals come from? |
| 16:47 | bbloom | i 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:47 | bbloom | do you have a better proposal? |
| 16:48 | kovas | jonasen: I'm gonna take off for a while, will be on IRC later |
| 16:48 | kovas | (hopefully) |
| 16:52 | bbloom | there are two use cases: 1) organize the backing code for some public api into multiple files, but preserve one namespace |
| 16:52 | bbloom | and 2) alias names locally in a union/merge fashion |
| 16:53 | bbloom | the former falls down when you want to extend somebody else's namespace |
| 16:53 | bbloom | the latter is slightly more effort |
| 16:53 | bbloom | i guess i'll just deal with zip and zipx for now |
| 16:53 | bbloom | but i don't have to like it :-P |
| 16:54 | Raynes | bbloom: 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:54 | bbloom | Raynes: and i'm going to trust you on that, but i'm saying that the shortcomings are probably implementation failings, not something inherent |
| 16:54 | bbloom | ie the stacktraces suck |
| 16:55 | bbloom | or something similar |
| 16:55 | bbloom | no? |
| 16:55 | clojurebot | no is tufflax: there was a question somewhere in there, the answer |
| 16:55 | amalloy | Raynes: it sounds like you did just change his mind |
| 16:58 | Raynes | bbloom: 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:58 | Anderkent | Raynes: with a good implementation you'll know where stuff came from anyway, it's one extra find-def press more... |
| 16:59 | Raynes | Look |
| 16:59 | Raynes | I'm right. You're wrong. Just let it go. |
| 16:59 | Raynes | :P |
| 16:59 | Anderkent | I 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:00 | Raynes | It's easier if you guys stop having conflicting opinions! |
| 17:00 | bbloom | Raynes: you're only right because i have bigger fish to fry :-P like making this damn library work at all |
| 17:00 | clojurebot | http://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png |
| 17:01 | bbloom | Raynes: 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:01 | bbloom | Raynes: 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:02 | bbloom | consider (when false (def x 1)) |
| 17:02 | bbloom | obviously a stupid edge case |
| 17:02 | bbloom | but illustrates the issue |
| 17:02 | gfredericks | on cljs that happens at code-load-time, right? |
| 17:03 | bbloom | gfredericks: in cljs x would be defined unconditionally |
| 17:03 | gfredericks | if(false){_.x = 1} |
| 17:03 | gfredericks | wat |
| 17:03 | bbloom | wat indeed. |
| 17:03 | gfredericks | just because that's how def is handled? |
| 17:03 | bbloom | yeah |
| 17:03 | gfredericks | sweet |
| 17:05 | technomancy | I think nstools addresses most of the problems immigrate is designed to handle, but in a much more elegant way |
| 17:06 | bbloom | gfredericks: notice how parsing 'def unconfiditionally modifies the current namespace: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/analyzer.clj#L324 |
| 17:06 | bbloom | technomancy: what's your opinion on the namespace discussion? |
| 17:07 | gfredericks | bbloom: I notice! |
| 17:08 | bbloom | gfredericks: it makes me sad, but to fix it, you'd need to have a -main function or something |
| 17:08 | gfredericks | bbloom: because gclosure doesn't like top-level code? |
| 17:08 | bbloom | gfredericks: no, b/c the top level of clojure complects run and compile time |
| 17:09 | bbloom | gfredericks: it's too bad that clojure.core isn't divided up into clojure.core and clojure.compiler or something like that |
| 17:09 | gfredericks | so we could do it but we don't want to? |
| 17:09 | bbloom | gfredericks: it would be a pretty big breaking change, so not gonna happen |
| 17:10 | gfredericks | what would it break? people who rely on (if false (def something))? |
| 17:10 | bbloom | gfredericks: it would break any side-effectual code at the top level of a module |
| 17:11 | bbloom | the issue is that the environments are different. consider the *warn-on-reflection* var, which is often set! to true |
| 17:11 | bbloom | that var doesn't exist/matter outside the compiler at runtime |
| 17:12 | gfredericks | we're talking about fixing (if false (def something)), right? |
| 17:12 | technomancy | bbloom: 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:13 | bbloom | technomancy: are you referring to http://code.google.com/p/clj-nstools/ ? |
| 17:13 | technomancy | yeah |
| 17:13 | Raynes | google code |
| 17:13 | Raynes | evil one |
| 17:13 | technomancy | maybe it's worse if you use a lot of protocols, but the solution to that is easy: use fewer protocols |
| 17:13 | technomancy | Raynes: well the project dates from the days that Clojure was on Google Code |
| 17:13 | technomancy | so they get a pass |
| 17:14 | bbloom | i use damn near zero protocols :-P |
| 17:14 | Raynes | technomancy: 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:14 | Raynes | I'll overthrow the Enlive militia if it kills me. |
| 17:14 | technomancy | Raynes: cool. if I find myself needing HTML at some point in the future I'll give it a look. |
| 17:15 | Raynes | o/ |
| 17:15 | technomancy | \o |
| 17:15 | Raynes | technomancy: 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:15 | Raynes | I know it isn't all Heroku's fault, but man, 10+ hour downtime... |
| 17:16 | technomancy | yeah, can't blame you |
| 17:16 | amalloy | those poor folks who wanted to wrap up a paste for their children... |
| 17:16 | technomancy | I don't imagine refheap would be much administrative overhead on a VPS anyway |
| 17:17 | Raynes | amalloy: It was truly heartbreaking. |
| 17:17 | Raynes | technomancy: I moved to Heroku just because of how prone pastebins are to DDOS attacks. |
| 17:17 | Raynes | I don't know how to handle that crap. |
| 17:17 | Raynes | I could of pastebins have shut down over it. |
| 17:18 | amalloy | Raynes: actually i found a christmas present on refheap: https://www.refheap.com/paste/7851 |
| 17:18 | Anderkent | that last sentence didn't parse |
| 17:18 | clojurebot | the previous sentence is false |
| 17:18 | Raynes | amalloy: o/ |
| 17:20 | silasdavis | how can I require an java module from a local jar file |
| 17:20 | silasdavis | I have tried copying it to lib |
| 17:20 | gfredericks | lein doesn't like that |
| 17:20 | gfredericks | lein really wants that jar to be in a maven repo |
| 17:21 | silasdavis | ah |
| 17:21 | silasdavis | I'll do that then |
| 17:22 | silasdavis | how do wildcard requires? zephyr.android.HxMBT.* |
| 17:23 | gfredericks | you can't. (:import [zephyr.android.HxMBT OneClass AnotherClass OneMoarClass ...]) |
| 17:23 | Tolstoy | Trying 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:24 | Tolstoy | Otherwise, the clojurescript stuff works. |
| 17:28 | Tolstoy | Maybe 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:29 | Anderkent | Can I use memoize to speed up a self-recursive function? How do I refer to the memoized version? |
| 17:31 | technomancy | Anderkent: memoization would require stack-consuming recursion; `recur` skips it |
| 17:31 | Anderkent | technomancy: not tail recursive I'm afraid |
| 17:31 | gfredericks | Anderkent: alter-var-root should work |
| 17:31 | bbloom | wouldn't (def f (memoize (fn [x] ... (f y))) be fine? |
| 17:32 | gfredericks | bbloom: that too |
| 17:32 | technomancy | sure |
| 17:32 | gfredericks | wait does it? |
| 17:32 | gfredericks | I guess so. |
| 17:33 | Anderkent | thanks, that does it |
| 17:33 | gfredericks | but we need to use alter-var-root more for technomancy's sake |
| 17:33 | technomancy | so I can yell at you more? |
| 17:33 | gfredericks | it's what I wake up for |
| 17:34 | Anderkent | it's how you wake up |
| 17:34 | Anderkent | :) |
| 17:34 | technomancy | but I'm fine with non-runtime use of it |
| 17:34 | technomancy | ~gourds |
| 17:34 | clojurebot | SQUEEZE HIM! |
| 17:39 | zilti | I'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:21 | Rich_Morin | In "(fn foo [] ...)", is foo only used to allow recursion? |
| 18:21 | danlarkin | sometimes also to allow for easier-to-read stacktraces |
| 18:22 | Rich_Morin | point; tnx |
| 18:22 | yogthos | it's also what defn does under the covers |
| 18:22 | bbloom | Rich_Morin: to clarify, it's very different from (let [foo (fn [] ... |
| 18:22 | yogthos | (macroexpand '(defn foo [])) => (def foo (clojure.core/fn ([]))) |
| 18:23 | yogthos | lol not quite I guess :) |
| 18:23 | yogthos | should've read it first lol |
| 18:23 | Rich_Morin | tnx all! |
| 18:24 | bawr | (macroexpand '(defn foo [x y] x)) |
| 18:24 | zilti | bbloom: In what is it that different from (let [foo (fn ? |
| 18:24 | bawr | &(macroexpand '(defn foo [x y] x)) |
| 18:24 | lazybot | ⇒ (def foo (clojure.core/fn ([x y] x))) |
| 18:24 | yogthos | oh nice |
| 18:24 | bbloom | zilti: 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:25 | bawr | bbloom: what do you mean "to all future bindings"? |
| 18:25 | yogthos | I guess if you rebind it later inside the let? |
| 18:25 | bbloom | ,(let [f (fn [x] x) g f] (g 1)) |
| 18:25 | clojurebot | 1 |
| 18:26 | bbloom | ,(let [z (fn f [x] x) g f] (g 1)) |
| 18:26 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: f in this context, compiling:(NO_SOURCE_PATH:0)> |
| 18:26 | bbloom | i mean later bindings in the same let |
| 18:26 | bawr | Aah. |
| 18:26 | bawr | I see. |
| 18:26 | bbloom | lets occur in series |
| 18:26 | yogthos | &(let [x 1] (let [x (inc x)] (println x))) |
| 18:26 | lazybot | ⇒ 2 nil |
| 18:26 | yogthos | is that what you meant? |
| 18:28 | bbloom | what 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:28 | yogthos | ah ok |
| 18:29 | yogthos | like let* in cl |
| 18:29 | bbloom | yogthos: right |
| 18:29 | bbloom | if you need parallel let, like in cl, you can use letfn |
| 18:29 | bbloom | which allows for mutually recursive definitions |
| 18:30 | yogthos | ah I haven't considered that |
| 18:30 | zilti | By parallel let do you mean being able to call functions defined later in the letfn? |
| 18:30 | yogthos | I always took clojure style let for granted |
| 18:30 | bbloom | zilti: in a letfn, all bindings occur simultaneously and are available in each other's lexical scopes |
| 18:31 | zilti | bbloom: Good to know, didn't know that. |
| 18:31 | bbloom | yeah, 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:32 | bbloom | doesn't make sense in PERSISTENT/IMMUTABLE data structures, i mean |
| 18:32 | yogthos | today I learned :P |
| 18:32 | yogthos | I wondered about letfn before, this makes perfect sense though |
| 18:33 | bbloom | in 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:33 | zilti | I always thought it to be a "convenience function" but never figured why that very slight gain in characters would justify it :) |
| 18:33 | yogthos | ditto |
| 18:33 | yogthos | as always it turns out there's a deeper meaning there |
| 18:36 | gfredericks | (doc letfn*) |
| 18:36 | clojurebot | Excuse me? |
| 18:36 | gfredericks | ,(doc letfn*) |
| 18:36 | clojurebot | Huh? |
| 18:36 | bbloom | no * |
| 18:36 | bbloom | (doc letfn) |
| 18:36 | clojurebot | "([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:36 | zilti | ,(doc letfn) |
| 18:36 | clojurebot | "([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:36 | gfredericks | bbloom: letfn* is the special form I think |
| 18:37 | gfredericks | ,(macroexpand '(letfn [(a [] 2)] 42)) |
| 18:37 | clojurebot | (letfn* [a (clojure.core/fn a [] 2)] 42) |
| 18:37 | zilti | Does that * have a special meaning in Clojure/Lisp? I noticed it being used for the composable variants of functions in sqlkorma and Lamina. |
| 18:37 | bbloom | gfredericks: the true underlying special forms are an implementation detail :-) |
| 18:37 | gfredericks | zilti: it gets used to mean several different things |
| 18:37 | bbloom | zilti: x* just means "like x but slightly different" |
| 18:38 | bbloom | similar to x' which means "a new value of x" |
| 18:38 | bbloom | and *x* means "x is a dynamic var" |
| 18:38 | bbloom | but these are just conventions, not enforced |
| 18:38 | gfredericks | bbloom: I thought doc responded to special forms though |
| 18:38 | gfredericks | ,(doc var) |
| 18:38 | clojurebot | Huh? |
| 18:38 | gfredericks | &(doc var) |
| 18:38 | lazybot | ⇒ ------------------------- 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:39 | gfredericks | &(doc letfn*) |
| 18:39 | lazybot | ⇒ nil |
| 18:39 | gfredericks | hrm |
| 18:40 | bbloom | gfredericks: it's a hardcoded hack: https://github.com/clojure/clojure/blob/master/src/clj/clojure/repl.clj#L18 |
| 18:43 | tpope | bbloom: I have a proof of concept stacktrace parser. I'm struggling with how to reliably get my hands on the stack trace |
| 18:43 | zilti | Hell, we have 2012 and copying files does not ensure them being consistent |
| 18:43 | bbloom | tpope: 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:44 | yogthos | haha |
| 18:44 | tpope | bbloom: I make vim plugins till I'm broke, then take the first shitty rails contract I can get my hands on :/ |
| 18:44 | yogthos | my trick is to make a project first and then use it at work :P |
| 18:45 | tpope | with any luck I'll be able to change that to "first shitty clojure contract" soon enough |
| 18:45 | bbloom | tpope: enjoying clojure? |
| 18:45 | tpope | so far so good |
| 18:45 | bbloom | cool |
| 18:45 | tpope | sometimes I feel it's like 5 times too smart for me |
| 18:46 | bbloom | ok well what's the stack trace issue? my stack trace skills are weak, but i might be able to provide some insight |
| 18:46 | Raynes | I'm of the opinion that if you can do vimscript, you're smart enough for Clojure |
| 18:46 | bbloom | tpope: nah, you just need to unlearn so many things you take for granted. it's just different |
| 18:46 | yogthos | it is for sure |
| 18:46 | yogthos | but it's really self consistent which helps a lot |
| 18:46 | tpope | bbloom: I want to make it so that if evaling something gives an error, the stack trace is prepopulated into the location list |
| 18:46 | yogthos | you learn one concept and you can just apply it everywhere :) |
| 18:47 | tpope | makes sense, right? |
| 18:48 | tpope | Raynes: I remain optimistic |
| 18:48 | tpope | bbloom: biggest challenge. how do I get the stack trace out of nrepl? |
| 18:49 | tpope | I can eval (.getStackTrace *e), but then I've stepped on *1, etc |
| 18:50 | Raynes | tpope: (def temp *1) (.getStackTrace *e) (def *1 temp) |
| 18:50 | bbloom | Raynes: that would modify *2 and *3 :-P |
| 18:50 | tpope | yeah |
| 18:50 | Raynes | Fix them all. |
| 18:50 | Raynes | Rawr. |
| 18:50 | tpope | plus now I've dumped a temp var in the user's repl |
| 18:50 | bbloom | tpope: probably should ask cemerick, since *e etc are repl features |
| 18:50 | bbloom | not evaluator features |
| 18:51 | Raynes | tpope: That's what gensyms are for. |
| 18:51 | tpope | I could gensym it or something, but this is starting to get hairy |
| 18:51 | Raynes | Hacks are hack. |
| 18:51 | bbloom | nrepl provides multiple different commands other than "eval" right? |
| 18:51 | tpope | yes |
| 18:51 | tpope | I haven't exhaustively searched them |
| 18:51 | bbloom | is there a "get-var" command? |
| 18:52 | tpope | I guess I should |
| 18:53 | bbloom | https://github.com/clojure/tools.nrepl/blob/master/doc/ops.md |
| 18:53 | tpope | yeah just remembered where it was |
| 18:53 | tpope | I don't see anything |
| 18:54 | bbloom | tpope: you could clone the session and then eval whateve ryou want |
| 18:54 | tpope | ooh, cloning might work |
| 18:54 | bbloom | clone, eval, close |
| 18:54 | tpope | convoluted, but cleaner |
| 18:54 | bbloom | mmm immutability :-) |
| 18:54 | bbloom | cheap clones |
| 18:54 | bbloom | no idea what *actually* happens when cloning |
| 18:55 | bbloom | but i assume clone works |
| 18:55 | yogthos | presumably just a reference ;) |
| 18:55 | yogthos | and then it modifies its own tree from there right |
| 18:55 | bbloom | yogthos: right, my concern would be what happens with :stdin and :stdout |
| 18:55 | yogthos | mmm good point |
| 18:58 | bbloom | hmmm tpope, actually clone may not help |
| 18:58 | bbloom | ,#'*1 |
| 18:58 | clojurebot | #'clojure.core/*1 |
| 18:58 | tpope | what are the odds on that may? |
| 18:58 | bbloom | they *might* be dynamically rebound, such that each session gets their own |
| 18:59 | bbloom | but otherwise they are global mutable cells, rather than session data |
| 18:59 | bbloom | which seems odd, i'd assume nrepl needs to support multiple different *1 |
| 18:59 | bbloom | so i'd say it has like an 85% chance of working :-) |
| 18:59 | tpope | I estimate a half hour of bumbling around just to try it :/ |
| 18:59 | bbloom | ,(:dynamic (meta #'*1)) |
| 18:59 | clojurebot | true |
| 19:00 | bbloom | ok, 92% chance of success |
| 19:00 | bbloom | :-) |
| 19:03 | tpope | cool, foreplay shits itself on the nrepl source |
| 19:04 | bbloom | mmm metacircular |
| 19:44 | tpope | bbloom: doesn't work |
| 19:44 | bbloom | sad day :-( |
| 19:44 | bbloom | why not? |
| 19:44 | tpope | bbloom: also found https://github.com/clojure/tools.nrepl/blob/9b1fc6807cf87ad487887b1701abd1462028f635/src/test/clojure/clojure/tools/nrepl/sanity_test.clj#L113-134 :( |
| 19:45 | tpope | *e is nil in the cloned session |
| 19:45 | bbloom | tpope: seems like a bug |
| 19:46 | tpope | I suppose I could open an issue. A nice little xmas gift for cemerick |
| 19:46 | bbloom | tpope: tools.nrepl is tracked w/ jira |
| 19:46 | tpope | oh boy! |
| 19:46 | bbloom | dev.clojure.org |
| 19:47 | bbloom | i think you need a signed contributor agreement to open an issue there |
| 19:47 | bbloom | might be best to just email him :-P |
| 19:47 | tpope | I'll grab him in the channel sometime |
| 19:47 | bbloom | k |
| 19:54 | hyPiRion | bbloom tpope: No need to sign a CA for issue reporting |
| 19:54 | bbloom | ah ok thanks hyPiRion |
| 19:54 | tpope | cheers |
| 19:54 | hyPiRion | Just create an account there, and describe the issue :) |
| 19:54 | bbloom | hyPiRion: but you still do need to deal with jira :-P |
| 19:55 | tpope | this is less an issue and more a question anyways |
| 19:55 | hyPiRion | Ah |
| 19:57 | ravster | hello everyone |
| 19:57 | hyPiRion | hey |
| 20:11 | zilti | Here's my first "production-ready" micro-library: https://github.com/zilti/cynomys |
| 20:28 | mindbender1 | library authors, is there a significant perf diff in using sth |
| 20:28 | mindbender1 | like (foo {:bar ["baz"]}) as opposed to (foo :bar ["baz"]) |
| 20:29 | yogthos | depends on how you use it I find |
| 20:29 | yogthos | if you want to pass in some parameters I'd use it the second way |
| 20:30 | mindbender1 | yogthos: so what has been your finding cos I see a pervasice use of (foo :bar ["baz"]) among many clojure authors |
| 20:30 | mindbender1 | whereas I expect idiomatic usage of (foo {:bar ["baz"]) |
| 20:30 | yogthos | well 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:31 | yogthos | if it's something that specifies the environment options for example |
| 20:31 | yogthos | I find people tend to use the :flag foo notation |
| 20:31 | Raynes | Bahahaha |
| 20:32 | Raynes | yogthos: I forgot that you're the dude who did markdown-clj. |
| 20:32 | yogthos | :P |
| 20:33 | Raynes | So now I have to explain myself. |
| 20:33 | yogthos | hehe |
| 20:33 | yogthos | lol you opened a couple of bugs on it too :) |
| 20:34 | Raynes | yogthos: So, I complained about you using markdown-clj in lib-luminus. |
| 20:34 | yogthos | yeah you said you use pegdown for refheap right? |
| 20:35 | Raynes | yogthos: 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:36 | Raynes | Is there a big reason for markdown-clj? Some reason pegdown wasn't sufficient? |
| 20:36 | yogthos | main motivation was to make something that runs both in clojure and clojurescript :) |
| 20:36 | yogthos | for example in my blog I want to preview posts/comments |
| 20:36 | yogthos | and if you have a different js implementation of markdown it's not guaranteed to look the same when the server renders it |
| 20:37 | yogthos | but yeah it's not nearly as featureful as pegdown |
| 20:37 | Raynes | That makes sense. |
| 20:37 | yogthos | thanks :) |
| 20:37 | yogthos | lol originally I did it for lulz |
| 20:38 | mindbender1 | yogthos: 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:38 | yogthos | I 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:38 | Raynes | yogthos: Anyways, I just wanted to explain my reasoning, since I was pretty mean about it yesterday. |
| 20:38 | yogthos | so I was like can't be that bad to parse md, turns out it's not trivial to do it right :P |
| 20:39 | yogthos | no prob dude, I'm actually surprised it got as popular as it did |
| 20:39 | yogthos | all 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:39 | mindbender1 | Same question goes to others |
| 20:40 | mindbender1 | all these is still not heloing with the order problem |
| 20:40 | mindbender1 | helping |
| 20:40 | Raynes | yogthos: I think I'll throw together a little wrapper library for pegdown. |
| 20:40 | yogthos | yeah that'd be cool |
| 20:40 | Raynes | And perhaps use that in lib-noir, adding an optional extensions arg to md->html |
| 20:40 | yogthos | pegdown is pretty slick for sure |
| 20:41 | yogthos | that'd be nice, I moved the function to the template for now btw |
| 20:41 | Raynes | Well that'd be fine too. |
| 20:41 | yogthos | but yeah I was thinking about it |
| 20:41 | yogthos | I think it'd be best to keep libs in lib-noir and config in the template |
| 20:42 | yogthos | this way it makes updating libraries easier |
| 20:42 | Raynes | A 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:42 | yogthos | if too much stuff gets into template, then people are gonna have a hell of a time upgrading their apps |
| 20:42 | Raynes | So I'll still do that either way. |
| 20:42 | yogthos | yeah let's get a pegdown wrapper in lib-noir and I'll move md->html back there after :) |
| 20:43 | ibdknox | a pegdown wrapper should be its own lib |
| 20:43 | Raynes | ibdknox: Duh. |
| 20:43 | yogthos | right yeah, we include the lib in lib-noir :) |
| 20:43 | Raynes | ibdknox: Always planned for a separate library. |
| 20:43 | ibdknox | yogthos: in terms of using md in cljs, I just use some the JS markdown things |
| 20:43 | ibdknox | righto |
| 20:43 | Raynes | ibdknox: Go back to light table and leave the lib-noring to me. |
| 20:44 | Raynes | :P |
| 20:44 | Raynes | ibdknox: (totally kidding) |
| 20:44 | ibdknox | lol |
| 20:44 | yogthos | hehe |
| 20:44 | ibdknox | see.. Raynes is mean. |
| 20:44 | Raynes | ibdknox: His reasoning for having a lib that works in both places is so that markdown renders the same. |
| 20:44 | Raynes | The problem is that markdown sucks because it doesn't have a standard that everyone follows. |
| 20:44 | ibdknox | ah |
| 20:44 | Raynes | Otherwise this wouldn't be a problem. |
| 20:44 | ibdknox | indeed |
| 20:44 | yogthos | the whole thing stemmed from this http://briancarper.net/blog/415/clojure-and-markdown-and-javascript-and-java-and |
| 20:45 | yogthos | that's the beauty of md it's such a loose "standard" :) |
| 20:45 | yogthos | every implementation does it a bit different |
| 20:45 | ibdknox | well maybe Jeff Atwood 's quest will succeed |
| 20:45 | yogthos | haha |
| 20:45 | Raynes | You see beauty in strange things, sir. |
| 20:45 | ibdknox | It would be nice if it did |
| 20:46 | yogthos | mindbender1: what was the question btw? |
| 20:46 | Raynes | It sure would. |
| 20:46 | yogthos | the worst thing about md is that it has redundant syntax for no apparent reason, like stwo eparate heading declarations |
| 20:47 | ibdknox | yeah |
| 20:47 | yogthos | and list behavior is largely undefined |
| 20:47 | yogthos | what can go inside lists, how the spacing works, etc |
| 20:47 | ibdknox | I love doing things with GFM though |
| 20:47 | yogthos | btw could also link this in lib-noir :) https://github.com/yogthos/clj-pdf |
| 20:48 | yogthos | I was looking through django features |
| 20:48 | yogthos | and they have a pdf renderer |
| 20:48 | yogthos | can be nice for some stuff like reporting |
| 20:49 | ibdknox | I wonder if it just makes sense to point to these sorts of things in some canonical up-to-date place on webnoir |
| 20:49 | ibdknox | that's largely the problem |
| 20:49 | ibdknox | it's impossible to find this stuff |
| 20:49 | yogthos | yeah I know |
| 20:49 | yogthos | actually I heard from clojars guys that they plan to add number of downloads stats for libs |
| 20:49 | yogthos | that would help a lot |
| 20:49 | ibdknox | yes it would |
| 20:49 | yogthos | cause then you can see which libs people are using and what the health status is |
| 20:50 | yogthos | maybe could also show the frequency of updates |
| 20:50 | yogthos | and then you could sort by that :P |
| 20:50 | yogthos | I really think this has to be some automated feature not people aggregating libs by hand on some site |
| 20:50 | yogthos | that's just not sustainable |
| 20:50 | bbloom | yogthos: i wish github would bring back traffic stats too! |
| 20:50 | ibdknox | bbloom: me too |
| 20:50 | yogthos | yeah I know! |
| 20:51 | bbloom | the one down side to the automated approach is that it benefits incumbents |
| 20:51 | yogthos | but yeah seing how lein is the pretty much defacto standard it makes sense to track it through clojars |
| 20:52 | yogthos | true, but you could have different filters too, like activity |
| 20:52 | yogthos | new libs will have more activity than mature ones for example |
| 20:52 | yogthos | and it could give a combined weighted score too when sorting |
| 20:53 | bbloom | yogthos: i'd want to sort by the first differential of the number of new projects depending on that lib :-) |
| 20:53 | bbloom | ie show me what people are switching to |
| 20:53 | yogthos | that's a good idea |
| 20:55 | mindbender1 | yogthos: I'm just saying work hard to hide implementation details |
| 20:56 | yogthos | yeah that I definitely agree with |
| 20:56 | yogthos | what's the context though? |
| 20:57 | mindbender1 | It's just that when I see that form of order I ask myself why couldn't amap work here |
| 20:59 | yogthos | ah |
| 20:59 | mindbender1 | like they say eventual consistency is hard for programmers |
| 21:00 | yogthos | I don't think it's that bad in this particular context though, optional flags come at the end is not a bad convention |
| 21:00 | mindbender1 | those can work in maps too |
| 21:00 | yogthos | and it does make it a bit more readable I find, but admittedly not that much |
| 21:00 | mindbender1 | they are very open |
| 21:01 | mindbender1 | it allows your code to work in a threaded program |
| 21:02 | yogthos | I think it does mostly come down to aesthetics |
| 21:02 | yogthos | and realistically, you still have to read the docs to know what to pass in |
| 21:02 | yogthos | so it's not that using a map is going to make that any better |
| 21:03 | mindbender1 | but then you remove the order |
| 21:03 | mindbender1 | and save users the headache of syntac |
| 21:03 | mindbender1 | syntax |
| 21:03 | yogthos | true, but I think the headache is mostly perceived in this case no? |
| 21:04 | mindbender1 | when it builds up with other programs |
| 21:05 | yogthos | can you give an example of what you mean? |
| 21:05 | mindbender1 | when I think of your syntax with a gazillion other syntax I have to think about |
| 21:06 | yogthos | but there's not much syntax in clojure to being with to be fair |
| 21:06 | yogthos | I keenly feel that point when working with scala for example |
| 21:06 | yogthos | every 5 min or so I end up googling how to do this or that correctly |
| 21:06 | mindbender1 | actually I was reading pallet before I came here to whine |
| 21:06 | yogthos | hehe |
| 21:07 | mindbender1 | so? clojure authors seem to want to make sure it arrives |
| 21:08 | mindbender1 | Actully I don't even know why project.clj adopted a similar syntax |
| 21:09 | mindbender1 | maybe we should stop using maps |
| 21:09 | yogthos | well you kind of need actual maps in most cases |
| 21:10 | yogthos | thing that bothers me more is the cons/conj behavior :) |
| 21:10 | mindbender1 | have you listened to stu's data oriented programming |
| 21:11 | yogthos | yup |
| 21:11 | mindbender1 | I think he shared some luv there |
| 21:24 | gfredericks | it disappoints me sometimes that clojure maps aren't Comparable |
| 21:24 | gfredericks | is no comparator better than an arbitrary one? |
| 21:25 | gfredericks | I always enjoyed erlang's built-in total-ordering-over-all-types |
| 21:25 | gfredericks | I guess there could be no efficient ordering |
| 21:26 | gfredericks | erlang doesn't have maps :) |
| 21:26 | hyPiRion | how would you compare them? |
| 21:26 | yogthos | well you could check how many keys match? |
| 21:26 | yogthos | but that's definitely expensive |
| 21:27 | gfredericks | ignoring the efficiency question, it could be anything. |
| 21:27 | hyPiRion | Well then, what's the value of sorting them? |
| 21:27 | yogthos | so the more keys match the closer they are to each other, there's definitely situations where that can be useful |
| 21:27 | yogthos | any sort of fuzzy logic |
| 21:27 | gfredericks | hyPiRion: I'm often interested in canonical representatives in sets of maps that aren't in a particular order |
| 21:28 | gfredericks | e.g., from a db query |
| 21:28 | yogthos | that's actually a good example, say you have users in db and you want to find duplicates |
| 21:28 | gfredericks | yogthos: 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:29 | yogthos | yeah it's not hard to implement ;) |
| 21:29 | bbloom | i think the fact that it's not obvious how to compare them implies that, yes, no comparer is better than an arbitrary one |
| 21:29 | gfredericks | but I imagine that a vector's comparability depends on its entries as well |
| 21:29 | gfredericks | ,(sort [[] [2] [4]]) |
| 21:29 | clojurebot | ([] [2] [4]) |
| 21:29 | gfredericks | ,(sort [[] [{2 2}] [{}]]) |
| 21:29 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Comparable> |
| 21:29 | gfredericks | yep |
| 21:30 | gfredericks | bbloom: 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:31 | yogthos | I suspect that could lead to some hard to track down errors too though |
| 21:31 | hyPiRion | It's more evident to write, say |
| 21:31 | hyPiRion | ,(sort-by count [{} {:a 4} {:a :b :c :d}]) |
| 21:31 | clojurebot | ({} {:a 4} {:a :b, :c :d}) |
| 21:31 | hyPiRion | than just sort. |
| 21:32 | hyPiRion | I guess that's why, mostly. |
| 21:32 | gfredericks | hyPiRion: certainly in situations where you care how it's sorted, yes |
| 21:33 | gfredericks | oh wait wouldn't c.c/hash allow a usually-efficient ordering? |
| 21:33 | hyPiRion | gfredericks: I was just thinking about that |
| 21:34 | hyPiRion | It's consistent, as long you don't have mutables within the maps |
| 21:34 | gfredericks | which is lame to begin with |
| 21:34 | hyPiRion | AND it's totally ordered, sans collisions. |
| 21:34 | gfredericks | on collisions you just do some difficult slow thing |
| 21:35 | hyPiRion | another hashing |
| 21:35 | hyPiRion | with different algorithm |
| 21:35 | gfredericks | or just compare (sort m1) with (sort m2) |
| 21:36 | gfredericks | haha would that be (sort-by sort my-maps)? :D |
| 21:36 | gfredericks | ,(sort-by sort [{:a 12} {:b 17 :c 15} {} {:a 12}]) |
| 21:36 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.ArraySeq cannot be cast to java.lang.Comparable> |
| 21:36 | hyPiRion | nope, more like.. |
| 21:37 | gfredericks | consarnit |
| 21:37 | gfredericks | ,(sort-by (comp vec sort) [{:a 12} {:b 17 :c 15} {} {:a 12}]) |
| 21:37 | clojurebot | ({} {:a 12} {:a 12} {:c 15, :b 17}) |
| 21:37 | gfredericks | there it goes |
| 21:37 | hyPiRion | Gosh darnit, I need two maps with the same hash to test it out |
| 21:38 | hyPiRion | ,(sort-by (comp vec sort) [{:a 12} {:b 17 :c 15} {} {1 12}]) |
| 21:38 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.Keyword> |
| 21:38 | gfredericks | oh the hashing does give you more flexibility about types doesn't it |
| 21:38 | hyPiRion | ,(mapv hash [{:a 0} {:a nil}]) |
| 21:38 | clojurebot | [1013910569 1013910569] |
| 21:38 | hyPiRion | right. |
| 21:39 | gfredericks | (def other-hash (comp hash pr-str)) |
| 21:39 | hyPiRion | Blugh, hahah. |
| 21:39 | hyPiRion | ,(sort-by (comp hash pr-str) [{:a 12} {:b 17 :c 15} {} {1 12}]) |
| 21:39 | clojurebot | ({:a 12} {1 12} {} {:c 15, :b 17}) |
| 21:40 | hyPiRion | Actually, god damnit |
| 21:40 | hyPiRion | ,(sort-by pr-str [{:a 12} {:b 17 :c 15} {} {1 12}]) |
| 21:40 | clojurebot | ({1 12} {:a 12} {:c 15, :b 17} {}) |
| 21:40 | gfredericks | lerlz |
| 21:40 | hyPiRion | That's totally ordered, too. |
| 21:41 | hyPiRion | ,(sort-by pr-str [{2 12} {:b 17 :c 15} {1 13} {1 12}]) |
| 21:41 | clojurebot | ({1 12} {1 13} {2 12} {:c 15, :b 17}) |
| 21:41 | gfredericks | unless you want it to distinguish between types that print the same |
| 21:41 | hyPiRion | Well, if you're that guy, then fuck you. |
| 21:41 | gfredericks | yeah fuck him |
| 21:41 | hyPiRion | Because this is good enough |
| 21:41 | gfredericks | alright go commit it to core so we can make it into 1.5 |
| 21:42 | gfredericks | we've hammock'd enough |
| 21:42 | hyPiRion | Yeah, rhickey would surely add this in |
| 21:42 | yogthos | rofl |
| 21:42 | hyPiRion | Foolproof. |
| 21:43 | gfredericks | it 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:43 | gfredericks | I think couchdb does that too |
| 21:43 | hyPiRion | I'm working on a patch now |
| 21:43 | gfredericks | it helps to have a closed set of types |
| 21:44 | gfredericks | if we get into class names then we'll conflict with clojure's multiple-classes-per-datastructure approach |
| 21:46 | bbloom | there is no mutually exclusive list of protocols, which is on purpose |
| 21:46 | bbloom | you can have a map that is also a vector, if you really wanted to |
| 21:46 | bbloom | in fact, vectors already are maps.... |
| 21:46 | gfredericks | sorta? |
| 21:46 | gfredericks | ,(map? [3 4]) |
| 21:46 | clojurebot | false |
| 21:46 | gfredericks | so not in every sense at least |
| 21:46 | hyPiRion | Vectors aren't maps |
| 21:47 | bbloom | (doc map) |
| 21:47 | clojurebot | "([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:47 | bbloom | (doc map?) |
| 21:47 | clojurebot | "([x]); Return true if x implements IPersistentMap" |
| 21:47 | bbloom | ,(instance? IAssoc [3 4]) |
| 21:47 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: IAssoc in this context, compiling:(NO_SOURCE_PATH:0)> |
| 21:47 | bbloom | ,(instance? IAssocative [3 4]) |
| 21:47 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: IAssocative in this context, compiling:(NO_SOURCE_PATH:0)> |
| 21:47 | gfredericks | bbloom: clojure.lang maybe |
| 21:47 | bbloom | ,(instance? IAssociative [3 4]) |
| 21:47 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: IAssociative in this context, compiling:(NO_SOURCE_PATH:0)> |
| 21:47 | bbloom | ,(instance? clojure.lang.IAssociative [3 4]) |
| 21:47 | clojurebot | #<CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.lang.IAssociative, compiling:(NO_SOURCE_PATH:0)> |
| 21:47 | hyPiRion | Vectors has an ordering, whereas maps have no ordering |
| 21:48 | gfredericks | hyPiRion: that's not a convincing argument |
| 21:48 | bbloom | dur, no I |
| 21:48 | bbloom | ,(instance? clojure.lang.Associative [3 4]) |
| 21:48 | clojurebot | true |
| 21:48 | bbloom | ,(instance? clojure.lang.Associative {3 4}) |
| 21:48 | clojurebot | true |
| 21:48 | bbloom | ,(assoc [0 1 2 3] 2 :omg) |
| 21:48 | clojurebot | [0 1 :omg 3] |
| 21:48 | gfredericks | hyPiRion: vectors behave similarly to maps in some cases, as bbloom is demonstrating |
| 21:49 | gfredericks | ,(dissoc '[a b c d] 3) |
| 21:49 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap> |
| 21:49 | hyPiRion | Clearly. |
| 21:49 | gfredericks | hyPiRion: sorted-maps are also ordered |
| 21:50 | bbloom | the 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:50 | gfredericks | bbloom: yeah, I was sort of realizing the same thing |
| 21:50 | bbloom | effectively there is one type: a discriminated union of each of the primitive types |
| 21:50 | gfredericks | about fifteen inches up |
| 21:51 | bbloom | honesly, 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:53 | bbloom | which is sorta what happens defacto anyway |
| 21:53 | hyPiRion | You got what you wanted then, hurray |
| 21:53 | bbloom | ,(compare :foo 'foo) |
| 21:53 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.Keyword> |
| 21:53 | bbloom | ,(compare 'foo :foo) |
| 21:53 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.Symbol> |
| 21:54 | gfredericks | ,(compare [1 2 3] (subvec [1 2 3] 1)) |
| 21:54 | clojurebot | 1 |
| 21:54 | bbloom | gfredericks: logically speaking, you're promoting to sequences |
| 21:55 | gfredericks | ,(compare (seq [1 2 3]) (seq (subvec [1 2 3] 1))) |
| 21:55 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to java.lang.Comparable> |
| 21:55 | gfredericks | gotcha |
| 21:55 | hyPiRion | Huh |
| 21:55 | hyPiRion | "throw Util.sneakyThrow(e);" <<-- Within Clj source |
| 21:55 | hyPiRion | That guy, he's sneaky. |
| 21:56 | bbloom | gfredericks: heh, i'm actually surprised by that |
| 21:56 | bawr | XD |
| 21:56 | gfredericks | bbloom: phew. I thought I would get accused of ignoring your word "logically" |
| 21:57 | bbloom | gfredericks: ok fine, logically promoted to clojure.lang.Sequential |
| 21:57 | bbloom | which apparently isn't comparable either lol |
| 21:57 | gfredericks | well it's an interface |
| 21:57 | gfredericks | I guess it could extend comparable, eh? |
| 21:58 | bbloom | now i wonder: why aren't seqs comparable? |
| 21:58 | gfredericks | maybe the idea was that potentially infinite types shouldn't be comparable |
| 21:58 | hyPiRion | bbloom: They may be lazy and infinite. |
| 21:58 | hyPiRion | Have fun comparing that |
| 21:58 | bbloom | hyPiRion: dur. of course that makes perfect sense |
| 21:58 | gfredericks | ,(compare (range) (rest (range))) |
| 21:58 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Comparable> |
| 21:58 | gfredericks | ,(compare (vec (range)) (vec (rest (range)))) |
| 21:59 | hyPiRion | hah. |
| 21:59 | bbloom | gfredericks: poor little clojurebot |
| 21:59 | bbloom | he works so hard |
| 21:59 | gfredericks | what does an eval server do for timeouts? Isn't killing a thread supposed to be unsafe? |
| 21:59 | bbloom | gfredericks: java have timeout security context feature thinggies |
| 22:00 | gfredericks | slick |
| 22:00 | bbloom | &(compare (vec (range)) (vec (rest (range)))) |
| 22:00 | lazybot | Execution Timed Out! |
| 22:01 | gfredericks | ,(println "yo?") |
| 22:01 | clojurebot | yo? |
| 22:01 | gfredericks | phew |
| 22:01 | bbloom | you didn't kill it :-P |
| 22:02 | gfredericks | we have had 0 days since the last (println "yo?") |
| 22:07 | hyPiRion | gfredericks: https://github.com/hyPiRion/clojure/commit/4ef68dc957efa8fb4ade95260cade47a93880ddf |
| 22:08 | hyPiRion | Now you have sortable maps |
| 22:08 | hyPiRion | Too bad it killed sorted-map though, all the sorted-map tests failed it seems. |
| 22:08 | gfredericks | if you're not breaking sorted-map you're not doing real work |
| 22:08 | gfredericks | that's what my grandma always used to say |
| 22:09 | hyPiRion | Good thing I'm doing real work then! |
| 22:09 | gfredericks | haha I love that commit message |
| 22:10 | hyPiRion | It sounds like that's a feature, not a bug |
| 22:11 | hyPiRion | "1.5: sorted maps are now not only deprecated, they also have completely undefined behaviour" |
| 22:14 | gfredericks | "1.5: the syntactic role of parentheses and square-brackets have been swapped everywhere." |
| 22:14 | gfredericks | I wonder how much change in the java code that would require |
| 22:15 | hyPiRion | [let ((a b) (2 3)) [+ a b]] => 5 |
| 22:15 | hyPiRion | gfredericks: Probably two lines |
| 22:15 | gfredericks | hyPiRion: and then a gsub or something over all the clj files |
| 22:15 | hyPiRion | Well, four, |
| 22:15 | hyPiRion | Oh lordy |
| 22:16 | hyPiRion | That's my new goal |
| 22:16 | yogthos | fork clojure and swap square brackets and parens? :P |
| 22:17 | gfredericks | hyPiRion: name in Dlojure |
| 22:17 | bawr | Why are sorted maps deprecated? :< |
| 22:17 | yogthos | I think we're on to something here :P |
| 22:17 | bbloom | bawr: they aren't. these guys are just joking around |
| 22:18 | bawr | Go deeper. ()->{}->[]->|| |
| 22:18 | bawr | ELIMINATE PARENS ALTOGETHER. |
| 22:18 | yogthos | or you could just do what scheme does and make them interchangable :P |
| 22:19 | hyPiRion | bawr: Sweet idea |
| 22:19 | bawr | Oh, the wonderful ambiguities of trying to swap [] with one token. xD |
| 22:19 | gfredericks | (defmacro with-silly-delimeters [& forms] `(do ~@(map (partial wk/postwalk #(cond (vector? %) (list %) (seq? %) (vec %) :else %)) forms))) |
| 22:19 | yogthos | you could name it dylan :) |
| 22:19 | yogthos | http://en.wikipedia.org/wiki/Dylan_(programming_language) |
| 22:20 | hyPiRion | gfredericks: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L91-94 |
| 22:20 | amalloy | gfredericks: you probly want list* |
| 22:20 | bawr | hyPiRion: But once that proves to be impossible, hey. []-><> can work, too. |
| 22:20 | yogthos | 4 lines it is |
| 22:20 | gfredericks | amalloy: ah that's why it doesn't work |
| 22:20 | gfredericks | that did it |
| 22:21 | hyPiRion | It's amazing that all these Clojure things I just joke around with makes me so knowledgeable around the internals |
| 22:21 | gfredericks | amalloy is the only person who reads my macros |
| 22:22 | hyPiRion | ,(list* ()) |
| 22:22 | clojurebot | nil |
| 22:22 | bawr | gfredericks: Oh I read it, I just didn't parse it. ;) |
| 22:22 | hyPiRion | it's not as easy as you'd like it to be |
| 22:22 | gfredericks | hyPiRion: maybe seq is better |
| 22:22 | hyPiRion | ,(seq ()) |
| 22:22 | clojurebot | nil |
| 22:23 | hyPiRion | :p |
| 22:23 | gfredericks | whoops |
| 22:23 | gfredericks | of course |
| 22:23 | gfredericks | (or (seq %) ()) then |
| 22:23 | hyPiRion | Surely that's the best way of doing this. |
| 22:23 | hyPiRion | Wait. |
| 22:24 | hyPiRion | yeah, that's the best way |
| 22:24 | hyPiRion | must be. |
| 22:39 | gfredericks | man this reader code is so OO |
| 22:39 | ibdknox | do it with blind |
| 22:41 | gfredericks | okay with the power of google I cannot figure out what that cryptic comment meant |
| 22:42 | ibdknox | soon to be tools.reader: https://github.com/Bronsa/blind |
| 22:43 | gfredericks | eventually replacing the core reader? or what's the utility of making it a core lib? |
| 22:45 | bbloom | gfredericks: will probably become the reader for clojurescript |
| 22:46 | bbloom | and via that channel, will eventually replace the core reader.... at about the same speed pypy is replacing cpython :-P |
| 22:46 | gfredericks | clojurescript gets to have all the fun |
| 22:46 | ibdknox | it's very useful for tools guys :) |
| 22:47 | gfredericks | clojure: a good language for building clojurescripts in |
| 23:24 | amalloy | gfredericks, hyPiRion: ##(doc sequence) |
| 23:24 | lazybot | ⇒ ------------------------- 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:25 | gfredericks | woah it's like the opposite of seq |
| 23:43 | hyPiRion | All these core nuggets |
| 23:43 | hyPiRion | ,(#'clojure.core/>1? 2) |
| 23:43 | clojurebot | true |
| 23:59 | technomancy | slamhound is back ladies and gents |