#clojure log - Mar 23 2012

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:00 cemerick: oooh

0:00 lynaghk: despite the assurances of the folks at the desk

0:00 cemerick: nasty

0:00 lynaghk: yeah, I thought maybe Silicon Valley would be the one place where stuff like that works...nope.

0:00 cemerick: "sign out" rarely means Sign Out anyway

0: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"

0:02 ibdknox: lol

0:02 ohpauleez: lynaghk: ping

0:02 lynaghk: so I couldn't do anything but really paw at it with all combinations of my digits

0:02 ohpauleez: YES

0:02 ibdknox: lynaghk: don't pong

0:02 ohpauleez: finally!

0:02 ibdknox: don't do it

0:02 ohpauleez: haha

0:02 ibdknox: run

0:02 lynaghk: yo Paul! I was about to send you a pull request

0:02 cemerick: he's irc'ing from in the building!

0:02 lynaghk: need keyword args propogated for your kibit change

0:03 ibdknox: cemerick: lol

0:03 ohpauleez: Cool, I just saw you forked.

0:03 Totally send the request, and shoot me an email me if you have any special requests. I usually get changes in daily

0:04 hahah cemerick

0:04 lynaghk: ohpauleez: yeah, I think there are some other changes I need to figure out first.

0:04 ohpauleez: cool thanks.

0:04 cemerick: ibdknox: what have you been recommending for auth in conjunction with noir?

0:04 ohpauleez: hey paul :-)

0:04 ibdknox: cemerick: define auth

0:04 cemerick: as in just putting pages behind privileges?

0:05 cemerick: authentication / authorization

0: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

0:05 I'm not so sure yet, but we'll see

0:05 cemerick: Hey! what are we doing up right now?

0:06 ibdknox: cemerick: you can do the filtering very easily using pre-routes

0:06 cemerick: no one has created a magical auth thing, past that

0:07 cemerick: ibdknox: ah, I see you have a dep on jbcrypt directly; so you're providing form-based authentication yourself?

0:08 ibdknox: cemerick: just an encryption util to make sure people don't do something bad... like use sha1

0:08 cemerick: ohpauleez: heh, sometimes I'm up 'til 4 if I'm being a spaz.

0:08 ok

0:09 muhoo: i dunno how magical you're looking for, but there's this: https://github.com/sumilux/ssi-java-client

0:09 ibdknox: cemerick: decent example here: https://github.com/ibdknox/Noir-blog/blob/master/src/noir_blog/views/admin.clj#L51

0: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.

0:12 brehaut: cemerick: excellent!

0:13 cemerick: Meh. Doing it out of anger.

0:13 brehaut: thats how many web things get written isnt it?

0:13 cemerick: In retrospect, probably one of the reasons I try to stay away from webby things in general. :-P

0:13 brehaut: haha

0:14 xeqi: cemerick: I've been looking for one of those

0:14 like a ring version of warden

0:14 brehaut: i certainly didnt write necessary evil for fun :P

0:14 cemerick: I tried *really* hard to get spring-security to work with containerless jetty. Two days later, I cried uncle.

0:14 ibdknox: I want someone to build every auth for clojure

0:14 I thought I convinced someone to do it

0:14 I've since forgotten who that was

0:15 brehaut: ibdknox: i believe some sort of karmic transmutation has made that be cemerick

0:15 cemerick: I'll do form, basic, and *maybe* openid. Someone else will have to bring me patches for the rest.

0:16 xeqi: link for warden please?

0:16 xeqi: https://github.com/hassox/warden/wiki

0:16 brehaut: im sure raynes would love to do the oauth portion for you

0:16 cemerick: bwahahah

0:16 xeqi: Thanks; and, hi :-)

0:17 ibdknox: brehaut: yeah he loves that shit

0:17 ;)

0:17 brehaut: haha

0:18 xeqi: just another library for inspiration; too busy making some ring testing libs based on rack-test/capybara to dig into it myself

0:18 and, hi back

0:18 cemerick: xeqi: definitely, want to make sure I don't make too many egregious errors.

0:19 You should all be scared shitless at this point.

0:19 muhoo: someone is building an everyauth thing as a service. it's this: http://www.social-sign-in.com/

0:19 * ibdknox is pretty scared

0:19 cemerick: login as a service as a service? o.0

0:20 muhoo: cemerick: basically. yeah, i know.

