2012-03-23
| 00:00 | cemerick | oooh |
| 00:00 | lynaghk | despite the assurances of the folks at the desk |
| 00:00 | cemerick | nasty |
| 00:00 | lynaghk | yeah, I thought maybe Silicon Valley would be the one place where stuff like that works...nope. |
| 00:00 | cemerick | "sign out" rarely means Sign Out anyway |
| 00:01 | lynaghk | there wasn't anything, actually. I thought the first screen was "welcome to our kiosk iPad", but it turns out it was "welcome to the iPad you just purchased" |
| 00:02 | ibdknox | lol |
| 00:02 | ohpauleez | lynaghk: ping |
| 00:02 | lynaghk | so I couldn't do anything but really paw at it with all combinations of my digits |
| 00:02 | ohpauleez | YES |
| 00:02 | ibdknox | lynaghk: don't pong |
| 00:02 | ohpauleez | finally! |
| 00:02 | ibdknox | don't do it |
| 00:02 | ohpauleez | haha |
| 00:02 | ibdknox | run |
| 00:02 | lynaghk | yo Paul! I was about to send you a pull request |
| 00:02 | cemerick | he's irc'ing from in the building! |
| 00:02 | lynaghk | need keyword args propogated for your kibit change |
| 00:03 | ibdknox | cemerick: lol |
| 00:03 | ohpauleez | Cool, I just saw you forked. |
| 00:03 | ohpauleez | Totally send the request, and shoot me an email me if you have any special requests. I usually get changes in daily |
| 00:04 | ohpauleez | hahah cemerick |
| 00:04 | lynaghk | ohpauleez: yeah, I think there are some other changes I need to figure out first. |
| 00:04 | lynaghk | ohpauleez: cool thanks. |
| 00:04 | cemerick | ibdknox: what have you been recommending for auth in conjunction with noir? |
| 00:04 | cemerick | ohpauleez: hey paul :-) |
| 00:04 | ibdknox | cemerick: define auth |
| 00:04 | ibdknox | cemerick: as in just putting pages behind privileges? |
| 00:05 | cemerick | authentication / authorization |
| 00:05 | ohpauleez | I think David is totally right, what you want to do is totally possible. I think what we might see if that we spin out a new project that we base kibitz on |
| 00:05 | ohpauleez | I'm not so sure yet, but we'll see |
| 00:05 | ohpauleez | cemerick: Hey! what are we doing up right now? |
| 00:06 | ibdknox | cemerick: you can do the filtering very easily using pre-routes |
| 00:06 | ibdknox | cemerick: no one has created a magical auth thing, past that |
| 00:07 | cemerick | ibdknox: ah, I see you have a dep on jbcrypt directly; so you're providing form-based authentication yourself? |
| 00:08 | ibdknox | cemerick: just an encryption util to make sure people don't do something bad... like use sha1 |
| 00:08 | cemerick | ohpauleez: heh, sometimes I'm up 'til 4 if I'm being a spaz. |
| 00:08 | cemerick | ok |
| 00:09 | muhoo | i dunno how magical you're looking for, but there's this: https://github.com/sumilux/ssi-java-client |
| 00:09 | ibdknox | cemerick: decent example here: https://github.com/ibdknox/Noir-blog/blob/master/src/noir_blog/views/admin.clj#L51 |
| 00:11 | cemerick | ibdknox: I'm building a ring-security lib. form/basic/openid/oauth/etc, role-based authorization, channel redirection, etc. Tired of cobbling stuff together constantly. |
| 00:12 | brehaut | cemerick: excellent! |
| 00:13 | cemerick | Meh. Doing it out of anger. |
| 00:13 | brehaut | thats how many web things get written isnt it? |
| 00:13 | cemerick | In retrospect, probably one of the reasons I try to stay away from webby things in general. :-P |
| 00:13 | brehaut | haha |
| 00:14 | xeqi | cemerick: I've been looking for one of those |
| 00:14 | xeqi | like a ring version of warden |
| 00:14 | brehaut | i certainly didnt write necessary evil for fun :P |
| 00:14 | cemerick | I tried *really* hard to get spring-security to work with containerless jetty. Two days later, I cried uncle. |
| 00:14 | ibdknox | I want someone to build every auth for clojure |
| 00:14 | ibdknox | I thought I convinced someone to do it |
| 00:14 | ibdknox | I've since forgotten who that was |
| 00:15 | brehaut | ibdknox: i believe some sort of karmic transmutation has made that be cemerick |
| 00:15 | cemerick | I'll do form, basic, and *maybe* openid. Someone else will have to bring me patches for the rest. |
| 00:16 | cemerick | xeqi: link for warden please? |
| 00:16 | xeqi | https://github.com/hassox/warden/wiki |
| 00:16 | brehaut | im sure raynes would love to do the oauth portion for you |
| 00:16 | cemerick | bwahahah |
| 00:16 | cemerick | xeqi: Thanks; and, hi :-) |
| 00:17 | ibdknox | brehaut: yeah he loves that shit |
| 00:17 | ibdknox | ;) |
| 00:17 | brehaut | haha |
| 00:18 | xeqi | just another library for inspiration; too busy making some ring testing libs based on rack-test/capybara to dig into it myself |
| 00:18 | xeqi | and, hi back |
| 00:18 | cemerick | xeqi: definitely, want to make sure I don't make too many egregious errors. |
| 00:19 | cemerick | You should all be scared shitless at this point. |
| 00:19 | muhoo | someone is building an everyauth thing as a service. it's this: http://www.social-sign-in.com/ |
| 00:19 | cemerick | login as a service as a service? o.0 |
| 00:20 | muhoo | cemerick: basically. yeah, i know. |
| 00:20 | xeqi | isn't that openid? |
| 00:20 | muhoo | openid works for some services, not all. |
| 00:20 | cemerick | login as a service as a service as a service, then. |
| 00:20 | xeqi | wait.. theres an extra "as a service" on the end of that |
| 00:20 | muhoo | "as a service" means "we can charge you for it" |
| 00:21 | muhoo | instead of all that open-source hippie stuff :-) |
| 00:22 | technomancy | what about sandbar? isn't it supposed to do auth-y stuff? |
| 00:22 | muhoo | (recur service) |
| 00:22 | lynaghk | ohpauleez: pull requested. |
| 00:22 | technomancy | muhoo: FWIW I think the repl task in lein2 is supposed to have a :headless option |
| 00:22 | technomancy | oh... but that's nrepl, not raw socket repl |
| 00:22 | ohpauleez | lynaghk: cool, thanks, I'll check it out right now |
| 00:22 | muhoo | technomancy: ooh, that'd be awesome. i hacked it to work anyway though. i just started it from systemd with /dev/null as stdin and syslog as stdout |
| 00:23 | cemerick | technomancy: yeah, I read its source earlier. It does 40 other things too, and makes some unfortunate choices, IMO. |
| 00:23 | ibdknox | cemerick: technomancy: brenton said use at your own risk |
| 00:23 | ibdknox | lol |
| 00:23 | technomancy | good to know, heh |
| 00:23 | ibdknox | he talked someone out of using it at clojurewest |
| 00:23 | ibdknox | so |
| 00:23 | cemerick | hah, I didn't know that |
| 00:23 | technomancy | suspected it was a bit sprawling at first glance |
| 00:23 | brehaut | its 5pm friday here, so have a good weekend everyone |
| 00:23 | lynaghk | you too brehaut. |
| 00:24 | cemerick | I saw https://github.com/brentonashworth/sandbar/wiki/Stateful-Sessions and was immediately concerned. |
| 00:24 | cemerick | Anyway. There's a bunch of good ideas in there that I'm going to steal. |
| 00:24 | technomancy | yeah, still plenty of gaps in the web stack; somebody's just gotta step up =) |
| 00:25 | ibdknox | pfft what are you talking about my few thousand lines of Noir totally covers everything ;) |
| 00:25 | ibdknox | lol |
| 00:25 | xeqi | he |
| 00:25 | muhoo | technomancy: so, fyi: with :repl-port set, this basically works: lein trampoline repl < /dev/null 2> somewhere >somewherelse |
| 00:25 | ibdknox | a solid everyauth would be a wonderful addition |
| 00:26 | cemerick | ibdknox: is 'everyauth' an actual thing, or just a shorthand you're using? |
| 00:26 | ibdknox | actual thing |
| 00:26 | ibdknox | https://github.com/bnoguchi/everyauth |
| 00:26 | ibdknox | I know it's node - try not to throw up |
| 00:26 | cemerick | hrm |
| 00:27 | cemerick | that'll take a bit of effort, but I'll work on it. :-) |
| 00:27 | cemerick | impressive list! |
| 00:27 | ibdknox | mostly if the base of it is there, it's trivial to add in the pieces |
| 00:27 | technomancy | muhoo: if a simple patch could make the repl task do what you need out of the box I'd be happy to take it |
| 00:27 | technomancy | muhoo: planning on cutting a 1.7.1 release next week |
| 00:27 | muhoo | technomancy: i'm not quite comfortable with the innards of lein yet. |
| 00:28 | muhoo | but, i'm sure i will be :-) and i'm looking forward to contributing. |
| 00:28 | cemerick | `npm install everyauth` ha ha, wat? |
| 00:28 | technomancy | I can help you step through the code tomorrow if you like |
| 00:28 | xeqi | cemerick: same idea for rack: https://github.com/intridea/omniauth |
| 00:28 | cemerick | (keep the good prior art flowing) |
| 00:29 | muhoo | technomancy: that'd be really helpful, thanks! i was looking for a kind of "guided tour" of how it works, but didn't find anything. |
| 00:29 | muhoo | a lot of how to USE it, it's easy. but not a lot of HOW it does what it does |
| 00:29 | technomancy | muhoo: yeah, especially the repl in lein1 is not documented outside my own head; fortunately it all got rewritten in lein2 |
| 00:31 | xeqi | cemerick: https://github.com/hassox/warden_omniauth - warden + omniauth |
| 00:34 | jmalone | i have seen the clojurewest slides but were the presentations recorded? |
| 00:34 | lynaghk | ohpauleez: How complex can kibit / core logic rewrites be? Does it do multiple passes over the code to make sure it finds all of the alternatives? |
| 00:35 | lynaghk | jmalone: yeah, I believe they will be released on a rolling basis starting in a few weeks. |
| 00:35 | lynaghk | dunno who's on deck though. |
| 00:35 | ohpauleez | lynaghk: There is no backtracking or context awareness. The upcoming will have "best rule" enabled |
| 00:35 | ohpauleez | right now I can only do that with loop-recur, but I'm certain core.logic can do that |
| 00:36 | lynaghk | hmm. I'm not so much thinking about backtracking but overlapping forms |
| 00:36 | ohpauleez | so (if (=0 0) :a nil) will go to :a |
| 00:36 | jmalone | lynaghk: thanks i guess ill just have to be patient |
| 00:37 | ohpauleez | alts would be when, (zero? 0), true, then just :a |
| 00:37 | lynaghk | e.g. in a reify you need to change two of the method names, but the rule for each will be (reify ...some/none... (method-to-match) ...some/none...) |
| 00:37 | lynaghk | jmalone: there is a secret draft of my talk on the youtube, if you don't feel like being patient. It's just me talking over slides though, so you can't see me waving around like an idiot. |
| 00:38 | ohpauleez | Yeah, that context can't be captured if it's a complex rule |
| 00:38 | ohpauleez | (reify . ?x (blah) . ?y) type of rule |
| 00:39 | lynaghk | ohpauleez: damns. I was thinking about looping through until alts stopped popping up, but that feels like a hack. |
| 00:39 | ohpauleez | or the subforms need to have subrules |
| 00:39 | jmalone | lynaghk: haha thanks ill look it up |
| 00:39 | ohpauleez | lynaghk: Ahhh yeah, we can do that |
| 00:39 | ohpauleez | I see what you're saying |
| 00:39 | ohpauleez | yes, that'll be in this next release |
| 00:39 | lynaghk | okay, rad. |
| 00:39 | lynaghk | are you still keepin' it static? |
| 00:40 | lynaghk | In an ideal world I could use the matching / replacement after macro expansion time. |
| 00:40 | ohpauleez | (if (= 0 0) :a nil) => (when (= 0 0) :a) => (when (zero? 0) :a) => (when true :a) => :a |
| 00:40 | ohpauleez | still static |
| 00:40 | ohpauleez | if you can express the smaller parts as rules, it'll pick it up |
| 00:41 | lynaghk | ohpauleez: okay, that sounds great. |
| 00:41 | ohpauleez | if-nil goes to when, = 0 is a zero?, zero? 0 is true, when true is dead code |
| 00:41 | ohpauleez | and we have rules for each of those |
| 00:42 | ohpauleez | My master branch does this with loop/recur, but we can do it better with core.logic, I just don't know how to yet |
| 00:42 | ohpauleez | haha |
| 00:42 | lynaghk | did you just see that phrase on a t-shirt in your mind? Because I did. |
| 00:42 | lynaghk | Maybe I'll make some for the next Conj. |
| 00:43 | ohpauleez | hahaha |
| 00:43 | ohpauleez | You'll be wealthy beyond your imagination |
| 00:43 | ohpauleez | Seriously, core.logic is like a real life oracle |
| 00:43 | ohpauleez | You think up any reality, and all of sudden it magical is possible |
| 00:43 | alexbaranosky | so on the front: "we can do it better with core.logic" and on the back: " I just don't know how to yet" |
| 00:44 | alexbaranosky | I'd buy that |
| 00:44 | lynaghk | alexbaranosky: yep. |
| 00:44 | muhoo | prolog will be the haskell of 2013 |
| 00:44 | ohpauleez | It's the alchemy of programming, except it works |
| 00:45 | muhoo | ryan senior's presentation on core.logic did definitely leave me dazzled and intrigued, sure |
| 00:45 | alexbaranosky | I feel like I'm inches away from writing a logic program, after watching Senior's talk |
| 00:45 | muhoo | alexbaranosky: jinx :-) |
| 00:46 | ohpauleez | We have a "Kibit reading list" |
| 00:46 | muhoo | i was thinking today, i need to find two resistors from my bag o' crap, to use for an op-amp, and i thought, "hmm, maybe i should write something in core.logic to tell me which ones to use" |
| 00:46 | ohpauleez | specific to simplifying expressions with logic |
| 00:46 | lynaghk | muhoo: just those two golden rules... |
| 00:48 | Zoka | muhoo: on what port are you running your repl server - is it internal testing? |
| 00:48 | slyrus | muhoo: wasn't prolog the haskell of 1995? |
| 00:48 | muhoo | Zoka: yes, just an ephemeral port so i can ssh in , do port forwarding, and get to it. |
| 00:50 | Zoka | If you do not mind running jetty on that port you can rin proper web based nREPl interface https://github.com/zoka/ringMon/ |
| 00:50 | Zoka | s /rin/run/ |
| 00:51 | Zoka | mohoo: see: As a replacemnet for lein repl section |
| 00:52 | muhoo | i saw that nrepl stuff, looks very cool, but i'm happy with (-> :repl-port ssh-port-forwarding emacs-comint-mode) for now |
| 00:53 | Zoka | No problem |
| 00:53 | ohpauleez | lynaghk: If you ever come out, you should totally come party/crash at Tutorspree HQ |
| 00:53 | ohpauleez | We just finished a solid Startup Crawl |
| 00:53 | lynaghk | ohpauleez: donezo. |
| 00:53 | muhoo | Zoka: thanks though. it's a very neat project. |
| 00:54 | lynaghk | Last time I was in NYC I crashed with the Mongo folks. |
| 00:54 | scriptor | you slept in their iffice? |
| 00:54 | scriptor | *office |
| 00:54 | lynaghk | no, just came by for high fives |
| 00:54 | scriptor | ah, yea their office hours thing is pretty cool |
| 00:54 | lynaghk | they have office hours, and they're pretty nice. I was in the middle of a node.js+mongo project. |
| 00:55 | muhoo | i hear they are managing risk very effectively at tutorspree |
| 00:55 | lynaghk | I was, er, younger then. |
| 00:56 | ohpauleez | muhoo: haha I heard that too somewhere |
| 00:59 | cemerick | lynaghk: we all have a seedy past ;-) |
| 01:00 | lynaghk | cemerick: I still have my fixed gear bicycle to prove how fast I went then. |
| 01:03 | lynaghk | cemerick: you're wise; let me know if you think the following is a terrible idea: Write JVM Clojure code, expand all of the macros manually, remove macro references from the namespace forms, run through kibit to munge away some platform differences, then write out to files for use with ClojureScript. |
| 01:03 | ztellman | the best questions begin with "you're wise;" |
| 01:04 | lynaghk | ztellman: you're also wise! also question for you! |
| 01:04 | jmalone | lynaghk: do you have a link for that video? |
| 01:04 | cemerick | lynaghk: good troll dude :-P |
| 01:04 | ztellman | lynaghk: same question? different question? |
| 01:04 | lynaghk | same question |
| 01:04 | cemerick | lynaghk: I dunno what the worse idea is: asking me for advice on ClojureScript, or what you're proposing. ;-) |
| 01:04 | lynaghk | ha |
| 01:04 | ztellman | ha |
| 01:05 | ztellman | lynaghk: I did something kind of analogous for Lamina |
| 01:05 | ztellman | there's some weirdness that is exposed when you macroexpand everything |
| 01:05 | lynaghk | jmalone: http://www.youtube.com/watch?v=T83P3PVSy_8 There were a few more slides at Clojure/West, but the gist is the same. |
| 01:05 | ztellman | especially w.r.t. chunked-append & co |
| 01:05 | dnolen | lynaghk: ohpauleez: hullo! btw, core.logic does backtracking for you. |
| 01:05 | ztellman | I don't know if cljs has matching structures for that |
| 01:06 | cemerick | lynaghk: you were there for the portability discussion; big ol' windmill, it is. |
| 01:06 | ohpauleez | dnolen: YES! I need to learn how to whisper to core.logic to achieve that |
| 01:06 | dnolen | ohpauleez: it's automatic |
| 01:06 | ztellman | core.logic whispers to itself |
| 01:06 | lynaghk | cemerick: not looking for total portability, and this will require some manual help (e.g. marking forms with metadata so that kibit will know to exclude them when generating code) |
| 01:07 | ohpauleez | ztellman: one would expect this |
| 01:07 | jmalone | lynaghk: i was feeling rather silly not being able to find it, now i see its unlisted so i feel less silly |
| 01:07 | cemerick | lynaghk: I think the first order of business would be working out conditional compilation bits. The extensible reader in 1.4 might be a reasonable basis for this. |
| 01:07 | ohpauleez | dnolen: Is my assumption right- core.logic could "recurse" or do I need to l explicitly loop |
| 01:07 | ztellman | conditional compilation would be nice |
| 01:07 | lynaghk | ztellman: CLJS macros are the same as CLJ ones, and happen at conversion time. The only reason I'd want to expand them manually is because it might be easier than evalin' to detect them and then munging the namespace forms. |
| 01:08 | cemerick | without that, you're going to hit a serious brick wall eventually, and have no recourse. |
| 01:08 | dnolen | ohpauleez: it's really fun to see core.logic be used for something like kibit. It's not a bad way to see if it's fast enough for code analysis :) |
| 01:08 | lynaghk | cemerick: what do you mean, conditional compilation? |
| 01:08 | ztellman | lynaghk: I meant whether there are cljs analogues for chunked seqs and all the other implementation details that are exposed by macroexpand |
| 01:08 | cemerick | #clj […clojure code] #cljs […cljs code…] |
| 01:08 | ztellman | basically, if your approach works for (for …), you're golden |
| 01:08 | dnolen | ohpauleez: core.logic is properly tail recursive, internal uses really fancy trampolines. |
| 01:08 | ztellman | but that's surprisingly hard |
| 01:08 | cemerick | that may or may not work |
| 01:09 | ohpauleez | dnolen: So far it's been a blast. The biggest limit is me and my understanding of the possibilities |
| 01:09 | cemerick | actually, it should definitely work. |
| 01:09 | lynaghk | ztellman: thanks for the tip. I believe that macroexpand should work fine. |
| 01:09 | dnolen | ohpauleez: I admit it's pretty daunting - and I'm too lazy to convert copious Prolog literature. |
| 01:09 | lynaghk | cemerick: ah, yes that is what I'm using kibit for, basically |
| 01:09 | ohpauleez | It's what we're working with right now, so far, it hasn't been so bad. |
| 01:10 | dnolen | ohpauleez: my simple rule parser from tickt #20 was recursive. |
| 01:10 | ztellman | dnolen: just write write an automatic translator for art of prolog |
| 01:10 | ztellman | you have the tools |
| 01:10 | dnolen | ztellman: I have too many Clojure project as it is :) |
| 01:10 | lynaghk | jmalone: the secret is out now, so I just made that video public. I'll take it down once the official infoq video comes out. |
| 01:10 | ohpauleez | dnolen: it could achieve: (if (= 0 0) :a nil) => (when (= 0 0) :a) => (when (zero? 0) :a) => (when true :a) => :a |
| 01:10 | ohpauleez | ? |
| 01:10 | ohpauleez | man, I need to go back and study that again |
| 01:11 | cemerick | lynaghk: heh, ok, I see what you're really trying to do now. |
| 01:11 | cemerick | whew. |
| 01:12 | lynaghk | cemerick: yeah. It's a pretty serious Yak to shave, but I want to get it done and working so that you can use pretty much all of C2 on either JVM Clojure or ClojureScript. |
| 01:13 | dnolen | ohpauleez: oh, you want multiple passes. just call simplify again. I think simplify would terminate when the form unifies w/ itself (base case). |
| 01:13 | ohpauleez | dnolen: That's what I'm doing now |
| 01:14 | ohpauleez | cool, that's easy enough then |
| 01:14 | cemerick | lynaghk: what is the real scale of the nonportable bits? A much dumber solution (manually coding variants for each host) would have some estimable scale, and you'd know you could always make it work. |
| 01:14 | dnolen | ohpauleez: at certain point I might start getting concerned w/ performance, but seems like so far you guys haven't run into any issues? |
| 01:15 | ohpauleez | dnolen: I really have to thank you. core.logic has bent my brain in a way I haven't experienced for years, and it is truly amazing to have it be a part of Clojure |
| 01:15 | ohpauleez | it's been SO MUCH FUN to work with, and the benefits are clearly illustrated in kibit |
| 01:16 | dnolen | ohpauleez: ha! well thank the miniKanreners and Prologists. but yes, I'm pretty psyched about Kibit as well as the fact that a lot of people already seem to find the tool useful. |
| 01:16 | lynaghk | cemerick: where's the fun in that? = ) The only thing that can't be ported is the ClojureScript dom walking stuff. Everything else is just functions that help with data visualization tasks (scales, map projections &c.). Unfortunately you can't just copy paste them into .cljs files because of trivial differences (e.g. clojure.lang.IFn on Clojure and IFn on ClojureScript). |
| 01:17 | ohpauleez | dnolen: Yeah, no performance concerns so far. The rule sets are small enough and the forms we're analyzing are no longer than your longest form in code |
| 01:17 | ohpauleez | lynaghk: I'll merge your pull req in tomorrow morning after jonas takes a quick look at it, cool? |
| 01:18 | lynaghk | ohpauleez: sure, sounds good to me. |
| 01:18 | dnolen | ohpauleez: I think a lot of perf stuff in the future could be addressed via rule indexing. |
| 01:18 | cemerick | lynaghk: right, you mentioned that. Why not a conditional (import 'clojure.lang.IFn), etc? |
| 01:18 | lynaghk | cemerick: in ClojureScript just (def clojure.lang.IFn IFn)? |
| 01:18 | cemerick | But yeah, a lot less cred in that. |
| 01:18 | cemerick | heh, or that |
| 01:18 | ohpauleez | dnolen: Awesome, definitely good to know |
| 01:19 | cemerick | I think conditional compilation is pretty cred-ful though, and will come in handy later anyway. |
| 01:19 | lynaghk | yeah, and it's not all just symbol replacements. Some of the protocol method names are different (e.g. getAt and get-in, or something like that) |
| 01:20 | cemerick | lynaghk: conditional compilation + a definline, and the result would look damn pretty. |
| 01:20 | cemerick | s/a/many |
| 01:20 | lynaghk | cemerick: yeah, that's true. I feel like it would make the code uglier, and also it would be every-man-for-himself. If I can make a precompilation step that works for 80% of CLJS, then other people could use it too |
| 01:21 | cemerick | well, don't let me stop you ;-) |
| 01:21 | lynaghk | heh |
| 01:21 | lynaghk | So this conditional compilation stuff is in the fancy reader in 1.4? I'd just plug some magic into my project.clj or some such? |
| 01:21 | cemerick | no, the extensible reader should enable it |
| 01:22 | sritchie | cemerick, got it all working, thanks again |
| 01:22 | cemerick | i.e. you bind #clj to return nil on cljs, and #cljs to return nil on clj |
| 01:22 | cemerick | sritchie: nice |
| 01:22 | sritchie | cemerick: one qq, though -- for some reason, when I query a view with a reduce function, I'm getting different results than futon shows for the same view |
| 01:22 | cemerick | like, different order, or actually different data? |
| 01:23 | sritchie | my reduce is concatenating all values as string, and futon shows it properly -- the get-view function is returning a "nil" key with ALL vals concatenated |
| 01:23 | sritchie | passing {:reduce false} shows me the proper results of the map step |
| 01:23 | cemerick | futon defaults to reduce=false |
| 01:24 | sritchie | yeah, but when I click the reduce checkbox I get the proper pairings of key, reduced vals |
| 01:24 | sritchie | oh, I think I see |
| 01:24 | sritchie | there's a "groupings" dropdown |
| 01:24 | sritchie | futon has "exact" |
| 01:24 | sritchie | but if I switch it "none", I get the behaviour I'm seeing in clutch |
| 01:25 | cemerick | yup, it's just different defaults |
| 01:25 | sritchie | so I can pass a :grouping option in the map? |
| 01:26 | cemerick | tons of query options for views; check the table halfway down: http://wiki.apache.org/couchdb/HTTP_view_API |
| 01:26 | sritchie | cemerick: sorry to bug you about this stuff, not sure how to track down these options |
| 01:26 | sritchie | oh, great |
| 01:26 | sritchie | so I can pass these in w/ the map as keywords |
| 01:26 | cemerick | no worries. That wiki has tons of gems |
| 01:26 | cemerick | yup |
| 01:26 | sritchie | nice |
| 01:26 | sritchie | thanks dude |
| 01:26 | cemerick | just watch your underscores |
| 01:27 | cemerick | I burned a day because I was mistakenly using :group-level instead of :group_level |
| 01:27 | sritchie | cemerick: oh boy |
| 01:27 | cemerick | I guess I should make clutch normalize that :-P |
| 01:27 | sritchie | cemerick: I'm sure you've heard this before, but I'm going to write this business up |
| 01:27 | sritchie | couch is too good to let folks pass it by |
| 01:27 | cemerick | whack away |
| 01:27 | cemerick | I agree |
| 01:27 | cemerick | esp. cloudant |
| 01:28 | sritchie | haha, control that! |
| 01:28 | sritchie | cemerick: this is probably a generic cljs question, but is there a problem w/ returning clojure vectors from these map and reduce funcs? |
| 01:28 | sritchie | say I want to make a compound key |
| 01:29 | cemerick | you mean using a cljs view? |
| 01:29 | cemerick | I honestly don't know. |
| 01:29 | sritchie | yup |
| 01:29 | sritchie | seems to be failing -- |
| 01:29 | cemerick | Yeah, you may need to explicitly return a js array. |
| 01:29 | sritchie | I suppose I just need to make a javascript array |
| 01:29 | sritchie | yeah |
| 01:30 | sritchie | what's the syntax for that? |
| 01:30 | cemerick | no clue |
| 01:30 | sritchie | I guess there's some conversion *embarrassed* |
| 01:30 | sritchie | anyone know how to make a js array? |
| 01:30 | cemerick | FWIW, I've not used cljs views in anything real yet. |
| 01:30 | cemerick | How's that for embarrassed? ;-) |
| 01:30 | sritchie | haha, kudos for getting all this working, then |
| 01:30 | cemerick | maybe (js/Array 1 2 3) |
| 01:31 | sritchie | I'll try it out |
| 01:31 | sritchie | and push to cloudant immediately |
| 01:31 | lynaghk | sritchie: you just want (array 1 2 3) |
| 01:31 | sritchie | no js prefix? |
| 01:31 | sritchie | cool |
| 01:32 | lynaghk | I've found it helpful to just paw through the cljs compiler source. |
| 01:32 | sritchie | I've been meaning to do that anyway, I'm sure that would save a lot of pain here |
| 01:32 | lynaghk | there are a lot of macros in clojurescript/src/clj/cljs/core.clj that are illuminating |
| 01:32 | cemerick | lynaghk: see, and you're asking *me* about cljs‽ |
| 01:32 | lynaghk | cemerick: I asked you about macro magic = ) |
| 01:32 | cemerick | heh, fine |
| 01:33 | dnolen | lynaghk: +1. also if people have suggestions / improvement ... :) |
| 01:33 | scriptor | I found it really refreshing how emitting code in the cljs compiler is just printing stuff out to whatever the writer is bound to |
| 01:33 | scriptor | very simple and straightforward |
| 01:33 | ohpauleez | dnolen: Is there a logical equiv to _ |
| 01:33 | ohpauleez | (I'm writing some dead code elimination, and I need a way to express "nothing" in a rule |
| 01:34 | dnolen | ohpauleez: just create an lvar with that name (fresh [_] ...) |
| 01:34 | ohpauleez | Ahhh cool |
| 01:34 | ohpauleez | thank you |
| 01:34 | dnolen | ohpauleez: hmm ... oh in a rule you have ?foo |
| 01:35 | ohpauleez | [(when-not true ?x) _] |
| 01:35 | dnolen | ohpauleez: and ?foo in the same expression will be the same var. |
| 01:35 | dnolen | [(when-not true ?x) ?_] should work I think |
| 01:35 | lynaghk | cemerick: as it turns out, you can't return nil from an extensible reader fn: "No dispatch macro for: e" |
| 01:36 | cemerick | lynaghk: so return something innocuous, like [] |
| 01:36 | cemerick | or (do) |
| 01:37 | lynaghk | ohh, (do) sounds nice. |
| 01:38 | cemerick | eh, that'll get a little dicey for returns. |
| 01:38 | cemerick | you'll end up having to do (or #cljs […] #clj […]) |
| 01:39 | cemerick | side-effecting bits will be fine |
| 01:39 | lynaghk | yeah, but I don't think I really want it to become idiomatic for people to mix clj/cljs within forms. |
| 01:41 | cemerick | that sounds very sane |
| 01:42 | ohpauleez | Thanks for everyone's help! Kibit now has dead code elmination! |
| 01:43 | dnolen | ohpauleez: :D |
| 01:43 | sritchie | if I call concat on two cljs arrays, will they stay arrays? |
| 01:44 | dnolen | sritchie: (.concat a1 a2) yes |
| 01:44 | sritchie | I suppose I could do (apply array (apply concat [arr1 arr2 arr3])) |
| 01:44 | sritchie | dnolen: this is for a couchdb view -- one of the arguments is a sequence of values, each of which are js arrays |
| 01:45 | sritchie | dnolen: I just want to concat them all together and return a new single array |
| 01:45 | sritchie | I should probably go open up a cljs repl and educate myself |
| 01:45 | dnolen | sritchie: in general you can't call cljs fns on js arrays. |
| 01:45 | dnolen | sritchie: well you can but expect seq conversion. |
| 01:46 | sritchie | dnolen: I'll reduce across the sequence, I guess -- (reduce (fn [a b] (.concat a b)) vals) |
| 01:51 | lynaghk | dnolen, fun discovery: ClojureScript IFn doesn't care what you call the method (-invoke, invoke, foobar, whatever). And it'll happily take more than one, with the last form winning |
| 01:52 | lynaghk | (when using reify or deftype) |
| 03:12 | greeneggsandspam | Any VimClojure users? Is the any way for repl (\sr) to share the nailgun session? I'm trying to get the stuff evaluated via \ef (etc) to show up in the repl |
| 04:03 | gtuckerkellogg | This seems very strange |
| 04:03 | clojurebot | No entiendo |
| 04:04 | gtuckerkellogg | ,(defrecord Rule [foo bar]) |
| 04:04 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 04:12 | gtuckerkellogg | why does the map-> constructor for a defrecord abort with type hints? |
| 04:12 | gtuckerkellogg | http://pastebin.com/FVid7Vb5 |
| 04:14 | gtuckerkellogg | never mind, it's because I used ^int instead of ^Integer |
| 04:14 | gtuckerkellogg | arggh |
| 04:24 | muhoo | so how does this cloudant thing work in the free tier? it says "development" but what do they actually mean by that? |
| 04:25 | Raynes | It means "we'd rather you give us some money" |
| 04:28 | muhoo | "rather", i can live with. "oops, you're screwed, you MUST", i cannot. |
| 04:29 | muhoo | 250gb of data is something i will probably never come even close to exhausting, so if that's what they mean by "development", then my "production" will fit that just fine. |
| 04:31 | Raynes | muhoo: All of those cloud database services mark their free tier as 'development'. |
| 04:31 | muhoo | fair enough, thanks. |
| 04:32 | muhoo | 500k requests/month, ah. still probably fine. |
| 04:33 | Raynes | What if you get slashdotted, hacker newsed, and reddited on the same day? |
| 04:36 | muhoo | what if i get hit by lightening, win the lottery, and get hit by a bus in the same day? :-) |
| 04:36 | cemerick | muhoo: I have all but one of my sites on a single cloudant free tier FWIW |
| 04:37 | muhoo | thanks |
| 04:37 | cemerick | (regularly replicated back to a local couchdb, but only because I'm paranoid) |
| 04:37 | clgv | muhoo: chances are that your home gets hit by a hurricane as well ;) |
| 04:38 | scottj | muhoo: you said 250gb. did you mean 250mb? that's what I see for free cloudant on heroku. |
| 04:39 | muhoo | ah, yes, it is MB. hmm. still, i probably won't get too close to that |
| 04:40 | muhoo | at some point, if i get beyond that, i could always buy a linnode or something and just run couch on that, along with clojure, and whatever else i might want. |
| 05:46 | fliebel | Does java have any syntax like Clojure, for (import [package class class class])? |
| 05:46 | ejackson | package.* for the lazy folks |
| 05:48 | fliebel | ejackson: That's... disgusting |
| 05:49 | ejackson | glob it up baby |
| 06:43 | _andrew_k | in Java there only: |
| 06:44 | _andrew_k | import package.Class; // import class |
| 06:44 | _andrew_k | import package.*; // import classes from package |
| 06:44 | _andrew_k | import static package.Class.*; // import static methods from class |
| 06:44 | _andrew_k | import static package.Class.method; // import one static method from class |
| 06:55 | Zoka | If a jar is specified in :dev-dependencies in project.clj, should it it be avaliable in class path for "lein run" ? |
| 07:01 | ejackson | Zoka: should be |
| 07:02 | Zoka | I was using lein2 - I wil retry with 1.7 |
| 07:03 | ejackson | dunno about lein2 yet |
| 07:04 | Zoka | Yes, that was it 1.7 is fine |
| 07:04 | Somelauw | When trying to load a certain project using clojure-jack-in, emacs says it aborts abnormally. Other projects just work, so I don't get why? |
| 07:05 | Somelauw | I can post the project tree if that helps? |
| 07:05 | raek | Somelauw: what happens if you try to run lein repl in those projects? |
| 07:05 | raek | also, what clojure versions do they use? where do you have lein-swank, in the project.clj file or as a plugin? |
| 07:05 | Somelauw | But it would probably help more if I could get some error message |
| 07:06 | Somelauw | raek: Exception in thread "main" java.io.FileNotFoundException: Could not locate clojure/reflect__init.class or clojure/reflect.clj on classpath: (user.clj:1) |
| 07:06 | raek | Somelauw: was that error from clojure-jack-in or lein repl? |
| 07:07 | Somelauw | raek: in project.clj I have :dependencies [[clojure "1.2.1"]]) |
| 07:07 | Somelauw | raek: lein repl |
| 07:07 | raek | Somelauw: do you have stuff in a user.clj file? |
| 07:08 | raek | looks like you use features introduced in clojure 1.3 there |
| 07:09 | Somelauw | raek: yes, it includes reflect. |
| 07:09 | Somelauw | I will try without |
| 07:09 | bsteuber | Zoka: in lein2, the syntax for dev-dependencies is different |
| 07:10 | Somelauw | raek: thanks, it is working again |
| 07:10 | bsteuber | you write :profiles {:dev {:dependencies [..]}] now, that it'll also be in the classpath |
| 07:10 | bsteuber | *then |
| 07:12 | raek | Somelauw: I think clojure-jack-in errors are visible in the *Messages* or *swank* buffers |
| 07:13 | Somelauw | raek: thanks, I found the error in the old one |
| 07:13 | Somelauw | which was the same as lein repl |
| 07:17 | Zoka | bsteuber: do tou have a reference? |
| 07:21 | bsteuber | Zoka: this might help a bit: https://github.com/technomancy/leiningen/blob/master/sample.project.clj |
| 07:22 | bsteuber | also https://github.com/technomancy/leiningen/wiki/Upgrading, but there's not so much information yet |
| 07:24 | Zoka | Thanks, I was just about to go through source. I would not want to go back to 1.7 if I can help it |
| 07:25 | clgv | doesn't lein2 include warnings for deprecate options? if not, there should be a ticket for that ^^ |
| 07:42 | Zoka | bsteuber: I got it, here it is for Google to find, thanks again for pointer: |
| 07:42 | Zoka | ; :dev-dependencies equivalent for Lein 2.0 |
| 07:42 | Zoka | (defproject ringmon "0.1.2-SNAPSHOT" |
| 07:42 | Zoka | :description "Ring handler to inject web page with nREPL front end" |
| 07:42 | Zoka | :dependencies [[org.clojure/clojure "1.3.0"] |
| 07:42 | Zoka | [ring/ring-core "1.0.1"] |
| 07:42 | Zoka | [org.clojure/java.jmx "0.1"] |
| 07:42 | Zoka | [clj-json "0.5.0"] |
| 07:42 | Zoka | [org.clojure/tools.nrepl "0.2.0-beta2"]] |
| 07:43 | Zoka | :dev-dependencies |
| 07:43 | Zoka | [[ring/ring-jetty-adapter "1.0.1"]] ; keep this for Lein 1.7 |
| 07:43 | Zoka | |
| 07:43 | Zoka | ; lein 2.0 dev-dependencies equivalent |
| 07:43 | Zoka | :profiles {:dev {:dependencies [[ring/ring-jetty-adapter "1.0.1"]]}} |
| 07:43 | clgv | Zoka: use a oaste service |
| 07:43 | Zoka | :main ringmon.server) |
| 07:43 | Zoka | bsteuber: I got it, here it is for Google to find, thanks again for pointer: |
| 07:43 | Zoka | ; :dev-dependencies equivalent for Lein 2.0 |
| 07:43 | clgv | *paste |
| 07:43 | Zoka | (defproject ringmon "0.1.2-SNAPSHOT" |
| 07:43 | Zoka | :description "Ring handler to inject web page with nREPL front end" |
| 07:43 | Zoka | :dependencies [[org.clojure/clojure "1.3.0"] |
| 07:43 | Zoka | [ring/ring-core "1.0.1"] |
| 07:43 | Zoka | [org.clojure/java.jmx "0.1"] |
| 07:43 | Zoka | [clj-json "0.5.0"] |
| 07:43 | Zoka | [org.clojure/tools.nrepl "0.2.0-beta2"]] |
| 07:43 | Zoka | :dev-dependencies |
| 07:43 | Zoka | [[ring/ring-jetty-adapter "1.0.1"]] ; keep this for Lein 1.7 |
| 07:43 | Zoka | |
| 07:43 | clgv | :( |
| 07:43 | Zoka | ; lein 2.0 dev-dependencies equivalent |
| 07:43 | Zoka | :profiles {:dev {:dependencies [[ring/ring-jetty-adapter "1.0.1"]]}} |
| 07:43 | Zoka | :main ringmon.server) |
| 07:44 | Zoka | Sorry, I thought this was short enough |
| 07:45 | clgv | short enough are only oneliners ;) |
| 07:46 | Zoka | Anyway, I am very happy with lein2 - much faster |
| 07:48 | bsteuber | yes lein2 is getting great |
| 10:58 | y3di | whats up homies |
| 11:32 | unlink | What is Clojure's RAII equivalent? |
| 11:39 | unlink | For resources such as open files or temporary files which need to be deleted. |
| 11:39 | ferd | unlink: you have with-open for example, and it's easy to write your own with macros |
| 11:41 | clgv | unlink: with-open like ferd said. but be careful with lazy sequences within an with-open macro |
| 11:43 | unlink | I'd rather not write a boilerplate-y macro like with-open for each type of finalization that I need to do |
| 11:44 | unlink | and it would be nice if I didn't have to lexically scope the resources I allocate (a la GC) |
| 11:46 | clgv | unlink: huh? |
| 11:47 | unlink | for example, I want to do something like this: TempFile x = new TempFile(); if (someCondition) { x = TempFile.basedOne(x); } doSomethingWith(x); /* in finalizer .. delete all temp files created so far */ |
| 11:47 | unlink | *basedOn(x) |
| 11:48 | unlink | (with-tempfile [x (make-tempfile)] (with-tempfile [x (if condition (tempfile-based-on x) x)] (do-something-with x))) ;; this will attempt to delete x twice if condition is false |
| 11:48 | tomoj | couldn't you implement that with weak references? I feel like the answer must be "no" |
| 11:49 | tomoj | oh, I was thinking of doing it without with-tempfile |
| 11:49 | clgv | unlike: first you dont need with-tempfile. just use with-open. and only use it for those bindings that need to be ".close"d finally |
| 11:50 | unlink | clgv: Who is going to delete those tempfiles then? |
| 11:50 | clgv | you implemented TempFile yourself? |
| 11:51 | unlink | clgv: well, in my putative pseudo-Java, there would be a TempFile class which deletes its underlying file in the finalizer. |
| 11:53 | clgv | unlink: well ok then write with-tempfile - you will be deleted twice will only happen if 'tempfile-based-on returns the same file, but then you should use the macro only once |
| 11:53 | clgv | *your "will be deleted twice" |
| 11:54 | cemerick | unlink: FWIW, finalizers have always been unreliable, and are getting moreso |
| 11:54 | unlink | clgv: The issue is that I want to conditionally shadow the temporary file based on a condition, but the with-tempfile macro doesn't know that (it would have to delete idempotently). |
| 11:55 | clgv | unlink: then implement the deletion method that your macro will call with a check ;) |
| 11:56 | unlink | clgv: yes, in fact, that is what my implementation has. I was just hoping that I could finalize resources without a dozen lines of boilerplate. |
| 11:57 | unlink | clgv: It's also not clear to me how I would extend this notion to, say, a (variably-sized) list of files I want to delete. |
| 11:58 | unlink | e.g. how would I implement (with-tempfiles [xs (map make-tempfile ys)] ...) in terms of make-tempfile? |
| 11:58 | clgv | simply (finally (doseq [x xs] (.delete x))) |
| 11:59 | clgv | unlink: but you have to decide if it is always a collection or whether you need a check for that |
| 11:59 | unlink | what is "finally"? |
| 11:59 | clgv | (try ... (finally ...)) |
| 12:00 | unlink | clgv: true, but now I must duplicate the logic that recursively calls with-tempfiles, checks for symbols, the base case, etc. |
| 12:01 | clgv | I don't understand that comment |
| 12:05 | clgv | cemerick: ++ for your type flowchart |
| 12:06 | cemerick | thanks, glad it's useful |
| 12:06 | clgv | wasnt sure whether I wanted reify or proxy ;) |
| 12:09 | unlink | clgv: hmm, apparently you can't doseq inside of (finally ...) |
| 12:10 | clgv | unlink: why should that be? you can execute any code in there |
| 12:11 | unlink | ,(try nil (finally (doseq [x (range 10)] (println x)))) |
| 12:11 | clojurebot | unlink: It's greek to me. |
| 12:11 | unlink | CompilerException java.lang.UnsupportedOperationException: Cannot recur from catch/finally, compiling:(NO_SOURCE_PATH:1) |
| 12:12 | Bronsa | wow. |
| 12:12 | Bronsa | why is it so? |
| 12:13 | unlink | bug in the compiler. |
| 12:13 | cemerick | been that way for a while |
| 12:14 | clgv | unlink: the put it in a function and call that function |
| 12:14 | cemerick | a result of a prior fix to prevent recur from branching out of a recur; the easy fix was to just disallow recur within finally |
| 12:14 | unlink | http://paste.lisp.org/display/128516 |
| 12:15 | unlink | anyhow, I'd like to cut down on the boilerplate there without being excessively clever. |
| 12:17 | tomoj | does that paste suffer from the recur/finally problem, or does introducing a function solve it? |
| 12:18 | unlink | the function in that paste does work around the recur/finally problem. |
| 12:18 | tomoj | oh, good |
| 12:18 | tomoj | I was thinking the problem was much worse.. :) |
| 12:21 | unlink | It might be the case that *more* metaprogramming is the solution to my program, but at some point I'd like to just delete some files. |
| 12:23 | unlink | (fortunately java.io.File#delete happily proceeds when asked to delete a nonexistant file) |
| 12:29 | dnolen | core.logic port to CLJS is coming along ... |
| 12:31 | jonasen | dnolen: Thanks again for your latest comment on kibit#20 and sorry I haven't had time to respond yet |
| 12:31 | ibdknox | dnolen: that'll be neat :) |
| 12:32 | TimMc | ,(try nil (finally (#(doseq [x (range 10)] (println x))))) |
| 12:32 | clojurebot | TimMc: No entiendo |
| 12:32 | TimMc | Ah well. |
| 12:33 | ibdknox | TimMc: ? |
| 12:33 | TimMc | Tried it in my own REPL -- same compile error. |
| 12:33 | mk | "UnsupportedOperationException: Cannot recur from catch/finally" |
| 12:34 | TimMc | ibdknox: I was seeing if a fn literal would allow me to evade the check. |
| 12:34 | ibdknox | ah |
| 12:50 | jayunit100 | any tricks to print clj files to pdf .... |
| 12:50 | jayunit100 | i.e. syntax highlighted |
| 12:52 | gtrak | jayunit100, I did some quick googling: http://stackoverflow.com/questions/946858/convert-syntax-highlighted-code-to-html-in-emacs |
| 12:53 | gtrak | apparently there's also a way to print the buffer, assuming you use emacs, of course |
| 12:53 | clgv | how to get hold of the clojure classloader? |
| 12:53 | zamaterian | jayunit100, in vim http://www.plainlystated.com/2009/08/vim-tohtml-customization/ |
| 12:53 | gtrak | but once you have html, you can copy-paste into libreoffice or something |
| 12:59 | jayunit100 | zamaterian: ok thanx |
| 13:05 | jayunit100 | daymn that looks complicated |
| 13:07 | gtrak | jayunit100, you can also use pygments perhaps? |
| 13:10 | gf3 | ibdknox: you know what'd be hawt? Source maps for noir-cljs :D |
| 13:10 | ibdknox | source maps would be at the cljs compiler level |
| 13:10 | ibdknox | there was brief discussion about them yesterday :) |
| 13:11 | gf3 | ibdknox: ahh |
| 13:11 | gtrak | what could also be hawt, source maps for java sources pulled in by maven |
| 13:12 | muhoo | what is a source map? |
| 13:12 | mk | gf3: link to yesterday's logs: http://clojure-log.n01se.net/date/2012-03-22.html |
| 13:13 | mk | muhoo: http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/ |
| 13:13 | gf3 | mk: awesome, thank you |
| 13:14 | muhoo | ah, like in GCC |
| 13:15 | muhoo | .lss file :-) |
| 13:26 | muhoo | source map https://refheap.com/paste/1318 :-) hmm, looks like refheap doesn't do asm. |
| 13:31 | Togo | i guys. I'm new at clojure and trying to check whether a string contains only integer. Can anybody help me out. I have something like this: (defn only-integer? [string] (empty? (map integer? (.parseInt string)))) |
| 13:32 | stuartsierra | Togo: how about a regex? |
| 13:34 | Togo | i've tried it, but failed with regex ;-( can give me any suggestions? |
| 13:34 | ejackson | stuartsierra: now he has two problems ! (YESSSSSSSSS !) |
| 13:34 | stuartsierra | :) |
| 13:34 | RickInGA | ejackson ftw |
| 13:35 | stuartsierra | Togo: (re-matches #"\d+" the-string) |
| 13:35 | Togo | thanks a lot stuartsierra |
| 13:36 | stuartsierra | Flavor to taste for leading +/- signs, commas, etc. |
| 13:37 | mk | Togo: what counts as an integer? If you're going by what is accepted by parseInt, you should just use parseInt and return false when it throws its exception |
| 13:37 | mk | i.e. "an integer is whatever parseInt successfully reads" |
| 13:42 | Togo | i also tried it with try and catch but my attempt failed. My plan was to give the parseInt function a trimmed String. If i can parse it give me true if i get an exception false. But i never got an return value. |
| 13:42 | TimMc | &(Integer/parseInt "012") |
| 13:42 | lazybot | ⇒ 12 |
| 13:42 | TimMc | &(Integer. "012") |
| 13:42 | lazybot | ⇒ 12 |
| 13:43 | Togo | my code with try and catch: (defn only-integer? [string] (try (.parseInt string) true (catch Exception e) false) ) |
| 13:43 | mk | &(Integer. "twelve") |
| 13:43 | lazybot | java.lang.NumberFormatException: For input string: "twelve" |
| 13:44 | TimMc | Huh, I guess Integer doesn't do the octal switch. |
| 13:45 | stuartsierra | Togo: your parens are misplaced |
| 13:45 | Vinzent | Togo, (Integer/parseInt string), not (.parseInt string). parseInt is a static method of the Integer class |
| 13:45 | stuartsierra | (try (Integer/parseInt the-string) true (catch Exception e false)) |
| 13:47 | mk | note that what java considers an integer is an infinitely tiny subset of what the clojure reader considers an integer |
| 13:48 | Vinzent | mk, hm, clojure integers are java integers, aren't they? |
| 13:48 | Vinzent | or longs |
| 13:49 | mk | clojure is fine with 48573428563426534875248792348 |
| 13:49 | Vinzent | yeah, but technically it's a BigInteger, not integer |
| 13:49 | Togo | ok thanks guys this works for me! the further discussion is yours :-) |
| 13:51 | mk | sure - BigInteger, not int or Integer. I just mean that clojure has a different notion of how big integers can get :) |
| 13:51 | mk | (by default) |
| 13:52 | TimMc | and then there's BigInt... |
| 13:53 | TimMc | &(class 4N) |
| 13:53 | lazybot | ⇒ clojure.lang.BigInt |
| 13:53 | eggsby | are there any pubsub libs for clojure? |
| 13:53 | mk | interesting, I didn't know it used its own. Why does it do that? |
| 13:54 | Vinzent | mk, agree, you're right :) |
| 13:54 | dnolen | jonasen: no problem, hopefully it makes sense - basic idea would be to do a parse pass to normalize rules, you could even do this as a macroexpansion pass if you don't plan on manipulating the rules in the original form. |
| 13:54 | Vinzent | hm, I also thought bigint creates java's BitInteger |
| 13:55 | llasram | "clojure.lang.BigInt ... is similar to Java's java.math.BigInteger in allowing integer sizes exceeding 64 bits, but provides better performance by delegating to native operations when small enough." http://dev.clojure.org/display/doc/Documentation+for+1.3+Numerics |
| 13:57 | mk | one thing that occured to me is that instead of using e.g. floats in clojure, it might be possible to define *float, which does a float multiply |
| 13:57 | hyphaestus | ahh it's a wonderful day |
| 13:57 | mk | it converts its two arguments to floats, and then multiplies them in the typical lossy way |
| 13:59 | mk | I'm not sure how things work now, but if + yields different results for (+ .1 .2) when those are floats, that's a bad thing |
| 14:00 | mk | ,(+ 0.1 0.2) |
| 14:00 | clojurebot | 0.30000000000000004 |
| 14:01 | rhc | any number with a . is a float in clojure, right? |
| 14:01 | rhc | ,(+ 1/10 2/10) |
| 14:01 | clojurebot | 3/10 |
| 14:01 | technomancy | rhc: no, there are bigdecimals too |
| 14:01 | rhc | ah |
| 14:01 | mk | what's the notation for bigdecimal? |
| 14:01 | rhc | i thin x.yM |
| 14:02 | rhc | ,(+ 0.1M 0.2M) |
| 14:02 | clojurebot | 0.3M |
| 14:05 | mk | that seems wrong to me. It might not be possible, but a float value should be lazily converted into a decimal when it hits a proper math operator - until then, it can be used in e.g. (*f 0.1 0.2) without a conversion occurring |
| 14:05 | edw | Is the a CLJS channel? |
| 14:06 | dnolen | edw: it's the Clojure channel, CLJS is a Clojure implementation, so yes :) |
| 14:06 | mk | this connects the screwedupness of float math to the function, not to the datatype |
| 14:06 | TimMc | edw: There is now. |
| 14:07 | edw | dnolen: OMG I am not feeling well. Too much fun at Vol du Nuit last night. |
| 14:07 | edw | Apologies for my incoherent English. |
| 14:07 | TimMc | (There's only one other person in #clojurescript, I'd stay here.) |
| 14:08 | mk | what's the proper name of java clojure, then? |
| 14:08 | TimMc | "Clojure" |
| 14:08 | edw | I was looking through the CLJSone demo, and I was wondering where the design/development/deployment toolbar was deactivated in the production version. I find that magic a bit bewildering. |
| 14:08 | stuartsierra | edw: it's a Ring middleware |
| 14:08 | technomancy | mk: afaik we don't have the words we need to distinguish that kind of thing |
| 14:09 | edw | That strips out DOM nodes based on a header or deployment type or somethng? |
| 14:10 | mk | technomancy: maybe it'll come up as clojure lisps are created on more platforms |
| 14:10 | edw | Ah, using Enlive, I suppose. |
| 14:14 | chouser_ | I've used "ClojureJVM" when a distiction is really needed, which is pretty rare. |
| 14:15 | stuartsierra | edw: yse |
| 14:15 | stuartsierra | yes |
| 14:15 | technomancy | "True Clojure" |
| 14:24 | skarayan | what is the accepted best way to do distributed computing in clojure? |
| 14:24 | mk | skarayan: what sort of distributed computing? |
| 14:24 | Chiron | Storm? https://github.com/nathanmarz/storm/wiki |
| 14:26 | antares_ | skarayan: it depends on how you define "distributed computing". if you need a "real-time Hadoop", look at storm. If you just need a solid messaging protocol, AMQP with github.com/michaelklishin/langohr is a good option |
| 14:26 | stuartsierra | Also check out David Liebke's Avout. |
| 14:26 | antares_ | if you want to build something peer-to-peer, zeromq is what you need |
| 14:27 | Chiron | Speeking of Avout, it is "distributed" identity? |
| 14:28 | stuartsierra | Chiron: more or less, yes |
| 14:28 | antares_ | Chiron: it is distributed (no quotes) state |
| 14:28 | stuartsierra | distributed Atoms and the like |
| 14:30 | Chiron | What are the typical uses cases for Avout? currently I'm using Storm |
| 14:33 | edw | stuartsierra: Actually, that snipping can't happen in Ring, as the page is composed on the client side (if I am not mistaken). |
| 14:34 | stuartsierra | edw: the server renders the base layout |
| 14:35 | edw | Huh. Gawd I despise magic. |
| 14:39 | edw | stuartsierra: ...but I love find(1) and 'grep -H ...'. |
| 14:50 | Chiron | Sometimes, I'm really locked in OOP thinking. I create an atom or ref and then start mutating. How to get ride of this? |
| 14:51 | technomancy | maybe kibit could suggest atom -> reduce transformations =) |
| 14:52 | emezeske | edw: Have you tried ack? For the simple cases, it's a nice replacement for find ... | xargs grep ... |
| 14:53 | mk | perhaps simply forbid yourself from using those. If you have a particular example of where you're using them, and aren't sure what else you could do, ask here |
| 14:54 | Chiron | I let a data structure, perform some operations and then to update the letted data structure. that is why I'm using atoms |
| 14:54 | dnolen | ibdknox: did you the ML post about the GSoC game editor proposal? |
| 14:57 | mk | Chiron: hmm - how about a pastebin/gist of the source? |
| 14:59 | mk | how can I eval text? e.g. (eval "(+ 1 2)") -> 3, or -> (+ 1 2) |
| 15:00 | TimMc | mk: read-string, then eval |
| 15:00 | TimMc | I hope that's for a config file. |
| 15:01 | mk | TimMc: reading the reference and was just wondering |
| 15:01 | mk | thanks |
| 15:01 | TimMc | OK. :-) |
| 15:02 | edw | mk: To a first order approximation, eval is equivalent to regular expressions in jzw-land: "Now you have two problems." |
| 15:02 | TimMc | mk: Obligatory caution: Bind *read-eval* to false when you use read-string or read on user-provided data strings. |
| 15:02 | TimMc | edw: jwz |
| 15:03 | edw | D'oh. Again, last night...still recovering. |
| 15:03 | edw | LZW, on the other hand... |
| 15:03 | rhc | TimMc: speaking of that, is it possible to quote a literal string in clojure? |
| 15:03 | rhc | something akin to 'string' in other languages, or do you simply have to escape every \ and \t with \\ and \\t ? |
| 15:03 | mk | when is read-string usually used? The repl? |
| 15:05 | Chiron | @mk https://gist.github.com/2173859 |
| 15:05 | edw | rhc: Are you asking about the existence of here-document like syntax in Perl, shell scripts, and so forth? |
| 15:06 | rhc | edw: sort of, but the multiline thing is unnecessary |
| 15:07 | rhc | its more like if i'm building up a regex, i have to do stuff like (re-pattern (str "\\s\\?\\\\" some-input)) |
| 15:07 | edw | rhc: It usually doesn't take much before I decide to throw something in the resources directory and load it. |
| 15:07 | TimMc | Ah, yeah. |
| 15:07 | rhc | i wouldn't say its big enough to warrant loading it from some config, but i see where you're coming from |
| 15:07 | rhc | its just an annoyance, but nothing major |
| 15:08 | rhc | at least #"\s\?\\" works nicely |
| 15:09 | mk | anyone know how https://gist.github.com/2173859 can be done without using an atom? |
| 15:11 | DerGuteMoritz | mk: just `let' slave again |
| 15:11 | emezeske | mk: Couldn't you just (let [slave (:slave master) new-slave (assoc slave :status success)] ...) |
| 15:11 | mk | Chiron: ^ |
| 15:11 | Chiron | I thought about it, but I'm trying to force myself not to overuse let forms |
| 15:11 | emezeske | Chiron: You should probably use let forms a lot |
| 15:12 | Chiron | really? |
| 15:12 | TimMc | &(seq (str #"\t")) |
| 15:12 | lazybot | ⇒ (\\ \t) |
| 15:12 | Chiron | wouldn't this complicate code? |
| 15:12 | edw | But introducing mutation to reduce let forms is like commiting suicide to avoid the common cold. |
| 15:12 | Chousuke | hehehe |
| 15:12 | DerGuteMoritz | (let [master (get-it-from-somwhere) slave (:slave master) slave (if (< 0.7 (rand)) (assoc slave :status success) slave)] ...) |
| 15:12 | emezeske | Chiron: All let does is give a name to some intermediate result, that's not complicated |
| 15:12 | TimMc | rhc: It's a bit horrible, but (str #"foo") is a hack that gets you a raw-like string. |
| 15:12 | Chousuke | Chiron: you might try to see if you need the inteermediate variables at all |
| 15:13 | Chiron | you know, let inside let .. |
| 15:13 | DerGuteMoritz | Chiron: just rebind the same name again in the same let |
| 15:13 | Chousuke | in that let, for example, the rand is dubious |
| 15:13 | DerGuteMoritz | Chiron: see my example above |
| 15:13 | rhc | TimMc: yeah i noticed that, pretty interesting, but handy for cutting down the \\s in regex syntax |
| 15:13 | rhc | and nice for compile-time regex syntax checks.. |
| 15:13 | DerGuteMoritz | Chousuke: how so? |
| 15:13 | TimMc | rhc: Oooohh... |
| 15:14 | Chousuke | DerGuteMoritz: it feels like it's putting side-effects in middle of code that could be pure |
| 15:14 | Chousuke | that's generally not a good thing to do |
| 15:14 | Chiron | so this (let [master (get-it-from-somwhere) slave (:slave master) slave (if (< 0.7 (rand)) (assoc slave :status success) slave)] ...) is an idiomatic lisp/clojure? |
| 15:14 | TimMc | You'd still want to inject that randomness somehow (to allow testing.) |
| 15:14 | DerGuteMoritz | Chousuke: well if you need the result of a side-effect you have to do it this way when mutation is not an option |
| 15:15 | Chiron | it looks like accumulating all logic in one form |
| 15:15 | DerGuteMoritz | Chiron: I do it pretty regularly, yes |
| 15:15 | DerGuteMoritz | you can still break it up into smaller functions |
| 15:15 | DerGuteMoritz | if it gets out of hand |
| 15:15 | Chousuke | you might put that (if rand ...) thing in another function |
| 15:15 | DerGuteMoritz | that's right |
| 15:15 | DerGuteMoritz | the side-effect is still there though |
| 15:15 | DerGuteMoritz | of course :-) |
| 15:15 | DerGuteMoritz | the right hand side of a let form shouldn't grow too large vertically |
| 15:16 | DerGuteMoritz | especially in clojure |
| 15:16 | DerGuteMoritz | where there is no grouping of names and values |
| 15:16 | DerGuteMoritz | as opposed to most other lisps |
| 15:16 | Chiron | I should hang out here much much more :) |
| 15:16 | Chousuke | then do (let [slave (decide-success-for-slave (:slave (get-master-from-somewhere)))] ...) |
| 15:18 | Chousuke | the side-effect is still there but at least it's in its own unit of code |
| 15:18 | DerGuteMoritz | right |
| 15:18 | Chiron | you mean inside do form? |
| 15:18 | Chousuke | inside the function |
| 15:18 | Chousuke | you can mark the function with ! to make it even more explicit |
| 15:18 | Chiron | for example, my rand logic and save to mongo should be refactored to a seperate function |
| 15:19 | Chousuke | yeah. in general, keep side-effects and pure code as separate as possible |
| 15:19 | Chousuke | then write a couple functions where you tie them together |
| 15:20 | Chousuke | that way, you can develop the pure code separately from the rest of the system. |
| 15:20 | Chiron | Hmm. my FP elf is smiling |
| 15:20 | Chousuke | since it has no implicit dependencies on anything |
| 15:20 | Chousuke | so you can just make up some data for it and test it |
| 15:21 | mk | are metadata maps used much? |
| 15:21 | Chousuke | then when it works acceptably you can worry about getting real data from whatever database you have :P |
| 15:22 | Chousuke | mk: Clojure itself uses them for docstrings and such. I think metadata in general is not very often needed but I'm sure you'll be glad it's there when you do need it |
| 15:23 | mk | Chousuke: gotcha |
| 15:23 | Chousuke | type hints are metadata too |
| 15:24 | mk | right - I saw that, and was wondering if there were common uses besides that |
| 15:24 | Chousuke | I'm not sure. it seems to be one of those features that are completely useless until you need it. |
| 15:24 | Chousuke | and then it becomes something that saves you hours of headache |
| 15:27 | mk | "If the operator of a call is a symbol that names a global var that is a macro function, that macro function is called and is passed the unevaluated operand forms" - the operands to non-global vars aren't left unevaluated? |
| 15:27 | amalloy | protocols use metadata on vars for something. maybe to keep up to date as protocol definitions change? it's not really obvious to me |
| 15:28 | Chousuke | mk: there are no local macros |
| 15:28 | amalloy | there are no non-global macros |
| 15:28 | unlink | to those intererested, here is a macro which abstracts the commonalities between with-tempfile and with-tempfiles (also with-open): https://gist.github.com/2174086 |
| 15:28 | mk | ah, I see. |
| 15:28 | unlink | concerning the earlier conversation. /cc cemerick Bronsa |
| 15:30 | Chousuke | unlink: why is the finalizer a function? for simplicity of implementation? :P |
| 15:30 | TimMc | *macrolet |
| 15:30 | amalloy | macrolet is great. i wish it were part of the language instead of an enormous macro |
| 15:30 | Bronsa | which conversation. |
| 15:31 | Chiron | what does this mean for Clojure? http://www.shenlanguage.org/ |
| 15:31 | unlink | Chousuke: a better interface wasn't immediately apparent. |
| 15:31 | Bronsa | i tend to forget things |
| 15:31 | unlink | Bronsa: about try/finally. |
| 15:31 | Bronsa | oh. |
| 15:31 | TimMc | amalloy: It just makes some gensym-named defmacros and uses them? |
| 15:31 | Chousuke | unlink: well, you could write a macro that is called like (defwith with-delete [x] (.delete x)) |
| 15:32 | tmciver | Where can I find macrolet? |
| 15:32 | amalloy | clojure.tools.macro |
| 15:32 | Chousuke | macrolet shouldn't be that difficult to implement in the clojure compiler itself actually |
| 15:32 | Chousuke | I wonder why it's not yet done :/ |
| 15:33 | unlink | Chousuke: yeah, but it seemed strange that the binding would always have just one parameter...it seemed more natural to do something like #(.delete %) |
| 15:33 | Chousuke | no-one wants to code in java? |
| 15:33 | samaaron | does anyone have any good solutions for letting people plug in logging solutions to their libraries? |
| 15:33 | Chousuke | isn't there a clojure logging library or two already |
| 15:33 | amalloy | TimMc: no, it does a lot more work |
| 15:33 | samaaron | i.e. I have a lib, and my own logging solution, but I want people to be able to use my library with their specific logging solution |
| 15:33 | cemerick | Chousuke: it's been done at least a couple times already |
| 15:34 | samaaron | the only thing I can think of is to use dynamic bindings |
| 15:34 | samaaron | and let people dynamically bind their logging fn |
| 15:36 | amalloy | samaaron: clojure.tools.logging tries to do this but my understanding/experience is that it's a tremendous hassle to do any kind of logging in clojure these days |
| 15:37 | samaaron | amalloy: ok - that's a shame |
| 15:53 | hugod | samaaron: clojure.tools.logging works - using logback as the logging implementation gives zero config logging to stdout |
| 16:05 | sandover_ | writing a tiny server -- what logging should i use? currently a lot of println |
| 16:11 | nicl | Hey, guys. New to clojure. Trying to use the find-doc function in the repl. But using (clojure.repl/find-doc "example") gets a class not found error |
| 16:14 | nicl | any thoughts. Guessing it is something stupid |
| 16:15 | Bronsa | you probably are using clojure 1.2 |
| 16:15 | dnolen | nicl: you can just use clojure.repl like that, you need to require it first, (require 'clojure.repl) |
| 16:15 | Raynes | s/can/can't/ |
| 16:15 | dnolen | nicl: I suggest that you just use lein2, it comes with a very, very nice repl. |
| 16:16 | dnolen | Raynes: ooops, yeah thx. |
| 16:16 | Raynes | That unfortunately leaves abandoned java processes when closed at the moment. Should be fixed soon. |
| 16:16 | nicl | dnolen: I'm trying to use lein with Emacs. |
| 16:16 | Raynes | But it is indeed pretty nice. |
| 16:17 | dnolen | nicl: if you're on lein < 2 you will need to require clojure.repl first |
| 16:18 | nicl | dnolen: ah, ok. So even namespacing it is needs to be required. Guess that makes sense (although maybe not for a repl program!) |
| 16:19 | nicl | dnolen: yep, apparently I'm on 1.7.0 for leiningen |
| 16:27 | dnolen | some more testing to do, but core.logic is basically ported to CLJS |
| 17:24 | replaca_ | technomancy: if I wanted to read a project.clj, am I safe just skipping project and version and then doing (into {} (partition 2 the-rest))? |
| 17:25 | technomancy | replaca_: depends on what you're going for; you'll miss out on all the normalization |
| 17:26 | replaca_ | I mostly just want to get the version and dependencies |
| 17:26 | technomancy | should be fine for that, yeah |
| 17:26 | replaca_ | cool, thx |
| 17:28 | antares_ | sandover_: github.com/clojure/tools.logging |
| 17:47 | brianm | I'm using the maven shade plugin to build an uberjar which includes some embedded clojure, a la |
| 17:47 | brianm | IFn f = (IFn) clojure.lang.Compiler.load(new StringReader("#(+ 1 %)")); |
| 17:47 | brianm | when run from the ubjerjar, this explodes with an NPE in |
| 17:47 | brianm | Caused by: java.lang.NullPointerException |
| 17:47 | brianm | at clojure.lang.RT.load(RT.java:424) |
| 17:47 | brianm | at clojure.lang.RT.load(RT.java:398) |
| 17:47 | brianm | at clojure.lang.RT.doInit(RT.java:434) |
| 17:47 | brianm | google doesn't seem to know about it :-( |
| 17:47 | brianm | anyone know how to work around? |
| 17:48 | brianm | (clojure 1.3.0) |
| 17:49 | brianm | seems to be under |
| 17:49 | brianm | load("clojure/core"); |
| 17:59 | _andrew_k | brianm: is it full stack trace ? |
| 18:04 | brianm | _andrew_k: one sec |
| 18:04 | brianm | _andrew_k: https://gist.github.com/ace0db1c630356dda0be |
| 18:04 | brianm | line 3 is what it is trying to compile |
| 18:05 | brianm | switched out to MVEL -- for minimal expression stuff mvl is actually nicer, I justw anted excuse to embed clojure :-) |
| 18:06 | hugod | replaca_: you could also use leiningen.core, now that it is a lib in lein2 |
| 18:13 | _andrew_k | so i can explain this error |
| 18:13 | _andrew_k | look at stack trace - top block of code |
| 18:13 | brianm | looking |
| 18:13 | _andrew_k | at this line at org.skife.pummel.cli.Step.call(Step.java:70) |
| 18:14 | brianm | yep |
| 18:14 | _andrew_k | you are calling some method of Compiler class |
| 18:14 | brianm | yes |
| 18:14 | brianm | IFn f = (IFn) clojure.lang.Compiler.load(new StringReader("#(+ 1 %)")); |
| 18:14 | _andrew_k | at clojure.lang.Compiler.<clinit>(Compiler.java:222) |
| 18:14 | _andrew_k | in this line <clinit> means that this is call in class loading code code |
| 18:14 | brianm | yes |
| 18:14 | _andrew_k | https://github.com/clojure/clojure/blob/clojure-1.3.0/src/jvm/clojure/lang/Compiler.java |
| 18:15 | _andrew_k | line 222 |
| 18:15 | brianm | yes |
| 18:15 | muhoo | technomancy: i'd like to take you up on your offer to explain the innards of lein and lein-repl, but today has pretty much evaporated already |
| 18:15 | brianm | it is trying to load clojure/core |
| 18:15 | brianm | which it should be pulling crom clojure/core.clj on classpath |
| 18:15 | _andrew_k | in this line you are calling something in Namespace class |
| 18:16 | _andrew_k | in constructor of namespace class you are calling method from RT class |
| 18:16 | _andrew_k | not look at bottom block |
| 18:16 | _andrew_k | again <clinit> - it's statis code initialization of RT class |
| 18:17 | _andrew_k | *two line before `not` -> `now`* |
| 18:17 | _andrew_k | code in RT class passes through to method load |
| 18:17 | _andrew_k | https://github.com/clojure/clojure/blob/clojure-1.3.0/src/jvm/clojure/lang/RT.java |
| 18:17 | _andrew_k | NPE throws at line 424 |
| 18:18 | brianm | yes |
| 18:18 | brianm | if(booleanCast(Compiler.COMPILE_FILES.deref())) |
| 18:18 | _andrew_k | NPE can be thrown when you dereferencing null pointer (or compiler does it - unboxing for example) |
| 18:18 | _andrew_k | in this line there only one possible dereferencing |
| 18:19 | brianm | yes |
| 18:19 | _andrew_k | it's getfield COMPILE_FILES of Compiler - Compiler.COMPILE_FILES |
| 18:19 | _andrew_k | and if you can see in Compiler class |
| 18:19 | _andrew_k | this is 233 line |
| 18:19 | brianm | _andrew_k -- right, i can read the stack trace, but there is a lot of static initialization magic going on, and was wondering if anyone had thit this one before |
| 18:19 | brianm | I'd prefer to not debug through clojure to work out if I can ;-) |
| 18:20 | _andrew_k | and now - some lines before... remeber that we in line 222 go out from this class |
| 18:20 | _andrew_k | so out 233 line now not initialized yet |
| 18:20 | _andrew_k | out -> our |
| 18:20 | brianm | static final public Var COMPILE_FILES = Var.intern(Namespace.findOrCreate(Symbol.intern("clojure.core")), |
| 18:20 | brianm | Symbol.intern("*compile-files*"), Boolean.FALSE).setDynamic(); |
| 18:20 | brianm | should not |
| 18:21 | brianm | erg |
| 18:21 | _andrew_k | in 222 line of initializing Compiler class our code go out in Namespace class (top block of stack trace) and 233 line have not been initialized yet |
| 18:21 | brianm | oh my, static init race |
| 18:21 | _andrew_k | it's cycled initialization |
| 18:22 | matt444 | Hello, new Clojurian here. Can anyone explain to me -> when it is a function name? |
| 18:22 | brianm | nasty |
| 18:22 | matt444 | This is what I'm having trouble grepping: https://github.com/ibdknox/pinot/blob/master/src/pinot/util/clj.cljs |
| 18:23 | drewr | matt444: it's actually a macro; called the "threading macro" |
| 18:23 | brianm | hmm, so if I explicitely access RT for somethign first, should correct the order |
| 18:23 | pyninja | matt444: the name of that function is "->coll", it's just a name |
| 18:23 | matt444 | really? |
| 18:23 | matt444 | ah |
| 18:23 | matt444 | ok, I was confused having read about the piping functionality |
| 18:24 | pyninja | matt444: yeah, looks like calling ->coll on anything returns itself if it's a collection already otherwise returns a vector with it as first element |
| 18:24 | _andrew_k | brianm: you can thy to initialize core classes first just by calling some static variables from them by calling Class.forName("Compiler") and others |
| 18:24 | brianm | yeah |
| 18:25 | matt444 | pyninja: gotcha, thanks a lot |
| 18:25 | brianm | _andrew_k: thanks for help! |
| 18:26 | brianm | _andrew_k: explicity just called RT.init() ahead |
| 18:26 | brianm | worked a charm |
| 18:26 | brianm | of course, no need for it... |
| 18:32 | mstump | is there a way to quote a blob of text (json) in a test such that I don't have to go through and escape every " |
| 18:34 | gtrak | mstump, dump it in a file and slurp it |
| 18:34 | gtrak | I made a snippets folder for my web-app just for that reason |
| 18:36 | mstump | yeah, i do that for bigger chunks of json, but for something small I like to have it next to the test |
| 18:56 | mk | is there a way to test if a form will produce side-effects when evaluated? |
| 18:56 | emezeske | mk: Not in clojure; you want Haskell for that ^_^ |
| 18:58 | tmciver | mk: the presence of (do ... is a good indicator. |
| 18:58 | mk | is there any reliable way, for at least some subset of forms? |
| 19:01 | TimMc | mk: "Some subset"? Sure. :-P |
| 19:02 | mk | TimMc: how? :) |
| 19:04 | emezeske | mk: You could parse the sexpr tree looking for specific forms in call positions, but that's going to be soooo inaccurate |
| 19:07 | mk | it would be nice if for example an editor could mark which functions are functional, which ones are at risk of evaluating non-functional args, and so on |
| 19:07 | amalloy | mk: TimMc's point is that "some subset" gives him a lot of leeway. eg, for the subset '#{inc, doseq}, you can be sure |
| 19:09 | emezeske | mk: It's a losing battle. Imagine (defn higher-order-io [write-fn] (write-fn "stuff")). |
| 19:09 | emezeske | mk: Is that pure? What if you pass in a write-fn that is impure? |
| 19:11 | amalloy | you need a type system as thorough as haskell's to answer this question, and that has its own problems |
| 19:11 | mk | you'd mark the function as potentially executing its args. If you know that its arg function is pure, then you're safe, no? |
| 19:12 | emezeske | How do you know its arg function is pure? |
| 19:12 | emezeske | Or the arg function's arg function? |
| 19:14 | emezeske | What if higher-order-io is part of the public API for your library? You don't even know what write-fn will be passed to it. |
| 19:16 | mk | because the arg is defined somewhere in the code. If it's in the public api, you expose the fact that your function does or might or doesn't eval its arguments. Then the user of the lib can have that info |
| 19:16 | mephist0 | it seems tedious to me to update a map redefining it every time, is there a way to keep it mutable? |
| 19:18 | mk | mephist0: the map never becomes mutable, if I understand you right |
| 19:18 | mk | you might use a mutable map implementation, but that's probably a bad idea |
| 19:19 | mephist0 | mk thnks. i meant dinamic. |
| 19:22 | mk | mephist0: maybe someone could take a look at your code and make a suggestion (pastebin/gist) |
| 19:24 | mephist0 | somethig easy like rhis: (def map_ {:a 1 b 2}) (def map_ (assoc map_ :c 3)) |
| 19:25 | matt444 | ClojureScript gives really bad error messages :( |
| 19:25 | mephist0 | i want to keep map_ dynamic to avoid redefining. |
| 19:26 | emezeske | matt444: This is true! There is discussion here on how to make them much, much better: https://groups.google.com/forum/?fromgroups#!topic/clojure/u5uFFaZpHTU |
| 19:26 | matt444 | Just pointing to what the file and line number of the error is would do wonders |
| 19:27 | emezeske | Yep, that's exactly what that discussion is about |
| 19:30 | Scorchin | What's a good way to test that println has been called and a certain kind of input has been produced? |
| 19:30 | Scorchin | s/input/output |
| 19:30 | dnolen | matt444: we're working on it |
| 19:31 | dnolen | emezeske: is it possible to give multiple source paths? I'm trying to figure out how to easily run some tests |
| 19:31 | mk | mephist0: why bind when you could just do (#(assoc % :c 3) {:a 1 :b 2}) ? |
| 19:32 | matt444 | dnolen: Thank you, very well appreciated. |
| 19:32 | emezeske | dnolen: You can't specify multiple source paths. I think the easiest thing to do is to add another build for the tests. All of the builds are added to the classpath, so the test build can access the other builds. |
| 19:32 | matt444 | I get some WARNs when it compiles, could those be a source of the error? |
| 19:32 | emezeske | dnolen: Example: https://github.com/emezeske/lein-cljsbuild/blob/master/example-projects/advanced/project.clj#L74 |
| 19:33 | wink | hm, can't I just copy a tool-0.2-SNAPSHOT.jar to ~/.lein/plugins with lein2 and use that instead of the "official" tool-0.1.jar? lein tries to download it and fails |
| 19:33 | mk | mephist0: if you find yourself writing x =1; x = x+1; x = x+2, what you should really be writing is (+ 2 (+ 1 x)), or somesuch |
| 19:34 | antares_ | I need a bit of advice. I have "factory" kind of protocol that always returns the same type of data. Should I just add a return type hint to it? then all the namespaces that use it will have to import that data type (it is not part of java.lang.*). Not sure what to do… this is in a library. |
| 19:35 | antares_ | I see that clojure.java.io/Coercions protocol does have return type hints |
| 19:35 | antares_ | but they seem to be using fully-qualified class names |
| 19:35 | antares_ | is this the secret? |
| 19:36 | mk | antares_: does the fully-qualified class name make the namespaces not need to import? |
| 19:36 | matt444 | My problem turned out to be I didn't close my (ns) function, lucky it was easy! |
| 19:37 | antares_ | mk: yes, and it makes perfect sense |
| 19:39 | mk | antares_: were there any other problems with adding type hints, or are you going to go along with the Coercions usage? |
| 19:40 | antares_ | mk: I sort of already have the answer |
| 19:40 | mk | antares_: great :) |
| 19:40 | antares_ | using fully-qualified class names in return type hints is the way to go |
| 19:41 | antares_ | it will both eliminate some annoying reflection warnings for lib users and they won't have to import classes they should not really know about |
| 19:42 | dnolen | emezeske: k tried that, any thoughts on why I would be a seeing a google.require error about not having provided a namespace? |
| 19:42 | dnolen | emezeske: project looks something like this, https://gist.github.com/2176408 |
| 19:43 | Scorchin | Is there any way to catch the output of *out* ? |
| 19:43 | mephist0 | mk: thanks. I'm starting clojure, so to test i solved a problem, a chess960 game generator (http://pastebin.com/P0kSsfUa). What seems to me "akward" is to redefine a map every time. But hey im noob here, just testing. |
| 19:44 | emezeske | dnolen: what version of lein? |
| 19:44 | dnolen | emezeske: 1.7 |
| 19:44 | emezeske | hrm, let me ponder that |
| 19:45 | dnolen | emezeske: https://gist.github.com/2176408 updated gist with tests.cljs |
| 19:46 | emezeske | dnolen: did you try doing a 'lein cljsbuild clean' ? Not that I think you should have to do that, but... |
| 19:46 | dnolen | emezeske: I'm on 0.1.2, 0.1.3 is out I see |
| 19:46 | emezeske | dnolen: Yeah, I saw that, might be worth upgrading but I don't think it will help XD |
| 19:47 | dnolen | emezeske: yeah, nicer output, same error :) |
| 19:47 | emezeske | haha |
| 19:48 | mk | mephist0: why does redefining seem awkward? |
| 19:50 | emezeske | dnolen: what namespace is it complaining about? |
| 19:50 | antares_ | mephist0: sounds like you need to use an atom there |
| 19:50 | matt444 | Where can I see the documentation for google closure? |
| 19:50 | emezeske | I assume cljs.core.logic ? |
| 19:50 | antares_ | mephist0: def is definitely not the right way to mutate data |
| 19:51 | dnolen | emezeske: gist updated, https://gist.github.com/2176408 |
| 19:51 | antares_ | mk: def goes against the entire point of identity/value separation in Clojure |
| 19:51 | mephist0 | antare_: atom? will check it out. |
| 19:52 | seancorfield | emacs q: i just started getting this error when i try to clojure-jack-in - Error: Invalid byte code in /usr/share/emacs/24.0.94/lisp/emacs-lisp/cl.elc |
| 19:52 | mk | mephist0: you've got a lot of code duplication there. Move q, n1, and n2 up to the top of the file |
| 19:52 | seancorfield | it was working just the other day... suggestions? |
| 19:52 | mk | mephist0: then turn your assoc reduce sort vals combo into a function |
| 19:53 | antares_ | mephist0: yes, make your state map an atom and mutate it using swap! and assoc (or any of your own functions that use assoc) |
| 19:54 | emezeske | dnolen: I'm mystified. I have seen possibly weird issues with the compiler when a namespace is spread over multiple subdirectories, though |
| 19:54 | emezeske | dnolen: Maybe related: https://github.com/emezeske/lein-cljsbuild/issues/54 |
| 19:54 | matt444 | nice tip |
| 19:55 | mk | mephist0: instead of redefining, you could be giving your pieces variable to a function. But if you'd like, you could be giving a function to the atom. |
| 19:56 | dnolen | emezeske: yeah, removing optimizations fixed the issue. |
| 19:57 | dnolen | emezeske: did you create a ticket in CLJS JIRA? |
| 19:57 | emezeske | dnolen: nah, I was lazy and hoped pkamenarsky would do it ^_^ |
| 19:57 | emezeske | I probably should |
| 19:57 | dnolen | emezeske: I will now |
| 19:58 | emezeske | dnolen: you da man! |
| 19:58 | matt444 | irssi just doesn't look write in gnome-terminal |
| 19:58 | matt444 | right |
| 19:58 | emezeske | xterm+tmux > * |
| 19:58 | emezeske | Oops, forget I said that, wrong channel |
| 19:59 | mephist0 | thanks antares_ and mk. Very appreciated. ;) |
| 19:59 | matt444 | yessir |
| 20:06 | dnolen | emezeske: actually not quite, I get files but I see that goog.provide and goog.require appearing instead of those files getting concat'ed |
| 20:10 | seancorfield | hmm, google searches indicate i may have installed a package that caused cl.elc to be corrupted... i wonder how to easily get it back to a valid state? |
| 20:11 | alexbaranosky | what was the technique I saw recently for including a library using lein2 without needing a project file? |
| 20:11 | emezeske | dnolen: Ah, yeah, if you omit optimizations I think it does produce multiple files and you have to use the deps.js and so forth |
| 20:12 | emezeske | dnolen: Which is a pain |
| 20:12 | dnolen | alexbaranosky: http://sunng.info/blog/2012/03/my-favorite-feature-in-leiningen-2/ |
| 20:12 | alexbaranosky | dnolen, thanks |
| 20:12 | seancorfield | ugh... i get that cl.elc error trying to install any package now :( |
| 20:12 | dnolen | emezeske: hmm ... but isn't deps.js for the browser? |
| 20:12 | dnolen | emezeske: I just want to run tests at the command line |
| 20:13 | emezeske | dnolen: Ah, yeah, I think disabling optimizations makes that quite unpleasant |
| 20:13 | alexbaranosky | guess I should add (use '[cemerick.pomegranate :only (add-dependencies)]) to .lein/init.clj :) |
| 20:15 | dnolen | emezeske: I was wondering why cljs's own tests don't have this problem but that's because cljs.core is hard coded to be included. |
| 20:16 | alexbaranosky | does the technique used in that blog fail if I don't have the dependency locally? |
| 20:16 | dnolen | emezeske: I think the bug is that goog.require's should never appear under advanced compilation |
| 20:17 | dnolen | emezeske: it makes me think that the compiler can't find the files on the classpath. |
| 20:19 | muhoo | +1 pomegranate |
| 20:19 | dnolen | emezeske: do you have a good way that you test against CLJS HEAD? |
| 20:19 | alexbaranosky | does the pomegranate trick require a newish version of lein2? |
| 20:20 | alexbaranosky | I'm seeing an exception: "no value supplied for key [[...core.logic...]] |
| 20:22 | antares_ | I have a Java interop question, are there any special rules about calling variadic java methods? |
| 20:22 | antares_ | I have this signature: public EventHandlerGroup<T> handleEventsWith(final EventProcessor... processors), trying to call it as (.handleEventsWIth o processor) results in a java.lang.IllegalArgumentException: No matching method from the compiler |
| 20:24 | antares_ | ok, looks like I'll have to use into-array |
| 20:24 | antares_ | found in http://dev.clojure.org/display/doc/FAQ |
| 20:25 | emezeske | dnolen: sorry, was afk, catching up |
| 20:25 | alexbaranosky | none of you guys have seen?: #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: [[org.clojure/core.logic "0.6.8"]]> |
| 20:26 | emezeske | dnolen: yeah, it's not too hard for me to test against HEAD |
| 20:26 | dnolen | emezeske: what do you do? I thinking about checking out lein-cljsbuild and sorting this issue out |
| 20:28 | antares_ | alexbaranosky: can you gist your project.clj or at least the :dependencies key? |
| 20:29 | emezeske | dnolen: Basically, I'd build the clojurescript jar and install it to my local maven repo |
| 20:29 | emezeske | dnolen: And then edit lein-cljsbuild/support/project.clj to point at that local version |
| 20:29 | emezeske | dnolen: Then, rebuild lein-cljsbuild (both support/ and plugin/ dirs) and install that |
| 20:29 | dnolen | emezeske: what commands do you use to build and install it? sorry maven noob |
| 20:30 | emezeske | dnolen: Haha, that's actually the part I'm fuzzy on too. I forgot that it doesn't use leiningen |
| 20:31 | emezeske | dnolen: I guess I haven't built clojurescript myself since it was released as an official jar |
| 20:31 | alexbaranosky | antares_, I thought the whole point was to not need to have a project.clj? |
| 20:32 | antares_ | alexbaranosky: are you adding plugins to your lein2 profile? sorry, it is true that I wasn't following the channel for the last hour or so |
| 20:33 | alexbaranosky | antares_, was referring to attempting to use this: http://sunng.info/blog/2012/03/my-favorite-feature-in-leiningen-2/ |
| 20:34 | emezeske | dnolen: Do you think the problem is that the classpath is not being set up correctly? |
| 20:34 | antares_ | alexbaranosky: ahh. I haven't tried using pomegranate from the REPL |
| 20:36 | dnolen | emezeske: possibly |
| 20:36 | dnolen | emezeske: I know compiler.clj pretty well, looks like it's time for me really read closure.clj |
| 20:37 | emezeske | dnolen: I wonder if there's some way you could, in your cljs file, print out the current classpath (perhaps with a crazy macro)? |
| 20:37 | dnolen | emezeske: huh, that's a good idea, and not really a crazy macro :) |
| 20:41 | emezeske | dnolen: if the classpath is wrong, I can debug that in lein-cljsbuild pretty easily |
| 20:42 | matt444 | goog.events is for custom events? |
| 20:42 | matt444 | right? |
| 20:42 | matt444 | What is the closure method for listening? |
| 20:43 | wink | can anyone give me a hint in which format this function expects kw-opts? https://github.com/jonase/kibit/blob/master/src/jonase/kibit/core.clj#L175 |
| 20:44 | dnolen | emezeske: classpath looks OK, in fact in tests.cljs I can load the macros which proves that it is |
| 20:44 | dnolen | emezeske: so something wrong in the compiler I think |
| 20:45 | amalloy | wink: (check-file "blah" :opt1 val1 :opt2 val2) |
| 20:45 | emezeske | dnolen: cool |
| 20:46 | emezeske | dnolen: I think I'd suggest debugging that with the raw compiler (e.g. without lein-cljsbuild) |
| 20:46 | wink | amalloy: oh, yes. that wqrks. thanks a lot. I totally would've expected {:opt1 val1} though. hmm |
| 20:46 | emezeske | dnolen: Using lein-cljsbuild adds a bunch of "lein install"ing and so forth |
| 20:46 | emezeske | dnolen: I think you can pretty easily use just the compiler by editing the cljsc script and adding the classpath entries that you need there |
| 20:47 | dnolen | emezeske: yep |
| 20:48 | mk | how do I chain e.g. (+ 4 (+ 3 (+ 2 x)))? I want something like (foo x + (2 3 4)) |
| 20:50 | dnolen | ,(let [x 1] (apply + x [2 3 4])) |
| 20:50 | clojurebot | 10 |
| 20:50 | dnolen | mk: ^ |
| 20:50 | AimHere | For things which don't accept that, 'reduce' is perhaps better |
| 20:52 | AimHere | What I mean is that '+' accepts multiple arguments, so applying it to a list can work; some functions only take two, in which case 'apply won't |
| 20:52 | mk | how can that be done when the function in question should take X as the middle argument of a multi-arg function? |
| 20:53 | AimHere | (reduce + x [2 3 4]) |
| 20:55 | mk | suppose I need to do the equivalent of x = (* 1 x 3); x = (* 2 x 4); and so on |
| 20:56 | dnolen | ,(apply * [1 x 3]) |
| 20:56 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0)> |
| 20:56 | dnolen | ,(let [x 2] (apply * [1 x 3])) |
| 20:56 | clojurebot | 6 |
| 20:56 | dnolen | mk: is that what you mean? |
| 20:57 | mk | the proper way to do this seems to be (((...(* 2 (* 1 x 3) 4)...))), but I don't want to have such deeply nested function calls |
| 20:57 | dnolen | mk: use let then for intermediate values |
| 20:59 | mk | dnolen: I don't follow |
| 20:59 | dnolen | (let [n (* 1 x 3)] (* 2 n 4)) |
| 20:59 | AimHere | Is what you're after just applying a list of functions to x? You might consider 'juxt' |
| 21:00 | AimHere | Wait, not juxt... |
| 21:00 | mk | dnolen: how does that work if I need to apply the function 12 times? |
| 21:02 | dnolen | mk: if there are real subparts of the formula you can just break those out too. I don't really know what you're trying to do. |
| 21:04 | AimHere | ,(let [x 10] (reduce #(%2 %1) x [#(* 2 %) #(* 3 %) #(* 4 %)]) |
| 21:04 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 21:04 | mk | I have a value that I'm trying to push through 12 functions. Each one alters the value. But I don't want to nest the functions, because that looks ugly. The functions have many arguments |
| 21:04 | AimHere | mk > howabout applying it to a list of functions, like my abortive attempt above? |
| 21:05 | AimHere | (I left off the last right parentheses) |
| 21:06 | dnolen | mk: I'm not even sure I understand your example (* 2 1 x 3 4) works |
| 21:06 | mk | AimHere: thanks, I'll look at that - though I already have the functions defined elsewhere |
| 21:06 | AimHere | Well yes, I was just defining them inline for the example |
| 21:07 | dnolen | mk: if operator precedence matters you would be wrapping in parens anyhow. |
| 21:07 | mk | dnolen: * is just a placeholder. The function I use isn't commutative. |
| 21:07 | dnolen | mk: then you'd have parens anyhow. |
| 21:08 | rhc | is it possible to pass a def to a function and have the function modify the def? or am I thining about this incorrectly? |
| 21:08 | rhc | guess i should just return a let the caller def |
| 21:08 | mk | dnolen: that's fine, but I'd prefer (()()()()() a) to ((((((a))))) |
| 21:08 | rhc | or do what they want.. |
| 21:09 | AimHere | mk > There's also the -> operator |
| 21:09 | dnolen | mk: write an infix macro or use an existing one. not worth it tho imo. |
| 21:12 | mk | AimHere: -> looks about right, thanks |
| 21:13 | dnolen | AimHere: mk: though note -> doesn't arbitrarily thread, it's mostly for dealing with things in an "object-like" way. |
| 21:13 | dnolen | ,(-> "foo" first int) |
| 21:13 | clojurebot | 102 |
| 21:13 | dnolen | kinda like: foo.first().int() |
| 21:14 | mk | yeah, it's not perfect for this, but like you said it's probably not worth doing much more |
| 21:33 | ideally_world | Is there a better way of getting the count of the longest seq in a seq of seq than (count (reduce #(if (> (count %1) (count %2) %1 %2)) x))? |
| 21:33 | johnkpaul-afk | I am trying to get the getting started example for clojurescript one working |
| 21:33 | johnkpaul-afk | CompilerException java.lang.RuntimeException: No such namespace: js, compiling:(NO_SOURCE_PATH:1) |
| 21:33 | johnkpaul-afk | and I keep getting that error |
| 21:34 | amalloy | (apply max (map count x))? |
| 21:34 | johnkpaul-afk | I see many mailing list posts about the problem |
| 21:34 | mindbender1 | johnkpaul-afk: did you lein bootstrap? |
| 21:34 | johnkpaul-afk | that say to run (cljs-repl), but then I get a BindException |
| 21:34 | johnkpaul-afk | yes, I did |
| 21:35 | johnkpaul-afk | I can do that again though |
| 21:35 | mindbender1 | and lein deps with no errors |
| 21:35 | johnkpaul-afk | oh, no, I didn't do that |
| 21:35 | johnkpaul-afk | that's not in the guide |
| 21:35 | johnkpaul-afk | let me try that |
| 21:35 | ideally_world | amalloy, thanks, I knew mine was pertty clunky |
| 21:36 | mindbender1 | Yea bootstra took care of deps |
| 21:36 | johnkpaul-afk | mindbender1: yeah, I am experiencing the same problem |
| 21:36 | johnkpaul-afk | even after lein deps |
| 21:37 | mindbender1 | Are you running the version you checked out or a copy |
| 21:37 | johnkpaul-afk | the version I checked out |
| 21:37 | mindbender1 | cos it happened to me when I copied it |
| 21:37 | johnkpaul-afk | I copied from here exactly |
| 21:37 | johnkpaul-afk | https://github.com/brentonashworth/one/wiki/Getting-started |
| 21:38 | johnkpaul-afk | meaning, I cpied and pasted |
| 21:38 | matt444 | How can I call a JavaScript function by string? In JS you could do object["function_name"].call(null) |
| 21:39 | mindbender1 | johnkpaul-afk: where are you getting the errors in the browser or repl |
| 21:39 | johnkpaul-afk | repl |
| 21:40 | mk | matt444: not sure, but javascript objects are maps, and maps can map to functions, and functions can be called |
| 21:40 | mindbender1 | aah.. I got mine in the browser.. what were you trying to do |
| 21:40 | johnkpaul-afk | mindbender1: http://pastebin.com/W28cZFRX |
| 21:41 | johnkpaul-afk | I'm just trying to start the repl and (js/alert) |
| 21:41 | johnkpaul-afk | basically just try to make the sample app work |
| 21:41 | johnkpaul-afk | matt444: I know next to nothing, but can't you do ((:function_name object)) |
| 21:42 | mindbender1 | johnkpaul-afk: did you get the browser to open with (go) |
| 21:43 | johnkpaul-afk | yes |
| 21:43 | johnkpaul-afk | it opens immediately |
| 21:43 | mindbender1 | and when you do (js/alert) you get errors in the repl |
| 21:44 | johnkpaul-afk | yeah |
| 21:44 | mindbender1 | try (js/alert "hello") |
| 21:44 | johnkpaul-afk | I did, that's what's in the paste |
| 21:45 | johnkpaul-afk | oh! |
| 21:45 | johnkpaul-afk | got it |
| 21:45 | johnkpaul-afk | damn, that's not obvious |
| 21:45 | johnkpaul-afk | it doens't work if I have a clojurescript repl running |
| 21:45 | johnkpaul-afk | in another terminal window |
| 21:46 | mindbender1 | aah .. that should be noted |
| 21:46 | johnkpaul-afk | ha, yeah, I will remember that now |
| 21:46 | johnkpaul-afk | I've been working on this for half an hour |
| 21:46 | johnkpaul-afk | so confused |
| 21:46 | johnkpaul-afk | thank you for your help mindbender1! |
| 21:46 | mindbender1 | you will be cleared in a short while |
| 21:46 | mindbender1 | you welcome |
| 21:47 | mindbender1 | johnkpaul-afk: I think the relevant part of your errors was BindException Address already in use java.net.PlainSocketImpl.socketBind (PlainSocketImpl.java:-2) |
| 21:48 | mindbender1 | and you were not in the clojurescript repl as you would have noted by now |
| 21:48 | johnkpaul-afk | yeah, I thought that made no sense because I was seeing it fine at port 8080 |
| 21:48 | johnkpaul-afk | yeah |
| 21:48 | johnkpaul-afk | it makes sense now |
| 22:29 | mk | are structmaps totally deprecated? |
| 22:46 | qbg | mk: Not too much reason to use them |
| 22:53 | qbg | records are so much better |
| 22:55 | mk | is it safe to say you'd never use them? |
| 22:57 | qbg | I don't have any reason to use them |
| 22:59 | mk | the reference suggests that records should be usually used instead, so I was wondering if there was some remaining use, or if they're now totally vestigial |
| 22:59 | mk | I guess it's the latter |
| 23:00 | qbg | You don't have to generate a class to use them |
| 23:01 | Lajla[badbreath] | What's the exact differene between a record and a structmap? |
| 23:01 | qbg | The definitions can be anonymous also |
| 23:02 | technomancy | just use a map |
| 23:02 | mk | is there a benefit to not defining a class? There's also reify... |
| 23:03 | qbg | Classes have some overhead, but nothing much to worry about in almost all cases |
| 23:03 | technomancy | defining classes introduces hiccups to interactive development |
| 23:03 | technomancy | IIRC there are some cases where recompiling doesn't apply retroactively like it should |
| 23:03 | qbg | You keep old instances around, and it can be confusing |
| 23:04 | mk | Lajla[badbreath]: a record generates a real class, a structmap is like a map without having to see :property keywords everywhere |
| 23:05 | qbg | Structmaps are dense maps |
| 23:19 | srid | did I come to clojure thinking i am smart and cool? that kills pragmatism. |
| 23:31 | gtrak | anyone know of an easy way to pull out files based on ant-patterns in clojure? |