#clojure logs

2012-05-18

00:00fil512it kinda feels like you have to be above-average smart to develope in it, and it's easy to write code that's hard to understand...
00:00PeregrinePDXI don't think I am above average smart for a programmer.
00:00PeregrinePDXI'm also pretty new to clojure and it takes me awhile but I can figure out a lot of clojure.
00:01ivan__fil512: i think you have to be open minded more than smart - so many developers never seem to want to try anything new
00:01fil512I want to have the confidence that anyone from any team could walk up to the clojure code and understand what it's doing. but I worry this is not the case with clojure the way it is with more structured languages like java
00:02fil512I work on million dollar software projects. Our code has to be maintainable.
00:02fil512I'm always keeping an eye out for the next big thing.
00:02fil512Clojure is a candidate right now.
00:03fil512But is it a "business grade" programming language.
00:03fil512That's what I'm trying to figure out...
00:03ivan__fil512: should watch the infoq presentation the guardian did on there move to scala - its maybe not directly related to clojure but it was interesting about java guys trying something new
00:04fil512I've heard disastrous things about scala. Definitely not an option for us.
00:04fil512My impression of scala is some guy got impatient with java not having all the stuff he wanted in a language and so he invented a way to extend java so he could put all that cool stuff in...
00:04ivan__haha i dont think thats true at all
00:05fil512clojure feels orders of magnitude better thought out than scala
00:05fil512variable immutability as a way to deal with multi-core
00:05fil512super-clean kernel
00:06fil512when the robot overlords take over the world, they will code in clojure
00:06brehautimmutable data is a way to deal with reason in general. multi-core happens to fall out of that
00:06brehautbut its far more valuable than just that
00:06ivan__clojure is nice - but scala has its good points to. One of them is that its easy for java guys to get started
00:07eggsbyya ivan__
00:07fil512C# is easy for Java guys to learn too. That's not a criteria for me.
00:07eggsbywe have a lot of scala guys at work, only a few clj
00:07ivan__yeah, immutable data is the way to go - scala provides nice things for that too
00:07fil512been good chatting
00:07fil512gtg
00:07fil512thanks for the help!
00:08ivan__seeya
00:08ivan__idk, im all for clojure - but if you have 120 guys that dont know it, but know java - it seems like it would be a big deal to move to it heh
00:08eggsbyI think the biggest practical difference between clojure and scala, while both can mostly implement the features of the other without too much pain, if you switch from java to scala you don't need to learn anything, just a bit of syntax
00:09mtkoanI shudder at the thought of 120 programmers
00:09eggsbybut if you switch to clojure, you'll have to completely change how you think about writing programs
00:09eggsbyi.e. you can have 10 years of java experience and pick up scala in a few days, clojure would probably take a few weeks/months if you haven't had prior FP experience
00:09ivan__there arent many scala guys at work (and no clojure), but i can get away with using scala as long as I keep it nice and clean and dont try and do stuopid stuff with type system - java guys can read the code
00:10eggsbyif you are using groovy you could probably switch to scala without people really noticing :p
00:10ivan__eggsby: yeah - for me I started by writting scala in a very java way, over time i learnt how to work with immutable data, fp stuff etc
00:11ivan__not that i want to rant on about scala in #clojure haha - but i was just finding it wierd the objections that guy has to it
00:11eggsbyI liked fogus' talk about macros, where he implemented BASIC as a DSL in scala, then showed how because it didn't have macros parts of the language peeked through in the implementation
00:12ivan__this was before 2.10?
00:12ivan__(2.10 has macros)
00:13ivan__macros in scala dont make a lot of sense to me yet - ive seen one example but i understood the use in clojure a lot easier
00:13eggsbyah, must've been
00:13eggsbybut ya lol @ scala not being enterprise grade, hi twitter
00:14eggsbyONE MILLION DOLLARS
00:14eggsby:)
00:14ivan__The Guardian... they started out by using scala for doing the java test code - to make it interesting
00:14ivan__would be cool if i could do the same thing with clojure
00:15eggsbyClojure has been an enlightening experience. Kind of a lesson in the power of abstractions
00:16eggsbyI've been making the finishing touches to a system I built for work in clojure, the architecture from it was lifted from ring's middleware implementation, seemed like a good way to model transformations over data... then I ran into this article today: stuartsierra.com/2012/05/16/syntactic-pipelines
00:16eggsbyI had a lot of the same problems, repeated logic deep inside function bodies, seeing that repetition just plucked away with macros is so beautiful
00:17eggsbyI guess any language with metaprogramming capabilities can make something like that happen, but it just seems so elegant/general in clj/lisp
02:09RaynesPeople should be talking in this channel.
02:10PeregrinePDXSorry I was reading Clojure Programming
02:14PeregrinePDXI suppose I could put my random thoughts regarding learning clojure in here rather then in a PM window to someone I know.
02:14PeregrinePDXBut really I don't know that people are that interested that I find the existance of empty as a pleasant surprise.
02:20PeregrinePDXAlthough my cat seems to think learning clojure is a poor choice of my time and it would be better spent petting her.
02:21RaynesPeregrinePDX: It is late enough and quiet enough that your random thoughts should be socially acceptable.
02:21RaynesAnd if they serve to keep me entertained, rest assured that I will hold off the beasts.
02:43PeregrinePDXOh I like the existance of transients although I imagin some people prematurely optimize things by using them too much.
02:50amalloyPeregrinePDX: i don't think that happens very often
02:51amalloyclojure is very...firm on the topic of immutability, and nobody uses transients just for fun. records, now...those get used prematurely all the time
02:51PeregrinePDXThen clojure programmers are far more disciplined then some of my former coworkers.
02:52amalloyas a nice aside, i (and probably you) often write code that benefits from transients without having to think about it: ##(doc into) uses a transient under the hood
02:52lazybot⇒ "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."
02:52PeregrinePDXYeah, the clojure programming book I am reading was explaining that about into.
03:02aperiodicspeaking of records, i have a thing (bezier curve) that i want to be able to use like a map is basically every way besides when it's invoked
03:02aperiodicwhat's the easiest way to do that?
03:03aperiodics/is basically/in basically/
03:20amalloyaperiodic: maybe (defrecord Bezier [] clojure.lang.IFn (invoke [this arg] ...))?
03:30kralnamaste
03:33aperiodicamalloy: is that sufficient? i remember hearing something about a gotcha if you don't implement all the arities for invoke in BG's clojure/west talk, but it might've been minor
03:33amalloyi guess you probably also have to implement applyTo
03:36aperiodici should really get in the habit of checking clojure's source
03:38amalloygood habit to have
03:41aperiodicyeah, i'm just a little irrationally reluctant about reading java, and the style will probably take me a little getting used to
05:50xumingmingvcan some one explain this: http://stackoverflow.com/questions/4921566/clojure-returning-a-vector-from-an-anonymous-function
05:50xumingmingv(explain the accepted answer)
05:50xumingmingvi know list is function call
05:51xumingmingvvector is also function call?
05:52babilen&([1 2 3] 0)
05:52lazybot⇒ 1
05:52Borkdudexumingmingv: ##([1 2 3]) ;; calling a vector from function position with no args
05:52lazybotclojure.lang.ArityException: Wrong number of args (0) passed to: PersistentVector
05:52Borkdudexumingmingv: ##(vector 1 2 3) ;; calling the vector "function" to construct a vector
05:52lazybot⇒ [1 2 3]
05:52babilenxumingmingv: You can use (vector index) to get an element at the given index
05:54xumingmingvah, ok, i got it
05:54xumingmingvdo you guys feels it confusing?
05:55Borkdudexumingmingv: anonymous function with #-notation tricked me before as well
05:55babilenNot much -- The same works with maps (i.e. ##({:a 1} :a} == (get {:a 1} :a)
05:55Borkdudexumingmingv: ,((fn [] [1 2 3]))
05:55Borkdudexumingmingv: ##((fn [] [1 2 3]))
05:55lazybot⇒ [1 2 3]
05:56Borkdudexumingmingv: with this notation #( … how to return a vector directly? I think you can't )
05:57Borkdudexumingmingv: a literal that is. by calling the vector "fn" you can
05:57Borkdude,(#(vector 1 2 3))
05:57clojurebot[1 2 3]
05:59xumingmingvthanks you guys, Borkdude babilen
06:00Borkdudewow this is ugly… ##(+ 1 2 3 nil)
06:00lazybotjava.lang.NullPointerException
06:03myarrayplease, can anyone explain, what is the motivation of max-key / min-key functions in returning the *last* match instead of first?
06:03myarray(apply max-key count [[1 2] [3 4] [5] [6 7] [8]])
06:04Borkdude,(doc max-key)
06:04clojurebot"([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest."
06:04Borkdudemyarray: it probably uses reduce
06:05Borkdudemyarray: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L4419
06:06RaynesWell, it has too...
06:06RaynesI mean, if you want a sane algorithm.
06:06BorkdudeRaynes: yes
06:06RaynesIt has to go through all of them to know what the greatest is, so it makes sense for it to return the last greatest it finds.
06:07RaynesThough it could return the first it finds.
06:08BorkdudeRaynes: or all the maxima
06:09Borkdude(what is the plural of maximum in English? maximums?)
06:10Raynes&(apply (fn [k & xs] (reduce #(if (> (k %2) (k %)) %2 %) xs)) count [[1 2] [3 4] [5] [6 7] [8]])
06:10lazybot⇒ [1 2]
06:11Raynesmyarray: ^
06:11RaynesIf you need that behavior.
06:17BorkdudeRaynes: sleep well
06:17BorkdudeTEttinger: did you see my refactoring yesterday of your function?
06:19myarray&(apply max-key count [[1 2] [3 4] [5] [6 7] [8]])
06:19lazybot⇒ [6 7]
06:19myarrayit returns the last matching element
06:20myarrayimho its not very intuitive
06:20Borkdudemyarray: it is because it has to traverse all of the collection
06:20myarrayshould be [1 2]. I am curious why it is so, what is the idea behind returning the last
06:21Borkdudemyarray: see the source https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L4419
06:21Borkdudemyarray: if you want it the other way, use Raynes his variation
06:21myarrayno its not. Well, it does have to traverse, but it can keep the already found max value if it has found the same max value
06:21Borkdudemyarray: this is what Raynes his version does
06:23myarrayMy question is not "how to". My question is why it does it, what is the motivation?
06:24myarrayother FP languages that have max-key like functions return the first match if there are few equal max values
06:24myarrayis it some kind of Lisp behavior legacy?
06:25Borkdudemyarray: I think with these kinds of functions you should not depend on order anyway, so what's the big deal?
06:26Borkdudemyarray: it's just a choice. the version in core is a short elegant version, which produces a valid result
06:26myarrayThere is only one character in max-key function that should be changed in order to get the intuitive behavior.
06:27TEttingerBorkdude, yes! thanks for that.
06:27babilenI don;t necessarily find that behaviour to be more intuitive. max-key makes no promises regarding the order.
06:29myarraywell, may be it should :-)
06:29myarrayconsider a solution for this task http://www.4clojure.com/problem/53
06:29Borkdudemyarray: you mean replace > with >= ?
06:30myarrayone of them would be building a sequence of all possible seqs and then getting the first max
06:31myarrayotherwise, you have to "reverse" it before. But returning the first "winner of the hill" seems to be more intuitive to me
06:31myarrayBorkdude: yes
06:31TEttingerBorkdude, just so you know, it won't compile as-is
06:31myarrayBorkdude: or swapping left and right args
06:33myarrayBorkdude: it depends on reduce1 which private, if you are trying to make a copy of max-key in your own ns, you should have your reduce1 as well
06:35BorkdudeTEttinger: ah yes, you have to reverse the order of the function definitions
06:36TEttingerBorkdude, yeah, all it took was that, and changing a call to left? to left-col?
06:39BorkdudeTEttinger: ok changed it
06:39BorkdudeTEttinger: I think the algorithm can be much simpler though ;-)
06:39TEttingerthanks, yeah
06:40TEttingerhow do you think it would, though?
06:41TEttingeroh. i think i have a bug already
06:41TEttinger(path-in-matrix 0 11) will walk over a corner, which it isn't supposed to do
06:42BorkdudeTEttinger: I don't know what your algorithm is supposed to do exactly
06:42TEttingeryeah, it is meant to be a highlighter for a 1D-imitating-2D vector
06:43TEttingerso it should highlight the line between a starting corner square and a target square
06:43BorkdudeTEttinger: it should walk also in diagonals or smth?
06:43BorkdudeTEttinger: so the shortest path?
06:43TEttingeri could use bresenham, but for some reason i thought making one turn would look better to the user (which is a goal in this)
06:44TEttingerand with orthogonal-only movement, it currently does highlight the shortest line, except when it walks over corners
06:44BorkdudeTEttinger: good luck, the only thing I wanted to point out is that making a giant function into more smaller functions is easier to test =)
06:44TEttingerah ok
06:45TEttingeri will look into how to implement bresenham's line algorithm in clojure, i think it isn't very complex
06:48mduerksenmyarray: i think the preference of max-key is more intuitive the way its implemented now: left-to-right, just like e.g. merge. but intuition aside (which may vary), it should be explicitely written in the doc.
06:53hyPiRionWould jumping directly over Leiningen 1.x to Leiningen 2 be smart? I haven't used any, and I'm going to port a 1.2 project over to 1.4.
06:53Borkdudehaha
06:54Borkdudetechnomancy: http://twitpic.com/9mc9aw ;-)
06:54hyPiRionBorkdude: yeah, I noticed as well. :p
07:00hyPiRionWell, I cannot see why it shouldn't be smart.
07:02xumingmingva silly question
07:02xumingmingvwe know that we use ; for comments in clojure
07:02xumingmingvwhy most clojure code use ;; ...
07:02xumingmingvdouble ;
07:03ejacksonhaha, I guess due to // from java
07:04ejacksonand still having ; mean line end, so not wanting to put it at the front of a line :)
07:04hyPiRionLisp convention. ; is for comments in code, ;; is for comments before/after code
07:04ejacksonwell that makes more sense !
07:05xumingmingvafter code?
07:06hyPiRionAs in, after the closing paren of an expression. E.g. after a defn.
07:29TEttingergah, why is there no floor function? org.clojure/math.numeric-tower has some issue that prevents floor from working
07:31TEttingerhttp://pastebin.com/Ha8vkKsS my lengthy error
07:31BorkdudeTEttinger: ##(int 3.567) ?
07:31lazybot⇒ 3
07:31TEttinger,(int 15/2)
07:31clojurebot7
07:31TEttingeroh ok
07:31TEttingerthanks
07:34Borkdude,(* (int 3.5) 2.3)
07:34clojurebot6.8999999999999995
07:37babilenTEttinger: ##(Math/floor 42.23)
07:37lazybot⇒ 42.0
08:16Borkdudesometimes I wonder about clojuredocs, if I search for "def", why doesn't "def" turn up.. http://clojuredocs.org/search?x=0&y=0&q=def
08:19foxdonutBorkdude: strange indeed.. it shows up in the autocomplete but not in the search results :/
08:20Borkdudefoxdonut: I have had this with other searches as well
08:21Borkdudefoxdonut: also the autocomplete representation is broken in Chrome on my system
08:22foxdonutBorkdude: works on Chrome/Ubuntu and Chrome/Mac.. what are you on?
08:23Borkdudefoxdonut: Chrome / OSX
08:23Borkdudefoxdonut: http://twitpic.com/9md5xd <-- I get this
08:24Borkdudefoxdonut: try typing a "d", let the autocomplete come up and then press "e"
08:24foxdonutBorkdude: huh. that's whacked.
08:25Borkdudefoxdonut: you don't get this?
08:25foxdonutBorkdude: I don't get any truncated autocomplete, but doing the d-then-e thing makes 'def' not show up.
08:26Borkdudefoxdonut: with me the autocomplete results get positioned over the search box
08:51solussd_Could anyone tell me why this won't compile (I get a java.lang.InstantiationException when it tries to compile the macrolet form): https://www.refheap.com/paste/4fb64515e4b0225aed0333ec
09:01hyPiRionsolussd_: I don't know why, but I would've tried to get rid of that macro: https://www.refheap.com/paste/4fb647aae4b0225aed0333ed
09:03hyPiRionI screwed up the indentation, but the idea is that if you're able to make a macro into a function by using apply, then do that istead.
09:04neotyksolussd_: where did you get macrolet from, I want one as well
09:06TimMcfoxdonut: The autocomplete and search results most notably differ on things with hyphens.
09:06solussd_macrolet is in clojure.tools.macro
09:07solussd_hyPiRion: I cant use apply-- the args list is conditional on the args, and simply building the arg list and then applying the command is no better than the macro. I like macrolet. :)
09:08solussd_I'm concerned about what looks like perfectly valid code not compiling.. :/
09:14foxdonutTimMc: ic
09:15mmarczyksolussd_: actually the expansion seems to depend on the runtime values of dest-name and submodule-recursive -- so, not valid code at all
09:15mmarczyksolussd: ^
09:16mmarczyksolussd: CLHS says "the consequences are undefined if the local macro definitions reference any local variable or function bindings that are visible in that lexical environment" (i.e. the lexical environment where the macrolet form appears) http://www.lispworks.com/documentation/HyperSpec/Body/s_flet_.htm -- that applies to CL, but I'd expect the same from tools.macro
09:25goodieboyI'm having the problem described here: http://stackoverflow.com/questions/10289617/clojure-ring-jetty-i-am-using-lein-ring-server-how-do-i-configure-the-jetty
09:26goodieboyI have to keep using "lein ring server", so somehow I need to configure jetty within my project.clj -- I tried the example in that ^^ link, but nothing is working
09:27goodieboyanyone know how to deal with this -- summary: In development mode, jetty is giving me a "FULL HEAD" response
09:27mmarczykgoodieboy: http://stackoverflow.com/questions/9285096/clojure-ring-using-the-ring-jetty-adapter-large-requests-give-me-a-413-full-h/9286288#9286288
09:28goodieboymmarczyk: thanks! I'll give that a shot.
09:28weavejestergoodieboy: If you specify the configurator as a symbol, that might work.
09:29weavejestergoodieboy: e.g. {:ring {:adapter {:configurator some.config/foo}}}
09:29goodieboyweavejester: ahh, ok
09:29mmarczykI'd still expect unquote to be necessary
09:30mmarczykbut if it isn't, I'll be interested to learn that :-)
09:30weavejestermmarczyk: I believe the adapter arguments are passed as-is to eval-in-project
09:31weavejesterSo in theory they should be evaluated.
09:32mmarczykweavejester: ah, then it shouldn't matter, fns are self-evaluating currently
09:33weavejestermmarczyk: Yes… an anonymous function should work in theory...
09:33michaelr525weavejester: hi
09:34michaelr525weavejester: i don't want to bother you with this, but can you tell me whether you've seen my comment here: https://github.com/weavejester/lein-ring/issues/10
09:35goodieboyweavejester mmarczyk: hmm, i can't get it to work. Using :ring {:adapter {:configurator app/configure etc.. doesn't ever execute my function
09:35weavejestergoodieboy: Which version are you using?
09:35goodieboyweavejester: of lein-ring?
09:35weavejestergoodieboy: Yep
09:35goodieboyweavejester: 0.7.0
09:35weavejestermichaelr525: I have, but haven't had time to look into it.
09:37michaelr525weavejester: ok, thanks.. i intent to tackle this problem myself sooner or later anyways, thought maybe you have an idea what could it be
09:37weavejestermichaelr525: No idea, since I wasn't able to reproduce the original issue. Which version of Tomcat are you using, btw?
09:38michaelr5257.0.21
09:39weavejestergoodieboy: Hm, not sure why that wouldn't be working, but I haven't tested using configurator with lein-ring before
09:40goodieboyweavejester: ok. Using ~(prn "configure!") does work, but I guess that doesn't really mean that lein-ring is doing anything with the :configurator value, just that the prn is getting evaluated immediately right?
09:41goodieboylike this: {:ring {:adapter {:configurable ~(prn "configure!")}}}
09:42weavejestergoodieboy: This might need a patch for it to work
09:43goodieboyweavejester: if you could point me in the right direction, i could attempt doing this if you'd like
09:44weavejestergoodieboy: I'm afraid the only direction I can point you in is the lein-ring source code
09:44goodieboyweavejester: gotcha ok, checking that out now
09:45weavejestergoodieboy: Out of interest, why are your headers so big?
09:46goodieboyweavejester: we store a lot of data in cookies, i'm assuming that's it?
09:46weavejestergoodieboy: That's probably it.
09:52solussdmmarczyk: thanks!
10:06goodieboyweavejester: is this function called somewhere when running "lein ring server" ?
10:06goodieboyhttps://github.com/weavejester/ring-server/blob/master/src/ring/server/standalone.clj#L56
10:07goodieboyit looks like lein-ring recognizes :adapter here: https://github.com/weavejester/lein-ring/blob/master/src/leiningen/ring/server.clj#L27
10:08goodieboysorry wrong link, ring-jett-adapter: https://github.com/mmcgrana/ring/blob/master/ring-jetty-adapter/src/ring/adapter/jetty.clj#L61
10:09goodieboyanyway, that config setting is getting lost somewhere along the way
10:10jsabeaudry_Is there any point to doing @(future (dostuff)) instead of (dostuff)?
10:14rhcjsabeaudry_: not that i can see, just extra overhead
10:15jsabeaudry_rhc, thanks for the confirmation, that was my impression too
10:19gfredericks(-> (dostuff) future deref future deref future deref future deref) ;; make sure
10:24pjstadiggfredericks: needs syntax shorthand like caadar
10:29jsabeaudry_hehhehe
10:34gfredericksgoogling caadar tells me nothing. This is some mashup of car and cdr?
10:34gfredericks(def caadar (comp first first rest first))?
10:34jweissI think it's (car (car (cdr (car x))))
10:34jweissor maybe i got that backwards
10:35gfrederickslisp complects forwards with backwards
10:36pjstadigcommon lisp lets you use any combination of a's and d's between the c and r
10:36gfredericksO_O
10:36gfrederickswtf.
10:36pjstadigand it just becomes the composition of all the cars and cdrs
10:36jweisspjstadig: you mean, even caaadadaddaddadaddddddaaaar ?
10:36gfredericksso you can't name anything #"c[ad]+r" because it will be misinterpreted?
10:36pjstadigsure i think so, i'm not sure if there is some theoretical or practical limit
10:37llasramIs that really true? In /LoL/, one of the things the author does is define a macro w/in which one can use any #"c[ad]+r"
10:37llasramWouldn't think he'd need to do that if support already existed, but I don't know my CL v well..
10:37pjstadigto the hyperspec!
10:38pjstadighttp://www.lispworks.com/documentation/HyperSpec/Body/f_car_c.htm#car
10:38pjstadiglooks like only up to four compositions of car and cdr
10:38gfredericks#"c[ad]{1,4}r"
10:38jweissi have some data. most of the data is fixed, iow, always evaluates to the same thing. pieces of it are not - for instance it evaluates to a timestamped string. so far i've been enclosing this literal in (fn [] ...) so that i can call the fn and get a "new" piece of data each time. but that creates an awful lot of functions to compile. i'm wondering if i can implement this where the data is consumed, maybe with protocols.
10:38llasramThat seems... er, sensible?
10:39hyPiRionpjstadig: There's a practical limit. Most of the common lisp implementations is limited at around 4 or 5.
10:39hyPiRionThough that being said, nothing limits implementators to have more.
10:39gfredericksreminds me of the generated IFn primitive interfaces or whatever that was
10:41llasramOh yeah. Those make me slightly sad every time I think about them. But generating them dynamically seems pretty fraught with peril
10:43llasramjweiss: Like have an object which represents "the time at which you examine the object"?
10:43misislavskineotyk: with today's bleeding edge cljs, I'm seeing Unaught Error on robots discussed here about a month ago / CLJS-35. Do you know a workaround?
10:44jweissllasram: yeah, but i don't see how i can do it. some of the data need to refer to the same timestamped string.
10:45llasramjweiss: Yeah, I was thinking that would make it kind of problematic... What's the down-side of having a function generate the data? Do you have a v large number of these functions being dynamically `eval`ed or such?
10:46jweissllasram: as i add more data i'm adding more functions that need compiling, doesn't seem very scalable. functions seem a little heavyweight here
10:48ibdknoxHey folks
10:48Borkdudehi ibdknox
10:48llasramjweiss: So really your data are essentially templates? And you need something to generate the actual data from the templates? (thinking out loud)
10:48ibdknoxI have an exciting announcement :) Light Table was accepted late to YC
10:49llasramibdknox: Congratulations! And since I haven't been on #clojure since the Kickstarter project got funded, congratulations on that too!
10:49jweissllasram: yeah, when you put it that way, sounds like we're talking about macros
10:49ibdknoxcan a couple people help me spread the word: http://news.ycombinator.com/newest
10:50timvisherhey all
10:50ibdknoxIt's important that people know circumstances have changed :)
10:50ibdknoxllasram: thanks!
10:50timvisherhow would you go about converting an io/input-stream into a byte[]?
10:50llasramjweiss: Wellll. Not necessarily. That might be an easy way to implement things at first, but still locks your data into executable code. I don't know -- it probably depends on the details of the data
10:50raektimvisher: use the read method of the InputStream class
10:51TimMcByteArrayOutputStream + a pumper?
10:52raek(.read input-stream buffer)
10:52timvisherraek: recursively, i suppose?
10:52timvisheri'm trying to understand how I would terminate
10:52timvisherah yes
10:52timvisherwhile
10:52jweissllasram: have stuff like (fn [] {:a (unique-name "joe")}) which produces a different value each time. but then sometimes i need to refer to the same thing twice: (let [x {:a (unique-name "foo")}] (dothing x))
10:52raektimvisher: how much data do you need to read each time?
10:53timvisherfew megabytes
10:53timvisheror less
10:53jweisssorry llasram forgot to add (dootherthing x) :)
10:53raekdo you need to fill the buffer completely, or do you just want to read what's available?
10:53timvisheronly what's available
10:53gfredericksif he wants a byte[] doesn't he have to read everything first?
10:53Borkdudeibdknox: can I ask a dumb question, does this mean you don't need the kickstarter money anymore?
10:53raektimvisher: how are you using the byte-array?
10:53timvisheri'm trying to read a file from the web once, then turn it into both a bufferedimage as well as an md5 hash
10:54gfredericksibdknox: I can take the kickstarter money if you don't need it
10:54gfredericksI don't mind
10:54llasramjweiss: What's the data ultimately being used for?
10:54timvisheri don't believe i can use just the stream anymore because one or the other would consume it
10:54raektimvisher: if you want to put all the bytes into an output-stream, use clojure.java.io/copy
10:54timvisherso my thought is to read it once an then use it both places
10:54ibdknoxBorkdude: it's still very useful, but it is not *needed*. The project is safe. That's why I'm letting people know it's ok if for them that means they no longer feel the need to pledge
10:54raekah
10:54jweissllasram: functional tests. the reason i need unique values, is so I can run the same test twice, and the data being used doesn't collide with data that's already in the system under test.
10:55timvisherand i don't think it'll be possible for me to download the data twice, especially in quick succession
10:55Borkdudeibdknox: what happens if people take their pledge back and the sum gets below 200k?
10:55timvisherif that were possible then i could probably just stick with opening 2 streams
10:55goodieboyanyone know if it's possible to add repositories for "lein plugin install xxx" ?
10:55raekI would repeatedly fill the buffer (say 2048 bytes) using the read method and give the array (and size) to the two sinks that need it
10:56ibdknoxBorkdude: then the project isn't funded and no money transfers
10:57Borkdudeibdknox: so what about Python support now, already safe as well?
10:57raekso something like (loop [] (let [n (.read input-stream buffer)] (when-not (neg? n) (... buffer ... n ...) (recur)))
10:57ibdknoxBorkdude: That I'm not sure about
10:57timvisherseems reasonable
10:57llasramjweiss: Ah, so generated text fixtures? Functions actually seems a perfectly sensible way to go. Esp if you're ultimately just generating Clojure data-structures. You can compose them, refer to the same generated value multiple times... They seem pretty much perfect
10:57Borkdudeibdknox: and how about licensing? or will it be free?
10:58llasramjweiss: I guess I'm not seeing the scalability problem, unless you're creating 100ks of them?
10:59ibdknoxBorkdude: if the KS fails a few of the details around that might change, I'm not sure. In the long run maybe it isn't worth charging for the distributions
10:59cmiles74Has anyone see a Clojure library for working with Hazelcast? I don't want to reinvent the wheel.
10:59jsabeaudry_When lein uberjar fails with a compilaiton error, it seems like I'm still in the process, is there a way to tell it to retry without C-c'ing it and restarting it?
10:59Borkdudeibdknox: anyway, congrats!
11:00jweissllasram: i'm not sure it's a problem, just thought there might be another way. i'm ok with leaving it as is, just sometimes gets confusing as to exactly when something gets evaluated, because as i compose data, each level needs to be wrapped in a function. and then of course i need a construct to explicitly call it.
11:01jweissllasram: seems like lisp's quote/unquote constructs kind of do the same thing
11:03llasramjweiss: Do you have an example of where it gets confusing? The version I have in my head of just normal functions returning and composing normal data-structures seems fairly straightforward to me
11:04Borkdudeibdknox: I don'tknow the details of ycombinator's process, but I read they invest 18k and you get to be three months over there.. isn't 200k better?
11:04solussddependency question: I'm using a version of (lein-marginalia dev-dependency) marginalia in my project that itself depends on hiccup 0.3.7 (in this version escape-html is in hiccup.core), in my project I use hiccup 1.0.x. Running marginalia (lein marg) results in an exception complaining about not being able to find escape-html. it seems that marginalia is using hiccup 1.0, even though it has a dependency on hiccup 0.3.7. How do I get it to us
11:04solussdthe older hiccup while continuing to use hiccup 1.0 in my project?
11:04ibdknoxBorkdude: there's another guaranteed 150k as well. But the value of YC isn't the money, it's the guidance, the name, and the network.
11:04jweissllasram: https://github.com/weissjeffm/katello.auto/blob/master/src/katello/tests/permissions.clj#L97
11:05ibdknoxBorkdude: those things in combination are worth untold sums of money
11:05Borkdudeibdknox: I guess Arc support is now closer than Python ;-P
11:05ibdknoxlol
11:06ibdknoxBorkdude: certainly not :p
11:07llasramjweiss: Ahhhhh. Why the nested functions? Are those actually intended to be functions in the "final" data-structure, or are they evaluated before being used as fixtures?
11:09jweissllasram: well, the outer fn's need to be functions because of data like starting line 97. and the inner ones often need to be functions too, because of line 122
11:09jweissso the test harness needs to either take maps or functions. at both levels it has to take functions
11:10jweissactually the inner fn's have to be fn's no matter waht
11:11jweissbut they can't be partials, they really have to be fn's
11:11llasramjweiss: The code ultimately under test consumes functions, or the existing test harness needs them to be functions?
11:12timvisheris it possible to clear the slime repl buffer?
11:12jweissllasram: the harness is my code too, so it's not required in that sense.
11:13jweisstimvisher: M-x slime-repl-clear-buffer
11:13llasramtimvisher: which is bound to C-c M-o by default
11:13jweissllasram: i guess there's no getting around things needing to be evaluated at runtime.
11:14llasramThough of course thinking about bindings always makes me unable to correctly apply them...
11:14misislavskiIs anybody else having problems with the Uncaught error with robots.txt from clojurescript master?
11:14misislavskiI can't get my browser to connect to the repl.
11:14timvisherjweiss, llasram: very cool
11:14misislavskiboth chrome and ff throw: "Uncaught Error: URI file:/robots.txt is invalid for field ppu"
11:14llasramjweiss: Right. I think the part I'm questioning is the function nesting. It seems like the whole system would be really straightforward if you ultimately just have functions which produce fully evaluated datastructures
11:15llasramjweiss: You could compose those functions by having higher-level functions call lower-level ones, just like in normal code
11:15foxdonutwho wants to be Light Table backer #5000 ?
11:17jweissllasram: that's what it's doing. the inner fn's i have no choice - they really are functions no matter what, even if there's no
11:17jweissu
11:17jweissunique data in them
11:17jweissthe test is "assign this user these permissions, then as that user, run these functions"
11:18jweissso the test is sort of a HOF
11:18TimMcfoxdonut: 4,998 backers now.
11:19foxdonutTimMc: yeah saw that, didn't know you could back out of being a backer!
11:20TimMcThat's what ibdknox was saying in his post, though: You can back out now, it's OK. There's guaranteed funding.
11:20TimMcI'm keeping mine in. It's still an investment.
11:21llasramjweiss: Oh, ok. Well. Seems good as-is to me then :-) Or at least, I can't contribute any ideas as to how it could be simpler
11:21llasramjweiss: It's an interesting problem though -- curious to find out if you settle on some other way of doing it
11:22jweissllasram: certainly seems possible to me that there is no better way, but i'm not totally convinced of that yet :) i'll let you know if i find anything
11:22jweissthanks for your time
11:23foxdonutTimMc: what does this YC thing imply? and why might one not be a backer anymore because of it?
11:23gfredericks&(->> [oh boy] quote cycle (take 10))
11:23lazybot⇒ (oh boy oh boy oh boy oh boy oh boy)
11:23pbostromKS backers still get early access I believe
11:23gtrak`ibdknox: congrats
11:24ibdknoxgtrak`: thanks! :)
11:24gtrak`I'd like to do some cool startup one of these days, too :-), sounds exciting
11:25ibdknoxfoxdonut: the main thing is that before people threw in money to ensure that the project had a chance, now it does, so the circumstances under which that "investment" was made have changed.
11:25ibdknoxfoxdonut: ultimately getting YC is a very, very good thing for the project
11:25TimMcfoxdonut: I know nothing about YC. :-P
11:25pbostromibdknox: just curious, did you approach YC, or did they come after you?
11:25jweissi'm a little confused, KS and YC seem totally different. i thought KS was "if you really want this thing built, contribute so you can get it". and then for all the developer might care, everyone else can get it for free. YC doesn't seem like they would want anyone getting it for free.
11:25llasramibdknox: OOC, was the successful Kickstarter effort a factor in getting YC?
11:26foxdonutibdknox: thanks for the explanation. my contrib remains, for sure.
11:26ibdknoxpbostrom: we applied, though the whole thing was very interesting. we'll probably blog about it at some point
11:26ibdknoxllasram: definitely. Half the partners had actually contributed :)
11:27ibdknoxjweiss: there's tons of potential for a business even if the platform is open source :)
11:28rkzibdknox: was the interview intense or were they sold before you even walked in? did they ask you how you were going to make money?
11:28`fogusibdknox: We?
11:28ibdknoxrkz: it was rough as hell
11:28ibdknox`fogus: best friend from high school (ibdthor) :)
11:29`fogusibdknox: Congratulations to both of you. Huge news!
11:29ibdknoxrkz: they really laid into us, I found out later that was because they really liked us, but boy it didn't seem like it when we walked out of that room
11:30rkzibdknox: i had an interview too, one of the most intense things I've ever done in my life
11:30rkzthis was when all the partners were in the same room
11:31rkzso it was like 11 people
11:31rkzgrilling 3 of us
11:31rkzquestions from all directions
11:31TimMcHow does YC work? They invest money and get partial ownership?
11:32TimMcIs it a loan?
11:32rkzno, cash
11:32mmarczykibdknox: wow, congrats!!! :-)
11:32rkzfor 5-7 %
11:32ejacksonam i reading this correctly - KS got YC !
11:33TimMcyes
11:33TimMcAll of the acronyms!
11:33ejacksonBRILLIANT !
11:33ejacksons/KS/LT/
11:33ejacksonof course :)
11:34TimMcThat too.
11:34foxdonutVFC!
11:34ibdknoxmmarczyk: thanks :)
11:34TimMcLT's KS probably helped them get VC from YC.
11:34ejacksonOK
11:34TimMc:-D
11:34foxdonutIIRC RTFM OMG WTF BBQ
11:34RickInGAibdknox: congrats!
11:35ejacksoni hope this doesn't mean Clojure loses one if its most prolific project contributors
11:35ejacksonbut am thrilled nevertheless
11:35TimMcfoxdonut: No, only DAs. (Dyadic Acronyms)
11:36TimMcejackson: Eh, we'll get spinoffs.
11:37foxdonutTimMc: so no TLA then, huh
11:37TimMcright
11:38Borkdudeibdknox: maybe you should explain now what happens to the "reward structure"
11:38foxdonutTimMc: RO. TF. LM. AO.
11:39RickInGAfoxdonut: LOL
11:39ibdknoxBorkdude: yeah, I'll be posting a second update about that
11:39ache ibdknox: will LT be able to support LP some time in the future, perhaps with a plug-in? (literate programming)
11:40ibdknoxache: there's some neat stuff you could do with an LP plugin
11:40ibdknoxache: not sure I'll be the one to build it, since I'm already stretched pretty thin
11:40ibdknoxbut I imagine someone will :)
11:40acheas long as the door's open :)
11:41acheit would be a dream within a dream. congrats!
11:46cldwalkerhi all, does leiningen support an rc file i.e. leiningenrc? I'm calling (load-file my-file) each time I start lein repl
11:47TimMccldwalker: There's some sort of init.clj or user.clj in ~/.lein
11:47TimMcOne is for running code in Lein itself, the other is run for your repl session.
11:48cldwalkerTimMc: Thanks!
11:49bhenryhas anyone had the following problem? with :main in project.clj lein repl gives "REPL server launch timed out" but with no :main in project.clj it works fine. this is lein2
11:50foxdonutRickInGA: :)
11:50bhenryeven stranger is that i can run the (-main) function defined in the :main namespace from the repl that works.
11:56gfredericksbhenry: it might be trying to load the repl in your main ns. Does than ns do anything interesting at load-time?
11:57gfredericks(e.g., read a config file that is missing)
11:57TimMcbhenry: Try increasing Lein's REPL-start timeout. I forget how...
11:58bhenryit reads a config file, but it's not missing. and i can run (-main) from that namespace just fine once i load the repl after deleting the :main line from project.clj
12:01zakwilsonibdknox: congratulations on YC. Just don't forget about Korma and stuff!
12:02TimMcand us!
12:03TimMcbhenry: I used to have that problem. It's basically just slow JVM startup.
12:03hyPiRionibdknox: Seems like I'm late to the party, but congratulations from me too. :)
12:04ibdknoxthanks guys :)
12:04y3diholeeee shittt
12:04y3digratz
12:05ejacksonwell done Chris, awesome
12:05ibdknoxzakwilson: Korma is really orthogonal to what I'll need to be doing in the near future, so I'm going to be looking for someone to help keep it moving forward
12:05ibdknoxYeah, exciting times ahead
12:05zakwilsonI'd volunteer, but I'm bad at SQL.
12:05ibdknoxzakwilson: me too, don't tell anyone ;)
12:05zakwilsonHeh.
12:06eggsbyI showed a db friend who is learning clojure korma and he got excited
12:07eggsbycomposable sql... mm
12:07zakwilsonAs he should. SQL is a really terrible language.
12:07eggsbymeh, it's not bad or hard or anything, just limited
12:07fliebelibdknox: Congrats. It seems some people wonder about Python. Are you still lurking in the HN thread?
12:07pipelinekorma is the reason i wanted to learn clojure, no joke
12:07zakwilsonYes, that's why it's terrible.
12:08pipelinei heard about clojure a couple years ago and it sounded neat but there was no particular reason i wanted to learn it
12:08eggsbywoah YC changed their mind about light table?
12:08eggsbysup pipeline cobol4life
12:08zakwilsonI can't remember why I wanted to learn Clojure now. I was using Common Lisp at the time.
12:08eggsbyibdknox: I thought you initially got rejected from yc?
12:08ibdknoxeggsby: we were haha
12:09eggsbyheh
12:09ibdknoxeggsby: for a different idea though
12:09zakwilsonA dev tool written in a lisp that's at the top of HN every time it's mentioned is kind of a natural fit for YC.
12:09eggsbypg looked at the kickstarter results... 'welp'
12:09ibdknoxI got recognized at a restaurant the other day
12:09ibdknoxthis whole thing is a bit surreal
12:09eggsbynice
12:10eggsbyyou are dev famous now
12:10ibdknoxhaha
12:10zakwilsonI'm assuming this is in the bay area?
12:10eggsbyyou work at msft right ibdknox ?
12:10ibdknoxused to
12:10ibdknoxzakwilson: yeah
12:10eggsbyah
12:11llasramzakwilson: That's funny -- I too forgot for a while what had motivated me to learn Clojure in the first place. I'm now pretty sure it was Yegge's forward to /JoC/, although I couldn't tell you why exactly
12:11eggsbyDid they let you use clojure there...
12:12llasrams,forward,foreword,
12:28gfredericksif ibdknox is famous, then I am famous because I am in the same IRC channel he is. So I will henceforth expect recognition.
12:30zakwilsonI don't want to be famous. Just rich.
12:31TimMczakwilson: Best is to be rich but not famous. Then people don't ask you for money.
12:31zakwilsonYeah, but I'd buy a Ferrari and ruin it.
12:32gfredericksI didn't ask for fame, but here I am having to deal with it anyways.
12:32jodaroi can't complain, but sometimes i still do
12:33zakwilsonI said Ferrari, not Maserati!
12:33gfredericksthanks ibdknox for ruining all our lives. damn paparazzi won't leave me alone.
12:33ibdknox's my job. Making the world a little bit more awful one blind step at a time :D
12:34gfredericksit's nobody's business which movie star I'm marrying this month
12:36winkgfredericks: that's the quick route to "not having money"
12:37zakwilsonSo I came up with this idea for a Clojure-inspired replacement for C. Should I quit drinking?
12:37gfrederickswhat would it take to make the CLJS compiler emit C? just a GC impl?
12:38zakwilsonNo idea, but that's far from what I have in mind.
12:38jodaroeither quit drinking, or drink more
12:39zakwilsonActually, I think that would be hard. CLJS uses Google's java->js thing, IIRC.
12:39gfrederickszakwilson: if someone needs the performance of C can they afford all the dynamicity and immutability?
12:39yoklovzakwilson: no, it doesn't
12:39llasramzakwilson: Basic idea has been done, if I understand. I'm trying to find it...
12:39zakwilsonjodaro: http://xkcd.com/323/
12:39yoklovzakwilson: it uses googles js->js optimizer
12:40progogambit-clojure is in the works
12:40llasramzakwilson: Here we go: http://voodoo-slide.blogspot.com/2010/01/amplifying-c.html && https://github.com/deplinenoise/c-amplify
12:41jodarohah
12:42zakwilsonllasram: yeah, I remember something called SC that was, I think similar to that.
12:43jodarohah
12:43jodarotodays xkcd is good
12:43zakwilsonAnyway, what I have in mind is slightly more ambitious than just compiling to C or doing C with Lisp syntax, but less ambitious than trying to do systems programming with Clojure semantics.
12:43llasramWhat's the middle ground?
12:44krawitzhi, does anyone knows a convenient way to parse multipart responses in clj-http, except using commons-fileupload? i found only functions to make multipart requests, but not to parse responses. :-(
12:44TimMczakwilson: Taken a look at Rust, by the way?
12:46zakwilsonClojure-like syntax, avoidance of complecting whenever possible, LLVM backend, static typing (but the option of an unchecked cast if you really need it), pointers, ad-hoc hierarchies... just some brainstorming at the moment.
12:46ibdknoxwe should just do LLVM clojure :)
12:49llasram+1
12:49zakwilsonI like that idea, but so much Clojure depends on Java libraries.
12:54llasramzakwilson: Well, ClojureScript and clojure-py are having a go of it
12:55llasramMaybe start by creating a native-feeling C FFI layer which works in JVM Clojure by dynamically mapping to JNA, but could directly generate native code for an LLVM version
13:03TimMcAnd since we've seen LLVM compile to JS...
13:03TimMcWe could run Clojure in the browser! :-D
13:05pjstadigllasram & zakwilson: there's also this http://nakkaya.com/2011/06/29/ferret-an-experimental-clojure-compiler/
13:11TimMc"Since there is no support for vectors, they are converted to lists."
13:12TimMcUmmm... there goes most Clojure code right there.
13:12zakwilsonWouldn't any of many dynamic array implementations do for that?
13:13gfredericksTimMc: most?
13:14TimMczakwilson: Not if they use mutation...
13:14gfredericksdoes it mean vectors in code or vectors the data structures?
13:15TimMcPresumably the data structure.
13:15zakwilsonWell, there is that. I think compiling Clojure to C or C++ sounds like a terrible idea, personally.
13:40dnolen`ibdknox: congrats on YC12!
13:40ibdknoxdnolen`: thanks!
13:50dnolen`ibdknox: your talk for Strange Loop looks cool :)
13:50ibdknoxdid he post it?
13:51ibdknoxah he did
13:51ibdknox:)
13:52gfredericksthere are a lot of SL talks O_O
13:53technomancythey should just make it a full week conference
13:53dnolen`gfredericks: yeah they run like 3 tracks or something.
13:53hiredmansl is totally sweet
13:53technomancyI think it was more like six tracks last year
13:53gfredericksibdknox: the "Kodowa" link under your name goes nowheres
13:53gfredericksyes it was like six
13:54gfredericksmy favorite six talks were all at the same time
13:54ibdknoxhm
13:54dnolen`technomancy: heh, misremembered.
13:54Licenseribdknox congrats to the LightTable startup :)
13:54technomancyit's wild
13:54clojurebotIt's greek to me.
13:55technomancythat too
13:55ibdknoxgfredericks: there's nothing there yet anyways: http://kodowa.com/
13:57zakwilsonibdknox: your stuff is always so pretty.
13:57ibdknoxI have on idea what that site looks like on a non-mac
13:57ibdknoxprobably pretty shitty
13:57ibdknoxlol
13:58gfrederickspritty shetty
13:59ibdknoxman the reddit community is so depressing
13:59solussdibdknox: congrats, btw. :D Can't wait to play with light table
13:59ibdknoxwell, sounds like you'll get to play with some of it in not too long :)
14:03zakwilsonYes, reddit can be depressing. I've been there for nearly seven years and moderate a largish subreddit. Did I mention I drink?
14:03technomancy21st-century slashdot
14:03solussdcurrently using emacs/swank- i don't know if I can untrain myself of paredit mode. wonder if codemirror supports something similar. :)
14:04zakwilsonreddit actually did replace slashdot for me, so... yes.
14:04technomancyslashdot was never that slow though
14:04TimMcUgh, being a moderator kind of sucks.
14:04technomancywell, maybe it was and I just didn't notice because everything was slow back then
14:05zakwilsonI wonder if I pointed a text classifier at the reddit API if I could stop moderating by hand...
14:05gfredericksTimMc: I bet it's more fun to be an extremerator
14:07neotykdnolen`: attached reduced patch to cljs-204
14:09dnolen`neotyk: it looks good. Will apply later today.
14:13TimMcgfredericks: There are subreddits like that.
14:14TimMczakwilson: One of these days I will write a ROBOT9000 bot that has reddit mod credentials.
14:15weavejesterDoes anyone know of a good way to block until a trigger in Clojure?
14:15technomancyweavejester: promise is good for that
14:15hiredmana queue?
14:15weavejestertechnomancy: Yeah, but a promise only works once
14:16technomancysure
14:16LauJensenEvening gents
14:16technomancya seq of promises =)
14:16weavejesterI was thinking a lazy seq or a promise in an atom that keeps changing
14:16zakwilsonTimMc: that could be hillarious. I've done quite a bit with text classification lately. Even used it to write a chat bot.
14:16technomancya queue would be better I think
14:16weavejesterA queue isn't really what I want because each trigger resets the event.
14:17hiredmanresets the event?
14:17weavejesterI basically want to block until a file has been changed, or until a timeout.
14:17hiredmansounds like a queue to me
14:17weavejesterSo I don't care how many files have been changed
14:18hiredmanhttp://docs.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html
14:18weavejesterBut if I get 10 file changes all at once I don't want to keep triggering the refresh.
14:19weavejesterMaybe I just want a lock
14:19hiredmanyou have a source of events > queue > a consumer of the events, which component has the responsibility to throttle?
14:19zakwilsonpg says "When we realized that multiple YC partners had already independently contributed to the Kickstarter project because they wanted to use Light Table themselves, it was not a hard decision."
14:20zakwilsonI'd contribute too if I wasn't poor.
14:20weavejesterI was thinking of having a thread that watches a filesystem, and then to raise events when something changes.
14:21weavejesterAnd then I'd have a route that blocks until a file is changed, or until a timeout.
14:21nDuffHrm.
14:21mebaran151weavejester: have you seen the WatchService in JRE7?
14:21nDuffLooks like shutting down swank-clojure and starting a new thread later is still reusing some state (particularly, a classloader)
14:22hiredmanweavejester: it really sounds like a queue to me, you just have a particular consumer that has sme throttling requirements
14:22weavejestermebaran151: I don't really want to rely on Java 1.7...
14:22y3didnolen`: where did you see chris's SL talk? I can't seem to find it
14:22hiredmanso the consumer can look at the time from the "file modified" event from the queue and decide "well the last one was less than M minutes ago, so I will do nothing"
14:22mebaran151weavejester: a quick google found an Apache port that is supposed to be pure java
14:23mebaran151Apache VFS
14:24weavejestermebaran151: I'll look into that
14:25mebaran151it doesn't give you resolution as precise as the WatchService, but its DefaultFileMonitor polls once a second, and I think you can register multiple files too
14:26weavejestermebaran151: I think it would be easier for me to use ibdknox's watchtower
14:26weavejesterI'm just not certain what's the best way to block...
14:27mebaran151weavejester: watchtower looks neat
14:27mebaran151couldn't you just do a promise and deliver it from the on-change handler?
14:28weavejestermebaran151: Yep, and that would work once… but when a promise has been delivered, the value doesn't change.
14:29weavejesterI guess...
14:29weavejesterWhat I want to say is "has the filesystem changed since time X"
14:29weavejesterThat could be the promise.
14:31neotykdnolen`: thanks
14:31mebaran151throw the promise in an atom and reset it everytime?
14:32weavejestermebaran151: Yeah, but that somehow seems a little… wrong, maybe
14:33weavejesterFrom a functional point of view, I'm asking when the filesystem last changed.
14:34weavejesterI think I need to mull this over a bit. I've a feeling I should tie this to a time somehow.
14:34clojurebotmultimethods are http://clojure.org/multimethods
14:34gtrakmul?
14:35gtrakwhatcha talking about, clojurebot?
14:35Chousuke"mull this" -> multi? :P
14:35gtraklol
14:35gtrakI think I need to mull this
14:35raekI think clojurebot has a built-in probability of randomly interpreting an irc message as directed to itself
14:35Chousukeyeah
14:35pjstadig~mull
14:35clojurebotPardon?
14:35pjstadigand i don't think the content of the message matters
14:35hiredmanweavejester: seriously, an event queue, and the consumers can keep some kind of state if they wish
14:36weavejesterEach time we think we understand Clojurebot, it because something even more inscrutable
14:38weavejesterhiredman: Hmm...
14:38hiredmanthe way it got from what weavejester said to the bit about multimethods is 3-4 (faulty) inferences
14:39hiredman"..time.." -> something chouser said about time -> something chouser said about multimethods -> multimethods
14:41gfredericks~time
14:41clojurebotmultimethods seperate the 20% from the 80%
14:41gfredericksso the fact that "time" is a substring of "multimethods" is an unrelated coincidence?
14:41hiredmanI think so
14:42hiredmanbut I dunno, the inference seems be acting more generally than intended
14:42weavejesterhiredman: It doesn't really feel like a queue. I mean, if I don't care about how many events there are when I poll.
14:43hiredmanI don't follow how caring about "how many" has anything to do with a queue
14:43weavejesterhiredman: I guess I could have a queue of size 1 :)
14:44weavejesterhiredman: Well, if there are zero events, I want to block until an event. If there are many events, I return immediately.
14:45mwillhitehey all - pretty new to clojure here…I'm trying to get some ring middleware going so that I can process params in the form of json in my compojure app
14:45mwillhitein my project.clj I have the following: [ring-middleware-format "0.1.1"]
14:45hiredmanweavejester: seems reasonable
14:45mwillhiteran lein deps and it pulled down the repo
14:45mwillhitein my core.clj in the use call I have this: [ring.middleware.format-params :only [wrap-json-params]
14:46mwillhiteas specified in the readme
14:46mwillhitebut when I go to boot up the app I get the following error:
14:46mwillhiteCaused by: java.lang.RuntimeException: No such var: clojure.core/ring.middleware.format-params
14:46mwillhiteam I missing something super obvious here?
14:46hiredmanweavejester: you have some kind of file watcher thread that generates filesystem events, that thread has a list of weak or soft references to queues, you have listeners on each side of the queues
14:46hiredmanthe listeners don't have to consumer their entire queue
14:47weavejestermwillhite: Are you using (ns … (:use )) or just (use …)?
14:47mwillhitethe former
14:47weavejestermwillhite: I'd need to see your whole ns declaration, I think...
14:48mwillhitesure lemme pastie it
14:48raek"clojure.core/ring.middleware.format-params" sounds suspicious
14:48weavejesterhiredman: I'm still not sure why I'd want a queue when I don't care about the events themselves, just if there are any.
14:49weavejesterhiredman: It feels more like a concurrency primitive than a queue.
14:50TimMcThere's gotta be a way to use core.logic here.
14:50mwillhiteoh jeez, I'm an idiot…I had tacked it on after the closing paren :P
14:50mwillhitethanks! haha
14:50hiredmanweavejester: the queue approach is more general and provides a better separation between the event generator and the consumer
14:50hiredmanweavejester: if you ever think some day you might care about the events
14:51hiredmanif you are set on using something else, maybe a cyclicbarrier?
14:52mebaran151a promise that unpromises itself after reference would have some utility
14:52hiredman:(
14:52hiredmanthat's not a promise
14:52clojurebotTitim gan éirí ort.
14:53hiredmanthe power of a promise is the one shot nature
14:53weavejesterhiredman: But it kinda feels like the wrong solution. I mean, I'd need to either poll and then clean the queue each time, ignore events, or set the queue size to 1 or something.
14:53weavejesterhiredman: And a queue of size 1 doesn't seem like a queue anymore.
14:54hiredmanhttp://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CyclicBarrier.html
14:56weavejesterhiredman: That doesn't seem quite right either… It feels one step too complex - it still cares about the number.
14:58eggsbyso... I'm trying to dip my feet into macro lake, I have something passed to a macro, I want it passed in as a value to another function, but not evaluated... do I want to use ~ ?
14:59eggsby~@ will evaluate it, right?
14:59clojurebot@ is like the macro version of apply
15:00CaffeineHow to keep the REPL open? I would like to start the REPL with a script (passing it a clj file in param) and keep it opened after. Can I do that???
15:00lazybotCaffeine: Yes, 100% for sure.
15:00AimHereeggsby, you probably want ` to keep code from evaulating inside a macro
15:00AimHereThen you use ~ or @ for the bits you DO want to evaluate
15:00eggsbyAimHere: this is inside the body of a `() statement
15:01eggsbyoh, ok
15:01raekeggsby: do you know enough about macros to write one without syntax-quote?
15:01TimMcIt's not about evaluating, it's about syntax transformation!
15:01eggsbyraek: mm, this is my first time writing a macro, and a lot of it is code borrowed from an article :3
15:02eggsbyso say I have a list inside a `() form... would I go `(my-func ~@(first my-list) ~@(rest my-list)) if I wanted it to expand to (my-func first (rest-my-list)) ?
15:02raekI think it best to start with thinking of macros as functions from that is applied to the source code data structures
15:03stuartsierraCaffeine: Pass the -r option to clojure.main
15:03raekeggsby: do you have a simple example of a call to your macro and what it should expand to?
15:03eggsbyI don't really want the (rest-my-list) to be evaluated, I just want it passed in as a list minus the head
15:03hiredmanweavejester: if you have a design with an X shaped hole, and it turns out no one has ever created an X, what does it say about the design?
15:03stuartsierraCheck the command-line syntax by running clojure with -h
15:03eggsbylet me make one raek
15:04raekeggsby: the macro code is executed at compile time. it does not know about the runtime values.
15:05Caffeinestuartsierra: It works! Thanks!
15:06stuartsierra'welcome
15:06raekeggsby: one important thing that you need to know is that syntax quote is not tied to macros in any way. it's just a template language for lists, vectors and other data structures
15:07TimMc,(let [x [1 2 3]] `[a b ~@x c d])
15:07clojurebot[sandbox/a sandbox/b 1 2 3 ...]
15:07amalloyi'm hopping in late here, but weavejester's problem sounds like a queue to me too
15:08eggsbyraek: https://www.refheap.com/paste/2790
15:08eggsbythat's an inner function used by a macro
15:08weavejesterIt would have to be a queue of capacity 1
15:09eggsbyoops, every occurance of myargs should be 'real-args'
15:09weavejesterWhich seems like not a queue
15:09eggsbyderp... so many syntax errors there
15:10eggsbyraek: https://www.refheap.com/paste/2791 is what I meant
15:10raekeggsby: ok, so the macro should look at action and generate either a call to do-something or do-something else?
15:10eggsbyyes raek
15:10raekah
15:11raekbasically (my-macro :otheraction <a> <b> <c>) ==> (do-something-else <a> (list <b> <c>))?
15:12eggsbyya, but looking back maybe I should just rewrite how 'do-something-else' works...
15:12eggsbyand just use ~@ to flatten the remainder of the args, then have do-something-else use & to splat
15:13eggsbycause just going '(some-call ~@(real-args)) results in (some-call my real args) expanded, right?
15:13raekdo you want do-something-else to take <b> and <c> as separate args?
15:13eggsbyya basically
15:13RaynesRefheap is getting lots of paste love lately.
15:13raekok, let's wait with the implementation details a bit
15:14eggsbybut I think I should just manage that in the implementation of do-something and do-something-else, right raek ?
15:14eggsbyok
15:14raekI just want to understand what the macro should to first :-)
15:14gtrakRaynes: mmm paste love
15:14eggsbyraek: basically I have some expression that I want to pass to a function to conditionally evaluate
15:15raekeggsby: a macro can rewrite an expression into another one. is (my-macro :otheraction <a> <b> <c>) ==> (do-something-else <a> <b> <c>) fine?
15:15raekso this will "compile away" the conditional that checks for :otheraction
15:15eggsbyright
15:16muhooi love it. an exception in projectname.views.something/eval24214
15:16raekthe defmacro form could look like this then: (defmacro my-macro [action & args] ...)
15:17raekaction will be a keyword and args will be a sequence of code expressions
15:17amalloyeggsby: you know this macro can only recognize :some-action if you pass it as a compile-time literal, right? you can't do (let [action (if foo :some-action :other-action)] (my-macro action a b c))
15:18raekif the call looks like (my-macro :someaction (+ 1 2)), action will be bound to :someaction and args to '((+ 1 2)), and not '(3)
15:19raek(defmacro my-macro [action & args] (case action :someaction ... :otheraction ...))
15:19weavejesterA promise in an atom might be the best solution
15:19raekthe ...s should return data that looks like (do-something <arguments-here...>) or (do-something-else <arguments-here...>)
15:20hiredmanweavejester: :(
15:20raekso let's build some lists and symbols
15:20weavejesterhiredman: I don't think there's a way to use a LinkedBlockingQueue to do what I want
15:20eggsbyhm
15:20hiredmanweavejester: why don you just create a singe element array and lock it
15:20weavejesterhiredman: If I poll, I can get the head of the queue
15:21weavejesterhiredman: How would that be different from an atom with a single value?
15:21mebaran1`weavejester: you have two elements of state anyway, so it seems like you would need two concurrency primitives
15:21raek(defmacro my-macro [action & args] (case :someaction (cons 'do-something args) :otheraction (cons 'do-something-else args)))
15:21mebaran1`whether the atom has been read and whether the filesystem has changed
15:22eggsbycons... hm
15:22hiredmanweavejester: I don't know, a promise in an atom is just so disgusting
15:22weavejesterhiredman: I know… :(
15:22raeknow, instead of building lists like (cons 'foo (cons x (list 'bar 'baz))), we can use `(foo ~x bar baz)
15:22raek&'`(foo ~x bar baz)
15:22lazybotjava.lang.ClassNotFoundException: clojure.core
15:23TimMcYeah, lazybot is down for the count.
15:23raekthat is actually expanded to this by the reader: (seq (concat (list 'foo) (list x) (list 'bar) (list 'baz)))
15:24amalloyhuh
15:24eggsbywhat in the
15:24eggsbyhm
15:25weavejesterhiredman: Well, I don't know. A promise is for a value we don't yet know, like… when's the next file going to be changed?
15:25raekif we instead write `(foo ~@x bar baz) then we would get this: (seq (concat (list 'foo) x (list 'bar) (list 'baz)))
15:25weavejesterhiredman: So ideally you'd want to tie it to a time...
15:26eggsbyhmm
15:26S11001001,'`(foo ~@x bar baz)
15:26clojurebot(clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/foo)) x (clojure.core/list (quote sandbox/bar)) (clojure.core/list (quote sandbox/baz))))
15:27weavejesterhiredman: And an atom ties a value to an identity at a certain time.
15:27hiredmanI think I may jsut stick my fingers in my ears and say "queue queue queue queue ..."
15:27weavejesterhiredman: But the queue would only have one element! That's not really a queue, right?
15:27hiredmanweavejester: why would it only have one element?
15:27amalloyi put a delay in an atom recently. not as weird as a promise, but still feels a little weird
15:28raekeggsby: the macro can the be written like: (defmacro my-macro [action & args] (case :someaction `(do-something ~@args) :otheraction `(do-something-else ~@args)))
15:28hiredmanweavejester: your current consumer may only care about 1 element
15:28eggsbyraek: what if x was a primitive and couldn't be "flattened" like that
15:28weavejesterhiredman: Because I want to trigger a refresh when any amount of files change
15:29TimMc,(let [x 5] `[a b ~@x c d])
15:29clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
15:29eggsbyso if x were (2 3) `(1 ~x 4) would be (1 (2 3) 4) and `(1 ~@x 4) would be (1 2 3 4), right?
15:29pjstadigdon't do that
15:29TimMceggsby: Just what you'd expect.
15:29raekeggsby: like 123? then the code would expand to (seq (concat (list 'foo) 123 (list 'bar) (list 'baz))) and you would get an error when that is evaluated
15:29weavejesterhiredman: But there's no atomic operation to block and consume all of a blockingqueue
15:29eggsbyah, okay raek
15:29eggsbythat helps a lot, thanks
15:29raekthe macro constructs new code that is sent back to the compiler
15:29weavejesterhiredman: I can poll it to get the head
15:29eggsbyso what is the difference between ' and ` ?
15:30ieureIs there a Clojure/Java equivalent to Python's cmd library? http://docs.python.org/library/cmd.html
15:30ieureIt's a REPL building framework.
15:30raekeggsby: with ' you can't have "holes" like ~ and ~@
15:30raekalso, ` makes symbols namespace safe
15:30eggsbyah, I see
15:30weavejesterhiredman: But I don't see how I can use a blockingqueue to do this
15:30TimMcraek: Don't forget gensyms.
15:31hiredmanweavejester: https://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/FSEvents_ProgGuide/KernelQueues/KernelQueues.html http://linux.die.net/man/7/inotify http://c2.com/cgi/wiki?EventQueue
15:32hiredmanyou pull a message from the queue, check it meets some set of conditions, and if it does you trigger some action, then go back to polling
15:33TimMcand throw timeouts into the queue as well?
15:33hiredmanTimMc: most queues let you poll with a timeout
15:33hiredmanlbq definitely does, and so does every messagebus I know of
15:34weavejesterhiredman: That's a point...
15:35hiredmanweavejester: you can even push the state management even farther down, by making it all internal to the refresh function, so refreshing is always throttled no matter how you call it
15:35hiredmanthrottled to 60hz or something :)
15:37hiredmanrefresh can be a scheduled function that checks a "re-render" flag
15:37hiredmanso refresh runs every S seconds and just looks at an atom to see what needs to be redrawn
15:38weavejesterHm...
15:39weavejesterBecause the "refresh" is a response returned, I can't do that exactly
15:44weavejesterHm, also, a queue wouldn't work because there could be multiple consumers.
15:47TimMcweavejester: To recap, you need to take an action iff at least one event has occurred since the last time you took action, but only once x milliseconds have passed since the first such event?
15:48hiredmanweavejester: that does not preclude a queue
15:48TimMc(with the delay intended to allow grouping)
15:48hiredmanyou each consumer gets a queue
15:49weavejesterTimMc: I basically have a route in my web app that tells a javascript function whether or not to refresh the current page.
15:49weavejesterSo the javascript sends an XHR to the route
15:50weavejesterIf no files are changed it waits up until a timeout before returning false
15:50weavejesterIf any files are changed it returns true
15:51TimMcI think you can separate the blocking -- "taking action" could mean signaling all waiters on an object.
15:52weavejesterRight...
15:53hiredmanhttp://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#wait%28long%29
15:53weavejesterBut because each consumer is temporary, I can't assign them a queue.
15:53TimMcweavejester: False positives are bad?
15:53hiredmanhttp://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#notifyAll%28%29
15:53weavejesterhiredman: Yeah, I was thinking about that...
15:54weavejesterhiredman: But is keeping an lock object any better than a promise?
15:54weavejesterTimMc: Well, I don't want to change 10 files, and then have it refresh 10 times
15:54hiredmanweavejester: yes
15:55TimMcweavejester: So each waiter needs to have its own notion of a timeout, but they all rely on the same event stream.
15:55weavejesterTimMc: Yes...
15:56hiredman"spurious wakeup" ugh
15:57weavejesterThis is making me feel dumb. It feels like such an easy problem :)
15:58TimMcI'm having trouble with the idea of uses queues here. Queue read timeouts are a different *kind* of timeout than what you need.
15:58hiredmanyou need broadcast queues, which java.lang.concurrent doesn't have, but you can build them
15:59weavejesterI think I need a broadcast something, but I don't see why it should be a queue, when I don't care about the items being queued.
16:00hiredmanright, which is why you want a broadcast queue that goes away when no one is listening
16:00weavejesterA promise seems like the right way of delivering a single value to multiple threads when it's ready.
16:00weavejesterI mean, that's what it's for, right?
16:01hiredmanfor a one shot value
16:01weavejesterYes, but you could have a function returning a promise
16:03weavejesterLike… (next-modification-date dirs)
16:03weavejesterWhich would return a promise of the next modified date in the directories
16:03weavejesterI guess it would be more like (next-modified dirs timestamp)
16:05weavejesterI guess I'll think about it.
16:08TimMcweavejester: When a waiter comes in, it creates an atom and registers a closure over it with the notification service, then sleeps for 100 ms. Each time a file event happens, all the closures are called with the event info. In this case, each closure sets its atom's state to true. When the timeout is over, the waiter returns the atom's value.
16:08TimMc(Oh, and unregisters its atom.)
16:12TimMcweavejester: Alternatively, the notification service maintains a file event count. Client-side code keeps this as an opaque data value and sends it along with the XHR, getting a replacement value back each time -- along with whether to refresh as calculated by (!= old new).
16:12RaynesTimMc: Man, I thought you were talking about a restaurant for a moment there.
16:13TimMcThis approach does not rely on any queue, and each waiter simply sets a timeout and does that simple calculation when the timer fires.
16:14TimMcRaynes: I'm not? :-(
16:14RaynesI see what you did there./
16:19TimMcRaynes: What I did == killed the channel?
16:19gtrakis there a = that treats nested seqs/vectors within a map the same?
16:19RaynesTimMc: Yes.
16:19gtraklike... I don't want it to fail if the thing's a vector instead of a seq
16:20TimMc&(= {:a [1]} {:a (seq [1])})
16:20lazybot⇒ true
16:21TimMcgtrak: vectors and seqs are in the same equality partition
16:21gtrakah, I'm just doing something wrong :-) thanks
16:21gtrakthat's good to know anyway
16:21TimMcgtrak: Last table: http://www.brainonfire.net/files/seqs-and-colls/main.html
16:22gtrakneato
16:22TimMcTechnically it only shows a list vs. a vector, but whatevs. :-P
16:22gtrakwhat i did was I used defn vs def accidentally, so it tried to equate a map and a function xD
16:22gtrakbut i've never seen a defn without an arglist, why would that work?
16:23gtrak,(defn parsed {:graphs '("graph1" "graph2") :endpoint "http://url&quot; :all? true})
16:23clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
16:23gtrak&(defn parsed {:graphs '("graph1" "graph2") :endpoint "http://url&quot; :all? true})
16:23lazybotjava.lang.SecurityException: You tripped the alarm! def is bad!
16:23gtrak&(fn {:graphs '("graph1" "graph2") :endpoint "http://url&quot; :all? true})
16:23lazybotjava.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap
16:23gtrakhmm..
16:52devnRaynes: do you know off the top of your head, is it possible to capture *out* from (sandbox (safe-read "(println 1)"))? I'm using (with-out-str and I'm just getting back empty string. How would I capture *out* here?
16:54ibdknoxdevn: you can supply a set of bindings to the sandbox, you need to bind *out* to your own thing and then read from that
16:54Licenserdevn not sure how it is in raynes sandbox but for clj-sandbox stuff like *out* and stuff were bound on the creation of a sandbox
16:57devnibdknox: im not seeing where
16:58muhooit is so funny how much the vc/tech business reminds me of the music business
16:58devnLicenser: yeah im not sure that happens anymore
16:58dgrnbrgwhat's the easiest way to print a double w/ 2 digits of decimal places?
16:58muhooyou develop an indie following, then you get signed by a major
16:58dgrnbrgor just to convert a double to a string w/ 2 digits of decimal places?
16:59technomancy,(format "%0.2f" (/ 2 3))
16:59clojurebot#<MissingFormatWidthException java.util.MissingFormatWidthException: 0.2f>
16:59technomancy,(format "%.2f" (/ 2 3))
16:59clojurebot#<IllegalFormatConversionException java.util.IllegalFormatConversionException: f != clojure.lang.Ratio>
16:59Raynesdevn: lazybot has examples of rebinding *out*.
16:59technomancy,(format "%.2f" (float (/ 2 3))) ; FINE CLOJUREBOT
16:59clojurebot"0.67"
16:59RaynesWhat ibdknox said is spot on.
17:00devnRaynes: thanks, and thanks ibdknox
17:00dgrnbrgtechnomancy: thanks
17:00devnand thanks Licenser for starting the whole thing :)
17:00Raynesdevn: Also, I showed an example in my talk. Did you not pay attention? :(!
17:00Licenser^^
17:00RaynesI'm hurt, devn.
17:00devnRaynes: lol. i have that one coming.
17:00devni was out until 4am the night before and walked in near the end :X
17:01LicenserRaynes if there's one thing you should have learned ins school it's: students never listen to what the teacher sais
17:01RaynesI slept through most of the conference, so totally understandable.
17:01muhoook, so snoir send-request blows up with clojure.lang.Var$Unbound when there is a noir.session/flash-get in the page
17:02muhooapparently *noir-flash* doesn't exist when send-request is used
17:02devnRaynes: wicked. thanks.
17:05TimMc&(defn oops {:some :map})
17:05lazybotjava.lang.SecurityException: You tripped the alarm! def is bad!
17:06Raynesmuhoo: Those things are only bound inside of a request.
17:06TimMcUrr... right. ANyway, if you then do (oops), you get a NPE
17:06devnRaynes: seems like some of the stuff in lazybot could maybe be brought over to clojail? maybe?
17:06Raynesdevn: Perhaps.
17:07devnseems like someone like me could do that...
17:07devn;)
17:07Raynes:p
17:07devnwhat does box? do?
17:07devn(skimming the lazybot clojure.clj plugin)
17:08Raynesdevn: You can run lazybot and let his eval plugin work without a sandbox. It is useful in private company channels and stuff where you know your employees and coworkers aren't going to delete your machine.
17:08RaynesOr if you run it on a work machine or something.
17:08muhooso i'm confused then how to mock/test a noir app. i figured send-request would do it, but i guess not.
17:08RaynesI added it because we do at Geni.
17:08devnRaynes: gotcha
17:08Raynesdevn: It probably isn't particularly elegant. I sometimes add things on the fly without really thinking them through.
17:08RaynesIt's a character flaw.
17:09Raynesmuhoo: There is a way to mock all of those things, but I sure don't remember what it is.
17:09Raynesibdknox:
17:09LicenserRaynes you trust your coworkers enough for that?
17:09Raynes^
17:09RaynesLicenser: Sure, it runs on a company server.
17:09RaynesNot my problem if they delete stuff on that. :p
17:10Licenserwow I'd not trust any of my colegues furthen then I can throw them - and many of them are rather heavy
17:10Licenserhah
17:10TimMc"Raynes' bot deleted some stuff on the server!"
17:10devnIt could be a lot of fun. send messages to raynes by popping up swing guis
17:10RaynesHaha
17:11TimMc"Including its own logs, mysteriously!"
17:11devni actually ran everything from #clojure *without* safe-read the first time
17:11devnand no issues
17:11technomancynow that you said that though...
17:11RaynesTimMc: You should send me a lazybot pull request fixing the escaping problem in the logs.
17:11devntechnomancy: lol
17:11TimMcdevn: I remember when you found out about *read-eval*...
17:12RaynesMan, watching Stuart Sierra's talk was the scariest thing about the Conj.
17:12TimMcRaynes: Why so concerned about it suddenly?
17:12RaynesWe all thought he was going to pretty much cover the topic of my talk. It turned out to be an excellent primer for my talk though.
17:12RaynesHe talked about *read-eval* and stuff which is highly relevant to how clojail works.
17:13muhooaha! (with-noir (send-request "/")) ftw
17:13RaynesTimMc: because you're malevolent and I'd rather have you on my side.
17:14TimMcAlso, OMG, you haven't <b>fixed</b> that yet?
17:16TimMcI don't know where that code even lives. Not up for archaeology at the moment.
17:16RaynesTimMc: src/lazybot/plugins/logger.clj
17:17TimMcBut it logs to text file, yeah? Not the place to escape stuff, really.
17:17TimMcAt least, not the place for HTML-encoding.
17:18TimMcWhat's broken is the web server, perhaps the JS.
17:19RaynesTimMc: Yeah, but it'd be cool if lazybot served the text files himself. So do that.
17:20TimMcOK, but I'll make it only respond to SPARQL queries.
17:21TimMcRaynes: $('#log').html(lines.join("\n")); is the culprit. Map over lines with an html-encoding function, then join on "<br>".
17:22TimMcI also shudder to think what kind of path traversal exploits you might have in the server.
17:26TimMcRaynes: Or hell, you may be able to just dump the contents in via .text() and use a CSS style to force line breaks to be respected.
17:28eggsbyhey raek with your help I was able to get my macro working, thanks!
17:29raekeggsby: np :)
17:32muhoonow, if only there were a way to maintain a cookie store through several (with-noir (send-request)) requests, hmm
17:32muhooputting several send-requests inside one (with-noir) does not cut the mustard
17:58fil512how can I turn a string into a BufferedInputStream?
17:58fil512when I try (io/input-stream string)
17:59fil512it interprets my string as a filename
17:59weavejesterByteArrayInputStream
17:59fil512what would the syntax be?
17:59S11001001fil512: there's no syntax, it's just normal java calls
17:59fil512I've never made a normal java call before
18:00fil512in clojure
18:00S11001001http://clojure.org/java_interop
18:00weavejesterfil512: (ByteArrayInputStream. (.getBytes s))
18:00weavejesterSo (.getBytes s) is equivalent to the java s.getBytes()
18:00weavejesterAnd (ByteArrayInputStream. foo) is equivalent to: new ByteArrayInputStream(foo)
18:03nDuffWhat's the CCW equivalent to paredit's ctrl+right, ie. [(foo|) bar] => [(foo| bar)]
18:05fil512weavejester: thank you
18:09fil512is there a quick way to turn my map keys to keywords?
18:09fil512from strings
18:11raekfil512: clojure.walk/stringify-keys
18:14devnRaynes: hehe -- just found out why all the stuff in my DB started to magically get "I'm a string: ..." in them:
18:14devnRaynes: http://clojure-log.n01se.net/date/2008-11-09.html#16:34
18:15RaynesHahahaha
18:15devnlol
18:16devnRaynes: other question for you: are these sandbox local? WARNING: next already refers to: #'clojure.core/next in namespace: sandbox5320, being replaced by: #'clojure.zip/next
18:16espeedis there a way to define a default value to return if a record doesn't contain a key?
18:16devnI'm allowing def, those won't persist will they?
18:16hiredmandevn: that's the result of someone doing (use 'clojure.zip)
18:16TimMcespeed: ##(doc get)
18:16lazybot⇒ "([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."
18:17devnhiredman: any idea what would cause this one? WARNING: map already refers to: #'clojure.core/map in namespace: sandbox5320, being replaced by: #'clojure/map
18:17devnhiredman: that's just all alone
18:17TimMcespeed: And records probably support that syntax directly, too.
18:17hiredmandevn: that is just weird
18:17devnhappened somewhere around 10-22
18:17devn(2008)
18:18hiredman(do (in-ns 'clojure) (def map 1) (in-ns 'sandbox) (use 'clojure))
18:18hiredmanoh
18:18hiredman2008 would have been around the time the clojure ns became clojure.core
18:18hiredmanmaybe late 2008
18:20technomancylate 2008; the scars were still fresh when I joined.
18:22espeedTimMc: thanks. I am for something more like __getattr__, which is a function that's called if an object doesn't contain an attribute; so that the default value doesn't have to be explicitly passed to "get"
18:22espeed(__getattr__ in Python)
18:22devnhiredman: so, still -- how did that happen?
18:22devnhiredman: do you see what did it here? http://clojure-log.n01se.net/date/2008-10-22.html
18:24hiredmandevn: http://clojure-log.n01se.net/date/2008-10-22.html#00:59
18:24hiredmanif sometime ealier someone had done (in-ns 'clojure) (defn map ...) or similar
18:25devnhiredman: bingo. thanks
18:28yoklovespeed: if you implement IFn, and use the record as a function (as you also often do with maps and such), you can handle it the way you would like. there might be another way, but I'm not aware of it
18:40espeedyoklov: thanks
18:41TimMcespeed: "implement IFn" is a minor nightmare, by the way
18:42nDuffespeed: ...oh, hey, you're the one porting the graph library? Think I've seen a few of your questions over on StackOverflow
18:42espeednDuff: yes, as a Clojure learning exercise
18:42nDuffespeed: ...very much IMHO, but trying to Python idioms over to a non-Pythonic language seems a bit silly.
18:42yoklovTimMc: why is implement IFn a nightmare? You don't have to implement all the arities
18:42nDuffs/trying to/trying to port/
18:43espeednDuff: part of this process if figuring out the "Clojure-way" of doing things
18:43TimMcyoklov: No?
18:43espeed*is
18:44yoklovTimMc: at least, you don't in ClojureScript, though maybe it's different because in cljs IFn is a protocol and not a java interface?
18:45hiredman(for [i (range 20) :when (not= arity-I-care-about i)] `(invoke ~(vec (repeat i '_)) (throw (IllegalSomethingOrOther.))))
18:45hiredmanthen you just copy and paste the output of that for into your deftype
18:47hiredmanhttps://github.com/hiredman/clojure/blob/41df324e8e6699af82d6d3d2ccaae4ae840904ad/src/jvm/clojure/lang/RIC.java#L1864
18:50amalloydon't forget the this-arg
18:50hiredmansure
18:50hiredmanthat
18:54devnRaynes: i conj'd 'defmethod onto secure-tester-without-def, but it still seems to eval it
18:57devnRaynes: maybe not
19:27eggsbyhmm, say I have a sequence of functions, how can I expand those out into individual function calls?
19:28eggsbylike (list even? (partial = 2)) etc and I have some value I want to apply to every function
19:28eggsbymore specifically I want to say (and (pred1 data) (pred2 data) (pred3 data)) etc
19:29eggsbyso it'd be expanded to something like (and (even? 2) (= 2 2))
19:30amalloy(every? #(% data) fns)
19:31technomancycouldn't you use juxt for that?
19:32technomancy(apply every? ((juxt f1 f2 f3) x))
19:33technomancythat's wrong, but it uses juxt, so it's better
19:33raek:)
19:33eggsbygrr this stupid problem won't bend to my will
19:34eggsbyevery works amalloy thanks, I'll just have to make stuff play nice with it
19:35amalloytechnomancy: laziness, though
19:36amalloyi think a version with juxt that works (laziness aside) is like (every? identity ((apply juxt fs) x))
19:36technomancyevery? true?
19:39raekjuxt is better - even when it's wrong
19:39raekthat should be the motto of the juxt fan club
19:40amalloytechnomancy: i'm pretty sure we want identity here, unless you're insisting on every function returning a boolean
19:41technomancyguess it depends on the domain
19:41clojurebotexcusez-moi
20:46gfredericksI was shown speclj for the first time today and cannot figure out why the (with) macro creates a derefable
20:49nDuffIs ccw.clojure available as part of any published Maven repository?
21:25dnolen`a page describing how to extend core.logic http://github.com/clojure/core.logic/wiki/Extending-core.logic-(Datomic-example)
23:22ForSparePartsIs there any way to examine a clojure function from clojure? Like as a list of function calls, maybe?
23:27xeqiForSpareParts: are you looking for ##(doc source) or something like https://github.com/frenchy64/analyze
23:27lazybotjava.lang.RuntimeException: Unable to resolve var: source in this context
23:27xeqi&(doc clojure.repl/source)
23:27lazybot⇒ "Macro ([n]); Prints the source code for the given symbol, if it can find it. This requires that the symbol resolve to a Var defined in a namespace for which the .clj is in the classpath. Example: (source filter)"
23:28ForSparePartsNot sure which would do it. I'm thinking about unit testing and regression -- it would be useful to be able to list all the functions called by a given function.
23:29ForSparePartsUnless there's a much better way of doing that sort of thing that I'm just missing...?
23:29dnolen`ForSpareParts: it's possible but you would need to adapt an analyzer like the one that ships with ClojureScript
23:30ForSparePartshm. Does vanilla Clojure not come with one?
23:31brehautnot currently
23:31ForSparePartsInteresting.
23:32ForSparePartsAm I missing a better approach to this problem? I was thinking about a Java implementation, but it turned into a big OOP mess in my head.
23:32brehautclojurescript is sort of a proof of concept for clojure in clojure. its also clojure implemented with 3 or so years hindsight, so its got tricks that jvm clojure does not
23:34dnolen`ForSpareParts: I believe Clojure does have an analyzer but I don't think it's very easy to use.
23:34dnolen`ForSpareParts: just use the one in ClojureScript, analyzer is like <500 lines of code or something.
23:34brehautambrosebs has a port of it to clojure doesnt he?
23:35ForSparePartsYeah, I found something about the Clojure analyzer on dev.clojure.org that links to the Frenchy64 project that xeqi linked me to.
23:39zakwilsonI can't find the new comment reader syntax with google. What is it?
23:40dnolen`zakwilson: new?
23:40zakwilsondnolen`: there's something new in 1.4, as I recall.
23:41dnolen`zakwilson: tagged literals
23:44zakwilsondnolen`: found it in the reader source: #_
23:45dnolen`zakwilson: that's not new
23:46zakwilsondnolen`: I'll take your word for that. I only learned about it recently and I made a mental note of it being new.