0:20 xeqi: isn't that openid?

0:20 muhoo: openid works for some services, not all.

0:20 cemerick: login as a service as a service as a service, then.

0:20 xeqi: wait.. theres an extra "as a service" on the end of that

0:20 muhoo: "as a service" means "we can charge you for it"

0:21 instead of all that open-source hippie stuff :-)

0:22 technomancy: what about sandbar? isn't it supposed to do auth-y stuff?

0:22 muhoo: (recur service)

0:22 lynaghk: ohpauleez: pull requested.

0:22 technomancy: muhoo: FWIW I think the repl task in lein2 is supposed to have a :headless option

0:22 oh... but that's nrepl, not raw socket repl

0:22 ohpauleez: lynaghk: cool, thanks, I'll check it out right now

0: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

0:23 cemerick: technomancy: yeah, I read its source earlier. It does 40 other things too, and makes some unfortunate choices, IMO.

0:23 ibdknox: cemerick: technomancy: brenton said use at your own risk

0:23 lol

0:23 technomancy: good to know, heh

0:23 ibdknox: he talked someone out of using it at clojurewest

0:23 so

0:23 cemerick: hah, I didn't know that

0:23 technomancy: suspected it was a bit sprawling at first glance

0:23 brehaut: its 5pm friday here, so have a good weekend everyone

0:23 lynaghk: you too brehaut.

0:24 cemerick: I saw https://github.com/brentonashworth/sandbar/wiki/Stateful-Sessions and was immediately concerned.

0:24 Anyway. There's a bunch of good ideas in there that I'm going to steal.

0:24 technomancy: yeah, still plenty of gaps in the web stack; somebody's just gotta step up =)

0:25 * cemerick grumbles

0:25 ibdknox: pfft what are you talking about my few thousand lines of Noir totally covers everything ;)

0:25 lol

0:25 xeqi: he

0:25 muhoo: technomancy: so, fyi: with :repl-port set, this basically works: lein trampoline repl < /dev/null 2> somewhere >somewherelse

0:25 ibdknox: a solid everyauth would be a wonderful addition

0:26 cemerick: ibdknox: is 'everyauth' an actual thing, or just a shorthand you're using?

0:26 ibdknox: actual thing

0:26 https://github.com/bnoguchi/everyauth

0:26 I know it's node - try not to throw up

0:26 cemerick: hrm

0:27 that'll take a bit of effort, but I'll work on it. :-)

0:27 impressive list!

0:27 ibdknox: mostly if the base of it is there, it's trivial to add in the pieces

0: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

0:27 muhoo: planning on cutting a 1.7.1 release next week

0:27 muhoo: technomancy: i'm not quite comfortable with the innards of lein yet.

0:28 but, i'm sure i will be :-) and i'm looking forward to contributing.

0:28 cemerick: `npm install everyauth` ha ha, wat?

0:28 technomancy: I can help you step through the code tomorrow if you like

0:28 xeqi: cemerick: same idea for rack: https://github.com/intridea/omniauth

0:28 cemerick: (keep the good prior art flowing)

0: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.

0:29 a lot of how to USE it, it's easy. but not a lot of HOW it does what it does

0:29 technomancy: muhoo: yeah, especially the repl in lein1 is not documented outside my own head; fortunately it all got rewritten in lein2

0:31 xeqi: cemerick: https://github.com/hassox/warden_omniauth - warden + omniauth

0:34 jmalone: i have seen the clojurewest slides but were the presentations recorded?

0: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?

0:35 jmalone: yeah, I believe they will be released on a rolling basis starting in a few weeks.

0:35 dunno who's on deck though.

0:35 ohpauleez: lynaghk: There is no backtracking or context awareness. The upcoming will have "best rule" enabled

0:35 right now I can only do that with loop-recur, but I'm certain core.logic can do that

0:36 lynaghk: hmm. I'm not so much thinking about backtracking but overlapping forms

0:36 ohpauleez: so (if (=0 0) :a nil) will go to :a

0:36 jmalone: lynaghk: thanks i guess ill just have to be patient

0:37 ohpauleez: alts would be when, (zero? 0), true, then just :a

0: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...)

0:37 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.

0:38 ohpauleez: Yeah, that context can't be captured if it's a complex rule

0:38 (reify . ?x (blah) . ?y) type of rule

0:39 lynaghk: ohpauleez: damns. I was thinking about looping through until alts stopped popping up, but that feels like a hack.

0:39 ohpauleez: or the subforms need to have subrules

0:39 jmalone: lynaghk: haha thanks ill look it up

0:39 ohpauleez: lynaghk: Ahhh yeah, we can do that

0:39 I see what you're saying

0:39 yes, that'll be in this next release

0:39 lynaghk: okay, rad.

0:39 are you still keepin' it static?

0:40 In an ideal world I could use the matching / replacement after macro expansion time.

0:40 ohpauleez: (if (= 0 0) :a nil) => (when (= 0 0) :a) => (when (zero? 0) :a) => (when true :a) => :a

0:40 * lynaghk thinks to himself.

0:40 ohpauleez: still static

0:40 if you can express the smaller parts as rules, it'll pick it up

0:41 lynaghk: ohpauleez: okay, that sounds great.

0:41 ohpauleez: if-nil goes to when, = 0 is a zero?, zero? 0 is true, when true is dead code

0:41 and we have rules for each of those

0:42 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

0:42 haha

0:42 lynaghk: did you just see that phrase on a t-shirt in your mind? Because I did.

0:42 Maybe I'll make some for the next Conj.

0:43 ohpauleez: hahaha

0:43 You'll be wealthy beyond your imagination

0:43 Seriously, core.logic is like a real life oracle

0:43 You think up any reality, and all of sudden it magical is possible

0: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"

0:44 I'd buy that

0:44 lynaghk: alexbaranosky: yep.

0:44 muhoo: prolog will be the haskell of 2013

0:44 ohpauleez: It's the alchemy of programming, except it works

0:45 muhoo: ryan senior's presentation on core.logic did definitely leave me dazzled and intrigued, sure

0:45 alexbaranosky: I feel like I'm inches away from writing a logic program, after watching Senior's talk

0:45 muhoo: alexbaranosky: jinx :-)

0:46 ohpauleez: We have a "Kibit reading list"

0: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"

0:46 ohpauleez: specific to simplifying expressions with logic

0:46 lynaghk: muhoo: just those two golden rules...

0:48 Zoka: muhoo: on what port are you running your repl server - is it internal testing?

0:48 slyrus: muhoo: wasn't prolog the haskell of 1995?

0:48 muhoo: Zoka: yes, just an ephemeral port so i can ssh in , do port forwarding, and get to it.

0: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/

0:50 s /rin/run/

0:51 mohoo: see: As a replacemnet for lein repl section

0: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

0:53 Zoka: No problem

0:53 ohpauleez: lynaghk: If you ever come out, you should totally come party/crash at Tutorspree HQ

0:53 We just finished a solid Startup Crawl

0:53 lynaghk: ohpauleez: donezo.

0:53 muhoo: Zoka: thanks though. it's a very neat project.

0:54 lynaghk: Last time I was in NYC I crashed with the Mongo folks.

0:54 scriptor: you slept in their iffice?

0:54 *office

0:54 lynaghk: no, just came by for high fives

0:54 scriptor: ah, yea their office hours thing is pretty cool

0:54 lynaghk: they have office hours, and they're pretty nice. I was in the middle of a node.js+mongo project.

0:55 muhoo: i hear they are managing risk very effectively at tutorspree

0:55 lynaghk: I was, er, younger then.

0:56 ohpauleez: muhoo: haha I heard that too somewhere

0:59 cemerick: lynaghk: we all have a seedy past ;-)

1:00 lynaghk: cemerick: I still have my fixed gear bicycle to prove how fast I went then.

1:03 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.

1:03 ztellman: the best questions begin with "you're wise;"

1:04 lynaghk: ztellman: you're also wise! also question for you!

1:04 jmalone: lynaghk: do you have a link for that video?

1:04 cemerick: lynaghk: good troll dude :-P

1:04 ztellman: lynaghk: same question? different question?

1:04 lynaghk: same question

1:04 cemerick: lynaghk: I dunno what the worse idea is: asking me for advice on ClojureScript, or what you're proposing. ;-)

1:04 lynaghk: ha

1:04 ztellman: ha

1:05 lynaghk: I did something kind of analogous for Lamina

1:05 there's some weirdness that is exposed when you macroexpand everything

1: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.

1:05 ztellman: especially w.r.t. chunked-append & co

1:05 dnolen: lynaghk: ohpauleez: hullo! btw, core.logic does backtracking for you.

1:05 ztellman: I don't know if cljs has matching structures for that

1:06 cemerick: lynaghk: you were there for the portability discussion; big ol' windmill, it is.

1:06 ohpauleez: dnolen: YES! I need to learn how to whisper to core.logic to achieve that

1:06 dnolen: ohpauleez: it's automatic

1:06 ztellman: core.logic whispers to itself

1: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)

1:07 ohpauleez: ztellman: one would expect this

1:07 jmalone: lynaghk: i was feeling rather silly not being able to find it, now i see its unlisted so i feel less silly

1: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.

1:07 ohpauleez: dnolen: Is my assumption right- core.logic could "recurse" or do I need to l explicitly loop

1:07 ztellman: conditional compilation would be nice

1: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.

1:08 cemerick: without that, you're going to hit a serious brick wall eventually, and have no recourse.

1: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 :)

1:08 lynaghk: cemerick: what do you mean, conditional compilation?

1:08 ztellman: lynaghk: I meant whether there are cljs analogues for chunked seqs and all the other implementation details that are exposed by macroexpand

1:08 cemerick: #clj […clojure code] #cljs […cljs code…]

1:08 ztellman: basically, if your approach works for (for …), you're golden

1:08 dnolen: ohpauleez: core.logic is properly tail recursive, internal uses really fancy trampolines.

1:08 ztellman: but that's surprisingly hard

1:08 cemerick: that may or may not work

1:09 ohpauleez: dnolen: So far it's been a blast. The biggest limit is me and my understanding of the possibilities

1:09 cemerick: actually, it should definitely work.

1:09 lynaghk: ztellman: thanks for the tip. I believe that macroexpand should work fine.

1:09 dnolen: ohpauleez: I admit it's pretty daunting - and I'm too lazy to convert copious Prolog literature.

1:09 lynaghk: cemerick: ah, yes that is what I'm using kibit for, basically

1:09 ohpauleez: It's what we're working with right now, so far, it hasn't been so bad.

1:10 dnolen: ohpauleez: my simple rule parser from tickt #20 was recursive.

1:10 ztellman: dnolen: just write write an automatic translator for art of prolog

1:10 you have the tools

1:10 dnolen: ztellman: I have too many Clojure project as it is :)

1: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.

1:10 ohpauleez: dnolen: it could achieve: (if (= 0 0) :a nil) => (when (= 0 0) :a) => (when (zero? 0) :a) => (when true :a) => :a

1:10 ?

1:10 man, I need to go back and study that again

1:11 cemerick: lynaghk: heh, ok, I see what you're really trying to do now.

1:11 whew.

1: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.

1: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).

1:13 ohpauleez: dnolen: That's what I'm doing now

1:14 cool, that's easy enough then

1: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.

1: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?

1: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

1:15 it's been SO MUCH FUN to work with, and the benefits are clearly illustrated in kibit

1: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.

1: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).

1: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

1:17 lynaghk: I'll merge your pull req in tomorrow morning after jonas takes a quick look at it, cool?

1:18 lynaghk: ohpauleez: sure, sounds good to me.

1:18 dnolen: ohpauleez: I think a lot of perf stuff in the future could be addressed via rule indexing.

1:18 cemerick: lynaghk: right, you mentioned that. Why not a conditional (import 'clojure.lang.IFn), etc?

1:18 lynaghk: cemerick: in ClojureScript just (def clojure.lang.IFn IFn)?

1:18 cemerick: But yeah, a lot less cred in that.

1:18 heh, or that

1:18 ohpauleez: dnolen: Awesome, definitely good to know

1:19 cemerick: I think conditional compilation is pretty cred-ful though, and will come in handy later anyway.

1: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)

1:20 cemerick: lynaghk: conditional compilation + a definline, and the result would look damn pretty.

1:20 s/a/many

1: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

1:21 cemerick: well, don't let me stop you ;-)

1:21 lynaghk: heh

1:21 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?

1:21 cemerick: no, the extensible reader should enable it

1:22 sritchie: cemerick, got it all working, thanks again

1:22 cemerick: i.e. you bind #clj to return nil on cljs, and #cljs to return nil on clj

1:22 sritchie: nice

1: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

1:22 cemerick: like, different order, or actually different data?

1: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

1:23 passing {:reduce false} shows me the proper results of the map step

1:23 cemerick: futon defaults to reduce=false

1:24 sritchie: yeah, but when I click the reduce checkbox I get the proper pairings of key, reduced vals

1:24 oh, I think I see

1:24 there's a "groupings" dropdown

1:24 futon has "exact"

1:24 but if I switch it "none", I get the behaviour I'm seeing in clutch

1:25 cemerick: yup, it's just different defaults

1:25 sritchie: so I can pass a :grouping option in the map?

1:26 cemerick: tons of query options for views; check the table halfway down: http://wiki.apache.org/couchdb/HTTP_view_API

1:26 sritchie: cemerick: sorry to bug you about this stuff, not sure how to track down these options

1:26 oh, great

1:26 so I can pass these in w/ the map as keywords

1:26 cemerick: no worries. That wiki has tons of gems

1:26 yup

1:26 sritchie: nice

1:26 thanks dude

1:26 cemerick: just watch your underscores

1:27 I burned a day because I was mistakenly using :group-level instead of :group_level

1:27 sritchie: cemerick: oh boy

1:27 cemerick: I guess I should make clutch normalize that :-P

1:27 sritchie: cemerick: I'm sure you've heard this before, but I'm going to write this business up

1:27 couch is too good to let folks pass it by

1:27 cemerick: whack away

1:27 I agree

1:27 esp. cloudant

1:28 * cemerick needs to stop being such a fanboy ;-)

1:28 sritchie: haha, control that!

1:28 cemerick: this is probably a generic cljs question, but is there a problem w/ returning clojure vectors from these map and reduce funcs?

1:28 say I want to make a compound key

1:29 cemerick: you mean using a cljs view?

1:29 I honestly don't know.

1:29 sritchie: yup

1:29 seems to be failing --

1:29 cemerick: Yeah, you may need to explicitly return a js array.

1:29 sritchie: I suppose I just need to make a javascript array

1:29 yeah

1:30 what's the syntax for that?

1:30 cemerick: no clue

1:30 sritchie: I guess there's some conversion *embarrassed*

1:30 anyone know how to make a js array?

1:30 cemerick: FWIW, I've not used cljs views in anything real yet.

1:30 How's that for embarrassed? ;-)

1:30 sritchie: haha, kudos for getting all this working, then

1:30 cemerick: maybe (js/Array 1 2 3)

1:31 sritchie: I'll try it out

1:31 and push to cloudant immediately

1:31 lynaghk: sritchie: you just want (array 1 2 3)

1:31 sritchie: no js prefix?

1:31 cool

1:32 lynaghk: I've found it helpful to just paw through the cljs compiler source.

1:32 sritchie: I've been meaning to do that anyway, I'm sure that would save a lot of pain here

1:32 lynaghk: there are a lot of macros in clojurescript/src/clj/cljs/core.clj that are illuminating

1:32 cemerick: lynaghk: see, and you're asking *me* about cljs‌‽

1:32 lynaghk: cemerick: I asked you about macro magic = )

1:32 cemerick: heh, fine

1:33 dnolen: lynaghk: +1. also if people have suggestions / improvement ... :)

1: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

1:33 very simple and straightforward

1:33 ohpauleez: dnolen: Is there a logical equiv to _

1:33 (I'm writing some dead code elimination, and I need a way to express "nothing" in a rule

1:34 dnolen: ohpauleez: just create an lvar with that name (fresh [_] ...)

1:34 ohpauleez: Ahhh cool

1:34 thank you

1:34 dnolen: ohpauleez: hmm ... oh in a rule you have ?foo

1:35 ohpauleez: [(when-not true ?x) _]

1:35 dnolen: ohpauleez: and ?foo in the same expression will be the same var.

1:35 [(when-not true ?x) ?_] should work I think

1:35 lynaghk: cemerick: as it turns out, you can't return nil from an extensible reader fn: "No dispatch macro for: e"

1:36 cemerick: lynaghk: so return something innocuous, like []

1:36 or (do)

1:37 lynaghk: ohh, (do) sounds nice.

1:38 cemerick: eh, that'll get a little dicey for returns.

1:38 you'll end up having to do (or #cljs […] #clj […])

1:39 side-effecting bits will be fine

1:39 lynaghk: yeah, but I don't think I really want it to become idiomatic for people to mix clj/cljs within forms.

1:41 cemerick: that sounds very sane

1:42 ohpauleez: Thanks for everyone's help! Kibit now has dead code elmination!

1:43 dnolen: ohpauleez: :D

1:43 sritchie: if I call concat on two cljs arrays, will they stay arrays?

1:44 dnolen: sritchie: (.concat a1 a2) yes

1:44 sritchie: I suppose I could do (apply array (apply concat [arr1 arr2 arr3]))

1:44 dnolen: this is for a couchdb view -- one of the arguments is a sequence of values, each of which are js arrays

1:45 dnolen: I just want to concat them all together and return a new single array

1:45 I should probably go open up a cljs repl and educate myself

1:45 dnolen: sritchie: in general you can't call cljs fns on js arrays.

1:45 sritchie: well you can but expect seq conversion.

1:46 sritchie: dnolen: I'll reduce across the sequence, I guess -- (reduce (fn [a b] (.concat a b)) vals)

1: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

1:52 (when using reify or deftype)

3: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

4:03 gtuckerkellogg: This seems very strange

4:03 clojurebot: No entiendo

4:04 gtuckerkellogg: ,(defrecord Rule [foo bar])

4:04 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

4:12 gtuckerkellogg: why does the map-> constructor for a defrecord abort with type hints?

4:12 http://pastebin.com/FVid7Vb5

4:14 never mind, it's because I used ^int instead of ^Integer

4:14 arggh

4:24 muhoo: so how does this cloudant thing work in the free tier? it says "development" but what do they actually mean by that?

4:25 Raynes: It means "we'd rather you give us some money"

4:28 muhoo: "rather", i can live with. "oops, you're screwed, you MUST", i cannot.

4:29 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.

4:31 Raynes: muhoo: All of those cloud database services mark their free tier as 'development'.

4:31 muhoo: fair enough, thanks.

4:32 500k requests/month, ah. still probably fine.

4:33 Raynes: What if you get slashdotted, hacker newsed, and reddited on the same day?

4:36 muhoo: what if i get hit by lightening, win the lottery, and get hit by a bus in the same day? :-)

4:36 cemerick: muhoo: I have all but one of my sites on a single cloudant free tier FWIW

4:37 muhoo: thanks

4:37 cemerick: (regularly replicated back to a local couchdb, but only because I'm paranoid)

4:37 clgv: muhoo: chances are that your home gets hit by a hurricane as well ;)

4:38 scottj: muhoo: you said 250gb. did you mean 250mb? that's what I see for free cloudant on heroku.

4:39 muhoo: ah, yes, it is MB. hmm. still, i probably won't get too close to that

4:40 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.

5:46 fliebel: Does java have any syntax like Clojure, for (import [package class class class])?

5:46 ejackson: package.* for the lazy folks

5:48 fliebel: ejackson: That's... disgusting

5:49 ejackson: glob it up baby

6:43 _andrew_k: in Java there only:

6:44 import package.Class; // import class

6:44 import package.*; // import classes from package

6:44 import static package.Class.*; // import static methods from class

6:44 import static package.Class.method; // import one static method from class

6:55 Zoka: If a jar is specified in :dev-dependencies in project.clj, should it it be avaliable in class path for "lein run" ?

7:01 ejackson: Zoka: should be

7:02 Zoka: I was using lein2 - I wil retry with 1.7

7:03 ejackson: dunno about lein2 yet

7:04 Zoka: Yes, that was it 1.7 is fine

7: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?

7:05 I can post the project tree if that helps?

7:05 raek: Somelauw: what happens if you try to run lein repl in those projects?

7:05 also, what clojure versions do they use? where do you have lein-swank, in the project.clj file or as a plugin?

7:05 Somelauw: But it would probably help more if I could get some error message

7:06 raek: Exception in thread "main" java.io.FileNotFoundException: Could not locate clojure/reflect__init.class or clojure/reflect.clj on classpath: (user.clj:1)

7:06 raek: Somelauw: was that error from clojure-jack-in or lein repl?

7:07 Somelauw: raek: in project.clj I have :dependencies [[clojure "1.2.1"]])

7:07 raek: lein repl

7:07 raek: Somelauw: do you have stuff in a user.clj file?

7:08 looks like you use features introduced in clojure 1.3 there

7:09 Somelauw: raek: yes, it includes reflect.

7:09 I will try without

7:09 bsteuber: Zoka: in lein2, the syntax for dev-dependencies is different

7:10 Somelauw: raek: thanks, it is working again

7:10 bsteuber: you write :profiles {:dev {:dependencies [..]}] now, that it'll also be in the classpath

7:10 *then

7:12 raek: Somelauw: I think clojure-jack-in errors are visible in the *Messages* or *swank* buffers

7:13 Somelauw: raek: thanks, I found the error in the old one

7:13 which was the same as lein repl

7:17 Zoka: bsteuber: do tou have a reference?

7:21 bsteuber: Zoka: this might help a bit: https://github.com/technomancy/leiningen/blob/master/sample.project.clj

7:22 also https://github.com/technomancy/leiningen/wiki/Upgrading, but there's not so much information yet

7: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

7:25 clgv: doesn't lein2 include warnings for deprecate options? if not, there should be a ticket for that ^^

7:42 Zoka: bsteuber: I got it, here it is for Google to find, thanks again for pointer:

7:42 ; :dev-dependencies equivalent for Lein 2.0

7:42 (defproject ringmon "0.1.2-SNAPSHOT"

7:42 :description "Ring handler to inject web page with nREPL front end"

7:42 :dependencies [[org.clojure/clojure "1.3.0"]

7:42 [ring/ring-core "1.0.1"]

7:42 [org.clojure/java.jmx "0.1"]

7:42 [clj-json "0.5.0"]

7:42 [org.clojure/tools.nrepl "0.2.0-beta2"]]

7:43 :dev-dependencies

7:43 [[ring/ring-jetty-adapter "1.0.1"]] ; keep this for Lein 1.7

7:43

7:43 ; lein 2.0 dev-dependencies equivalent

7:43 :profiles {:dev {:dependencies [[ring/ring-jetty-adapter "1.0.1"]]}}

7:43 clgv: Zoka: use a oaste service

7:43 Zoka: :main ringmon.server)

7:43 bsteuber: I got it, here it is for Google to find, thanks again for pointer:

7:43 ; :dev-dependencies equivalent for Lein 2.0

7:43 clgv: *paste

7:43 Zoka: (defproject ringmon "0.1.2-SNAPSHOT"

7:43 :description "Ring handler to inject web page with nREPL front end"

7:43 :dependencies [[org.clojure/clojure "1.3.0"]

7:43 [ring/ring-core "1.0.1"]

7:43 [org.clojure/java.jmx "0.1"]

7:43 [clj-json "0.5.0"]

7:43 [org.clojure/tools.nrepl "0.2.0-beta2"]]

7:43 :dev-dependencies

7:43 [[ring/ring-jetty-adapter "1.0.1"]] ; keep this for Lein 1.7

7:43

7:43 clgv: :(

7:43 Zoka: ; lein 2.0 dev-dependencies equivalent

7:43 :profiles {:dev {:dependencies [[ring/ring-jetty-adapter "1.0.1"]]}}

7:43 :main ringmon.server)

7:44 Sorry, I thought this was short enough

7:45 clgv: short enough are only oneliners ;)

7:46 Zoka: Anyway, I am very happy with lein2 - much faster

7:48 bsteuber: yes lein2 is getting great

10:58 y3di: whats up homies

11:32 unlink: What is Clojure's RAII equivalent?

11:39 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 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 *basedOn(x)

11:48 (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 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 *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 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 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 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 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 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 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 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 (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 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 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 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 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 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 .lss file :-)

13:17 * muhoo starts to think the lorites were right

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 * ejackson will be here all week folks.

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 i.e. "an integer is whatever parseInt successfully reads"

13:41 * TimMc throws an 012 after stuartsierra

13:41 * stuartsierra ducks

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:44 * TimMc reels the 012 back in

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 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 (by default)

13:52 TimMc: and then there's BigInt...

13:53 &(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 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 ,(+ 0.1 0.2)

14:00 clojurebot: 0.30000000000000004

14:01 rhc: any number with a . is a float in clojure, right?

14:01 ,(+ 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 ,(+ 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 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 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:25 * technomancy votes for amqp

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 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 how can I eval text? e.g. (eval "(+ 1 2)") -> 3, or -> (+ 1 2)

15:00 TimMc: mk: read-string, then eval

15:00 I hope that's for a config file.

15:01 mk: TimMc: reading the reference and was just wondering

15:01 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 edw: jwz

15:03 edw: D'oh. Again, last night...still recovering.

15:03 LZW, on the other hand...

15:03 rhc: TimMc: speaking of that, is it possible to quote a literal string in clojure?

15:03 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 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 its just an annoyance, but nothing major

15:08 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 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 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 you can still break it up into smaller functions

15:15 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 the side-effect is still there though

15:15 of course :-)

15:15 the right hand side of a let form shouldn't grow too large vertically

15:16 especially in clojure

15:16 where there is no grouping of names and values

15:16 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 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 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 then write a couple functions where you tie them together

15:20 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 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 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 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 pokes amalloy with a let-macro and a question

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 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 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 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 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 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 IFn f = (IFn) clojure.lang.Compiler.load(new StringReader("#(+ 1 %)"));

17:47 when run from the ubjerjar, this explodes with an NPE in

17:47 Caused by: java.lang.NullPointerException

17:47 at clojure.lang.RT.load(RT.java:424)

17:47 at clojure.lang.RT.load(RT.java:398)

17:47 at clojure.lang.RT.doInit(RT.java:434)

17:47 google doesn't seem to know about it :-(

17:47 anyone know how to work around?

17:48 (clojure 1.3.0)

17:49 seems to be under

17:49 load("clojure/core");

17:59 _andrew_k: brianm: is it full stack trace ?

18:04 brianm: _andrew_k: one sec

18:04 _andrew_k: https://gist.github.com/ace0db1c630356dda0be

18:04 line 3 is what it is trying to compile

18:05 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 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 IFn f = (IFn) clojure.lang.Compiler.load(new StringReader("#(+ 1 %)"));

18:14 _andrew_k: at clojure.lang.Compiler.<clinit>(Compiler.java:222)

18:14 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 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 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 in constructor of namespace class you are calling method from RT class

18:16 not look at bottom block

18:16 again <clinit> - it's statis code initialization of RT class

18:17 *two line before `not` -> `now`*

18:17 code in RT class passes through to method load

18:17 https://github.com/clojure/clojure/blob/clojure-1.3.0/src/jvm/clojure/lang/RT.java

18:17 NPE throws at line 424

18:18 brianm: yes

18:18 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 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 and if you can see in Compiler class

18:19 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 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 so out 233 line now not initialized yet

18:20 out -> our

18:20 brianm: static final public Var COMPILE_FILES = Var.intern(Namespace.findOrCreate(Symbol.intern("clojure.core")),

18:20 Symbol.intern("*compile-files*"), Boolean.FALSE).setDynamic();

18:20 should not

18:21 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 ah

18:23 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 * _andrew_k so many typos ;( time for sleep

18:25 matt444: pyninja: gotcha, thanks a lot

18:25 brianm: _andrew_k: thanks for help!

18:26 _andrew_k: explicity just called RT.init() ahead

18:26 worked a charm

18:26 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 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 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 Or the arg function's arg function?

19:14 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 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 s/input/output

19:30 dnolen: matt444: we're working on it

19:31 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 I see that clojure.java.io/Coercions protocol does have return type hints

19:35 but they seem to be using fully-qualified class names

19:35 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 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 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 * emezeske is thinking about how to debug this.

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 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 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 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 right

19:58 emezeske: xterm+tmux > *

19:58 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 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 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 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 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 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 ok, looks like I'll have to use into-array

20:24 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 dnolen: And then edit lein-cljsbuild/support/project.clj to point at that local version

20:29 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 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 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 right?

20:42 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 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 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 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 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 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 (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 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 ,(-> "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 CompilerException java.lang.RuntimeException: No such namespace: js, compiling:(NO_SOURCE_PATH:1)

21:33 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 yes, I did

21:35 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 that's not in the guide

21:35 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 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 https://github.com/brentonashworth/one/wiki/Getting-started

21:38 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 I'm just trying to start the repl and (js/alert)

21:41 basically just try to make the sample app work

21:41 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 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 oh!

21:45 got it

21:45 damn, that's not obvious

21:45 it doens't work if I have a clojurescript repl running

21:45 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 I've been working on this for half an hour

21:46 so confused

21:46 thank you for your help mindbender1!

21:46 mindbender1: you will be cleared in a short while

21:46 you welcome

21:47 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 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 yeah

21:48 it makes sense now

22:29 mk: are structmaps totally deprecated?

22:46 qbg: mk: Not too much reason to use them

22:53 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 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 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:14 * emezeske seconds technomancy's notion: just use a map.

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?

Logging service provided by n01se.net