#clojure logs

2015-02-16

01:38julianlevistonHi, question about core async patterns. I have a fanning pattern. Each time my ‘retrieve’ function is called, it gathers a set of ids, starts a go block (therefore the main function call finishes), which runs a ‘retrieve associated’ function on its results, which then calls back into ‘retrieve’ for each of those items (ie recurses). I’d like to pass a ‘done chan’ into the main retrieve function, but not
01:38julianlevistonhave it wait around until all its “children” are done… so is there a way I can start another go block all it does is wait around unti the n children have finished and send “:done” back to the done chan? Will that pattern work ok, do you think?
01:41julianlevistonmostly I don’t care if the fanning operation is done, but very ocassionally I need to sync up some work at the end, and so I’d wrap the done chan put in a check-for-presence conditional
01:42julianlevistonI might go try it out and see how I go… lol… thansk for being a sounding board, channel :)
01:58Kneivano prob =)
02:07julianlevistonKneiva: lol
04:27ro_stthere's no point to using tomcat to host a jar if that jar doesn't accept http connections, right?
04:27ro_stfor that, you'd simply java -jar app.jar inside an upstart script or whatever?
04:37cmdrdatsro_st: unless you already have tomcat going and don't want to manage another app's lifecycle
04:39ro_stnew nodes, so wondering if it's worth the bother
04:39ro_stdoes it make sense to use tomcat for non http apps?
04:40ro_sttomcat is to java as apache is to php, no?
04:41Empperiro_st: kinda, but not quite
04:41Empperiand in my opinion if you don't need HTTP server functionality then you don't need Tomcat
04:41Empperiand you shouldn't use it
04:41cmdrdatsif you're not using any of the servlet deployment stuff, then probably pointless to use tomcat..
04:41cmdrdatssnap :)
04:42Emppericomparing java and php is kinda pointless anyway
04:42ro_stcool. no tomcat then. we already use upstart to java -jar wossname.jar so we'd continue to do that
04:42ro_stEmpperi: let's not go there :-)
04:42Empperiphp has been designed from ground up to be used in applications which are very short lived
04:42Empperiand java is the opposite
04:42Empperion average a php program lives as long as the http request which is handled by apache/nginx/whatever
04:43ro_sti know.
04:43Empperibut yeah, you'd just complicate your life with Tomcat :)
04:43ro_stcool. thanks
04:46dysfundoes cemerick get on irc much these days?
04:48ro_stit's sleepy time in his timezone
04:49dysfunah
04:58txushi there!
05:02jballanctxus: howdy!
05:02jballancdysfun: weechat with a bouncer for me...but at least that sets /away when I disconnect
05:03dysfuni've thought of using a bouncer, but i *like* irssi anyway
05:03dysfunwhen i had a client who used irc, i used colloquy. a bouncer would have been nice for external networks
05:04dysfun(mostly because colloquy supports growl and it was useful for mentions)
05:05zactsI'm going to try znc for myself
05:05scottjyou could setup irssi to do that, even over ssh and screen. fnotify is the irssi module to look at.
05:05zactsmainly so I can have snappy keyboard response time
05:05dysfunyeah, i know, but i'm lazy :)
05:05zactsthere is mosh though
05:06dysfuntbh i usually don't notice any lag on ssh to this box
05:06dysfunif the internet is having a bad day, maybe it's a little annoying, but it's rare
05:06zactswell mosh is cool for this
05:06dysfunmosh doesn't do tunnelling, which i need for access to some databases
05:07zactsah
05:13txusyay first time in the clojure channel
05:13txushow are y'all??
05:13lazybottxus: Uh, no. Why would you even ask?
05:16hyPiRionoh lazybot, why so mean
05:17hyPiRionlazybot answers anyone ending their sentences with ??? or ??
05:17lazybothyPiRion: Definitely not.
05:24noncomi have just stumbled upon method resolution issue. there is a method ` java.nio.file.Paths.get(String first, String... more) ` , and if i call it like (Paths/get "/some/path"), clojure will fail to identify it correctly
05:24noncomit will confuse the method with ` java.nio.file.Paths.get(URI uri) `
05:25noncomsolution is to call the required method by (Paths/get "/some/path" (into-array String []))
05:25noncomthen it will find the one i really need
05:25noncomso, is this behavior ok? is it considered normal? or should i probably file an issue on jira for that?
05:31dysfunthis is curious: java.io.FileNotFoundException: /Users/dysfun/tmp_clj/resources/templates/ayouts/main.tp (No such file or directory)
05:31dysfunthe l's have been removed from the path
05:31dysfunsome of them
05:32dysfunoh wow. it's a selmer thing
05:32dysfuni had {% extends layouts/main.tpl %} so it clearly took 'l' to be the delimiter
06:48michaelr`hey yo!
06:52michaelr`what's a good place to start a blog? I have two requirements: under my own domain name and export feature.
06:53slipsetmichaelr`: jekyll? github.io dns alias?
07:01michaelr`slipset: thanks.. looks like exactly what I'm looking for
08:52vasHi, I want to associate a username with the session using Ring. It seems like there is a simple way to do this...
08:53augustlvas: are you using the ring-session middleware?
08:56vasaugustl: yes, well, wrap-session.
08:57augustlvas: what is it that doesn't work in your code?
09:00vasi'm not sure how to associate the email with the session. i got an error for the number of args to assoc..
09:01augustlvas: how did you invoke assoc?
09:02augustlvas: generally the idea is to return a response map that contains a "session" key, then you'll get that back in the request the next time, via the session
09:04vasOh I see. my invokation of assoc works now... so session is essentially for subsequent requests. that makes sense
09:05vasdoes it make sense to do something like (GET "/page" [arg1 arg2 :as session] ... ) ?
09:05vasi'm under the impression that that will cause the whole request map to be stored :as session
09:07augustlvas: yep, but it's probably better to name it "req" or "request" since :session is one of the many keys in the request
09:08vasaugustl: ah okay, thank you. so if i wanted to persist a username it would be appropriate to store it in :session? does that make that key a map itself?
09:10augustlvas: only the things you put in :session will be put in the session
09:10augustlnot sure whether or not it's appropriate in your case :)
09:15vasaugustl: thanks :] so basically i'm going to set some part of :session to have the user's email, and somehow it'll have to check the session for every request to other pages to make sure the user variable is set. this is fun, learning about middleware by hacking together my own implementation. do you know how cookies fit into this picture?
09:29sdegutisHi, I'm having trouble porting this line to ClojureScript: new NW.Menu({ type: 'menubar' })
09:30justin_smithin clj that would be (NW$Menu. {:type "menubar"})
09:30Glenjaminorly, i always thought you had to do (-.Menu js/NW)
09:30justin_smithGlenjamin: that's probably the right way in cljs
09:30Glenjaminyou need a #js in there too justin_smith i think
09:31justin_smithGlenjamin: I said "in clj", but yeah
09:31Glenjaminoh, i see
09:31Glenjamini misread
09:47justin_smithnoncom|2: yes, that's the right way to call a varargs method with 0 of the optional args
09:47noncom|2justin_smith: oh well :)
09:48justin_smithnoncom|2: "varargs" are a fiction of javac that has no existence on the bytecode level, on the bytecode level it's just "array as the last arg"
09:48noncom|2yeah, that is how i guessed to put that (into-array) there..
09:49noncom|2stepped twice upon the thing today..
09:49justin_smithso it doesn't recognize the varargs method without the empty array there
09:53sdegutisThe solution I got from #clojurescript does not work: https://gist.github.com/sdegutis/03c30f1a8a5427d6e78b
09:55justin_smithsdegutis: hmm, that looks like what Glenjamin suggested. It doesn't work?
09:55Glenjaminsdegutis: does (new (.-Menu nw)) work?
09:55sdegutisGlenjamin: that is a compile-time error, because the second arg to new must be a symbol
09:55Glenjamineugh
09:55sdegutis(that was my first attempt)
09:57sdegutisPerhaps it's time for me to just bite the bullet and learn JavaScript.
09:58Glenjamini've found cljs to be a bit clunky at interop when dealing with JS that uses objects like hashmaps
09:58Glenjaminbut a few macros/helpers and it's not too bad
10:07sdegutiswelp, my hope in clojurescript is all gone
10:07sdegutisgonna try purescript again
10:20nonrecursivein case anyone’s interested in checking out Boot, I wrote an article that covers the concepts behind it http://www.flyingmachinestudios.com/programming/boot-clj/
10:21agarman@nonrecursive you have a quick boot v lein pitch?
10:22mnngfltgnonrecursive, thanks, I'll read it
10:23nonrecursiveagarman: erm not really, I just think boot’s fun to at least learn about because it’s built on well thought out abstractions that I haven’t seen in other build tools
10:26zerokarmaleftboot's logo is cuter. lein's logo has a more gentlemanly moustache.
10:26justin_smithagarman: I thinkthe big selling point of boot over lein is theoretically going to be lower overhead / better startup time. If you have tried starting things up with / without lein you'll see a pretty big difference.
10:27agarmanyeah, lein repl is slower than old school java script is slower than nailgun
10:27vasSo I am using crypto.password.scrypt to make an authentication token... unfortunately sometimes it generates forward slashes in the hashed result string... which is no fun when playing with ring destructuring syntax... i was thinking about just wrapping this up with yet another layer of encoding, perhaps there is a better easier simpler stronger faster kanye west better stronger idea?
10:27agarmanI'd be inclined to use something other than lein if it handles deps, is extensible and integrates with nailgun :-)
10:29nonrecursiveagarman justin_smith yeah, the speed is definitely one thing I’ve been enjoying about boot. You can also load dependencies without having to restart your repl
10:30justin_smiththat can be done via pomegranate or alembic/still with lein, but cool to know you can do it directly with boot
10:36vasi realized i can just replace the offending characters with a known string ^.^
11:00justin_smithvas: since it is being used in a URL, just URL-encode it ##(java.net.URLEncoder/encode "a/b/c.d%&e" "UTF-8")
11:00lazybot⇒ "a%2Fb%2Fc.d%25%26e"
11:01vasjustin_smith: way to be helpful and boring at the same time, I was translating it to "EEPAFORWARDSLASH" lol. thank you for your help ^.^
11:01justin_smithheh
11:02vaspresumably i have to url-decode it as well?
11:02justin_smithvas: depends how you are using it
11:02justin_smithif you generate the token just to recognize the same token again, you can just register the encoded version
11:02justin_smithbut you can also decode it if you prefer - I don't see how that would help though
11:03justin_smithI assume you save the token to the session, you can just save the version that is already encoded
11:04vasi'm stumped on how to save it to the session, but i'm learning about it now
11:04justin_smithvas: (assoc-in request [:session :super-secret-special-token] "token string")
11:05vasthank you. :D
11:05justin_smithand pass that forward as the new value of the request from your middleware
11:20IntegralistDoes anyone know how you can reference a function from another namespace when that namespace uses a macro to create the function?
11:20vasIntegralist: do you want to reference the macro?
11:21justin_smithIntegralist: the way the function is created doesn't matter
11:21justin_smithIntegralist: if it has been created at the time your code is compiled, you can refer to it as usual
11:22justin_smithIntegralist: if it is created at runtime, you'll need to wait until runtime to resolve it
11:22justin_smiththe resolve function helps with this
11:22justin_smith(doc resolve)
11:22clojurebot"([sym] [env sym]); same as (ns-resolve *ns* symbol) or (ns-resolve *ns* &env symbol)"
11:22justin_smith,(resolve '+)
11:22clojurebot#'clojure.core/+
11:22justin_smithwhat happens here is unlike directly using +, it doesn't have to exist yet when your form is compiled
11:23justin_smiththough if the var doesn't exist at runtime, this will be a runtime error
11:36Integralistjustin_smith: thanks I'll take a look at the resolve function.
11:37Integralistjustin_smith: effectively I have a macro that's called at run time which generates a function. but I'm getting an error to say the function that's generated doesn't exist
11:39justin_smithIntegralist: right, because you reference it before it exists
11:39justin_smith,((resolve '+) 2 2)
11:39clojurebot4
11:39justin_smiththat's how resolve is used
11:39justin_smithpretty simple
11:39justin_smithsince resolve only sees a symbol, there is no compile time error if that symbol can't be resolved yet
11:40justin_smithyou are also forgoing the basic error checking of the compiler of course - the advantage of not using resolve is that a typo in the function name would be caught
11:40justin_smith(and also resolution of a var is better done once at compile time rather than on every call, if you have the choice)
11:41justin_smithsince it has an overhead
11:41Integralistjustin_smith: so that didn't work for me. I get the error "Can't refer to qualified var that doesn't exist". I'll throw up a gist in a second to demonstrate what I'm doing
11:42justin_smithIntegralist: what was your arg to resolve?
11:44Integralistjustin_smith: here's a gist that shows three namespaces: the first https://gist.github.com/Integralist/b347b6f19d77af095550#file-macro-issue-clj-L1
11:44Integralistthe second https://gist.github.com/Integralist/b347b6f19d77af095550#file-macro-issue-clj-L21
11:44Integralistthe third https://gist.github.com/Integralist/b347b6f19d77af095550#file-macro-issue-clj-L30
11:45Integralistjustin_smith: in the first ns I def a macro that creates a function.
11:45justin_smithIntegralist: instead of 'utils/endpoint spell out the full ns name 'spurious-aws-sdk-helper.utils/endpoint
11:46justin_smiththat's pretty much what the error message was telling you
11:47Integralistjustin_smith: can I still use `:as utils` (for the other places in the ns that use code from that ns)
11:47justin_smithof course
11:47justin_smithit's just that resolve doesn't like the shorthand when resolving something that doesn't exist yet
11:48justin_smithnext trick of course is making sure that endpoint is created before the funciton that resolves/calls it is called
11:48justin_smith(clojure can't ensure that for you)
11:49Integralistjustin_smith: hmm, so I'm getting an error "Can't refer to qualified var that doesn't exist" for line 10 of core.clj (which is the reference to the macro def-endpoint)
11:50Integralistjustin_smith: I've tried using the full ns for that as well
11:50justin_smithdoes def-endpoint exist at the time that is compiled?
11:50justin_smithalso, btw, (do) inside defn body is not needed
11:52Integralistjustin_smith: oh! I thought `do` was needed for multilines of a function. That's good then :-)
11:52Integralistjustin_smith: so at the moment I'm in a repl and I'm calling `(use 'spurious-aws-sdk-helper.core :reload-all)`
11:52justin_smithso, def-endpoint is going to expand to a definition of "endpoint" inside the ns where it is called
11:52justin_smithis that what you want?
11:54Integralistjustin_smith: if we look at https://gist.github.com/Integralist/b347b6f19d77af095550#file-macro-issue-clj-L23-L28 effectively I expect nothing to happen as I've not executed any code to execute the `configure` function which would subsequently execute the call to `defmacro` - unless this is another case of `def` when `defmacro` is evaluated immediately (the problem with that would be the defmacro reli
11:54Integralistes on an arg provided by the user).
11:55justin_smithIntegralist: it might simplify things if instead of putting things inside functions, you use delay, and then use @ to force the delay and deref it
11:56Integralistjustin_smith: how would that work in this instance? sorry if that's a stupid question; I guess I'm still not clear on the use of delay
11:57justin_smithhmm, taking another look to make sure that would actually help here...
11:59Integralistjustin_smith: looking at delay docs it seems that you say "do X the first time I'm called, and then do Y for every subsequent call"
12:00tomjack"then be Y"
12:00tomjack(where Y is the result of doing X)
12:01justin_smithIntegralist: a delay is like a var or atom that can only change value once - from "unbound" to the result of evaluating its body
12:01sdegutisWhat's a superlative technique for branching off based on predicates for a given expression such as string?, vector?, seq?, nil? etc
12:01sdegutisRight now I'm doing this: (cond (string? thing) ... (vector? thing) ... etc)
12:01justin_smithsdegutis: I'd hardly call multimethods superlative, but they are nice enough for me
12:02sdegutisDo multi-methods work the same in ClojureScript?
12:02justin_smithyeah, they should
12:02sdegutisGreat, thanks.
12:02sdegutisI'll re-learn them.
12:02justin_smithmulti with dispatch on type of the first arg
12:03Integralistjustin_smith: just not sure if delay fn would help in this example because if I call `(@utils/def-endpoint type)` the first time it would do something (not sure what) and then it would do what it was supposed to do (which is generate a function) but I'm not sure when I would call @ to deref it again to execute actual function created.
12:03justin_smithsdegutis: they aren't hard, and are much cleaner than a condp on type usually (which is what I would use instead of a cond)
12:04sdegutisThanks justin_smith.
12:04justin_smithIntegralist: no, this isn't a case for delay - though it could be with a much more radical restructuring I think
12:04justin_smithIntegralist: it just feels like a big tangle of runtime binding that could be simplified
12:05justin_smitha defn with a form inside it that creates another defn is usually a bad sign
12:06Integralistjustin_smith: the idea was that the user calls one function and passes in a 'strategy' of sorts, in this case they pass in X or Y. If it's X, then the subsequent function that gets called using a different map structure to what would be used if they passed Y
12:06justin_smithIntegralist: in that case we have multimethods and protocols that are designed for that kind of usage
12:06Integralistjustin_smith: and I didn't want a function that ultimately had an if statement inside of it so I assumed a macro would be better
12:07Integralistjustin_smith: by multi-method are you referring to multi-arity?
12:07justin_smiththe lib would define a multimethod or protocol, and the app would pass in something fulfilling that
12:07justin_smith(doc defmulti)
12:07clojurebot"([name docstring? attr-map? dispatch-fn & ...]); Creates a new multimethod with the associated dispatch function. The docstring and attr-map are optional. Options are key-value pairs and may be one of: :default The default dispatch value, defaults to :default :hierarchy The value used for hierarchical dispatch (e.g. ::square is-a ::shape) Hierarchies are type-like relationships that do not depend upon type inheritance. By default Clo
12:08justin_smith$grim clojure.core/defmulti
12:08lazybothttp://grimoire.arrdem.com/1.6.0/clojure.core/defmulti
12:08justin_smithIntegralist: see the examples in the above link
12:08justin_smithI think it will simplify your code a lot
12:09Integralistjustin_smith: cool, looking at multimethod now
12:11justin_smithIntegralist: protocols are similar in usage, but only dispatch based on type (which should be fine in your case) and allow defining multiple methods, all part of one overall protocol
12:17dysfun#<CompilerException java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest, compiling:(ring/middleware/multipart_params.clj:46:5)>
12:17dysfunanyone know why i'm seeing that?
12:17dysfunb
12:18justin_smithdysfun: are you trying to aot compile a war file?
12:18dysfunno, that's just when i type 'lein repl'
12:18Lewixif I understand correctly, vars in clojure are kind of like constant right?
12:19justin_smithLewix: they are mutable - though in practice we only mutate them during development via the repl
12:19justin_smithin sane code at least
12:21Lewixjustin_smith: so does it mean they are used as constants however they behave like variables defined at the top level
12:22Lewixjustin_smith: great book between. I ordered it
12:24Lewixapprently people define vars as such: vars are not variables. great! but what are they then?
12:24justin_smithLewix: yeah, in sane code you can assume they are constant. You can capture them in let bindings or function args (equivalent) to ensure they are only resolved once and are then truly constant in that scope
12:24justin_smithLewix: well, vars actually are variables. Though they do have some features for coordination of their mutation
12:25Lewixjustin_smith: programming clojure keep on saying they're are not variables
12:25justin_smithhmm...
12:25noonianLewix: they are the thing that binds free variables to functions or values at the top level (free variables being anything not a formal parameter or let bound local)
12:26noonianthey are mutable but that is mainly for interactive development so you can redefine things, but in your actual program you normally shouldn't redefine top-level vars
12:27LewixI see . thanks guys
12:27justin_smithLewix: so perhaps we can pedantically say, contradicting "programming clojure" "vars are variables, but shouldn't be treated that way"
12:28Lewixjustin_smith: i like that
12:29Lewixjustin_smith: noonian definition was pretty good
12:30Lewixjustin_smith: it's definitely clearer than just saying. they're not variables
12:33justin_smithoh yeah, noonian's explanation is quite good
12:33justin_smith(inc noonian)
12:33lazybot⇒ 13
12:44sritchieDomKM: looks like my hack fails on unmatch, unfortunately
14:38DomKMsritchie: Uh oh :(
14:39sritchieDomKM: just because unmatch turns the seq of routes into a map
14:39sritchieso duplicate keys get knocked
14:39sritchieworked around it for now
14:42vasis there a reason why ring response would prompt a file download (containing the response string ) instead of just printing it to the browser?
14:42DomKMsritchie: Ah, sorry about that. Thanks for working around it for now. :)
14:43justin_smithvas: you need to set the content-type
14:43justin_smithvas: a browser prompts for a download if it doesn't know if it can display it (common cause of that, not setting the right content-type)
14:43vasjustin_smith aha. so response in the barebones http talkback.
14:44vasthank you justin
14:44justin_smithnp
14:45justin_smithvas: general idea is {:headers {:content-type "whatever"} :body (generate-body-string) :status 200 :session {some session-data}}
14:45justin_smiththere are middleware to help with automatic content-type setting, but sometimes you just need to set it by hand
14:46vasvery cool. i don't think i have ever been more intimate with http than i have working with clojure
14:46justin_smiththis is a much saner version of http :)
14:46vasso what would an idiomatic way to set the content type of a response look like?
14:47justin_smithvas: associate :headers {:content-type "text/html"} to your response map
14:47justin_smithor whatever the apropriate content-type is
14:47noonianif you have your routes organized into page-routes, api-routes etc you could put it all in middlewares and apply them to the different handler sets
14:48justin_smithnoonian: that's an excellent point
14:49vasyeah. that will be cool and fun to do. i'm starting to see where the layering of my app is happening..
14:54vasthank you for the suggestion noonian
14:55noonianvas: no problem, justin_smith did most of the helping :P good luck and enjoy learning Clojure!
14:56vas:D i just got the login/session functionality to work, ecstatic.
14:57vason behalf of this successful mission i'd like to thank justin smith, tupac shakur, rich hickey, the wutang clan...
14:58justin_smithnice
15:01vasso on a bunch of pages i'm going to be verifying the contents of the :session values... rather than doing it individually for each route, i can make a middleware that applies that step to given routes?
15:01justin_smithof course
15:01justin_smiththe generel outline of a middleware is (defn mid [handler] (fn [request] (handler (frob request))))
15:02justin_smith*general
15:02justin_smithso inside your frob you could redirect to an error page
15:02justin_smithor invalidate the session
15:02justin_smithor redirect to a login
15:02justin_smithor whatever
15:02justin_smithin fact, you can avoid calling the handler altogether and just hijack the whole thing
15:03justin_smith(if that's called for)
15:03nooniani'd recommend making the middleware do the verify logic, and then only apply it to specific handlers you want to do the verifying
15:03noonianinstead of the middleware figuring out which routes to verify
15:03justin_smithindeed
15:03kaplan_what is a middleware?
15:04justin_smithkaplan_: a function that wraps another function - usually in ring as a way to add a feature to a website
15:04SegFaultAXkaplan_: A function that is applied before, after, or around your handler.
15:04kaplan_ah ok
15:04sobelwhen i was into AOP, those were called 'advice'
15:05sobelor advisor functions
15:05sobeliirc
15:05SegFaultAXsobel: They're just normal functions. There's nothing special going on here.
15:05sobelSegFaultAX: yeah, they don't have to be special in lisp
15:05SegFaultAXYou could also call them "decorators" if you wanted to make them sound even more magical.
15:05justin_smithSegFaultAX: sure, but it's not like advice functions are that special
15:05justin_smithhaha
15:05SegFaultAX:)
15:06sobelSegFaultAX: ugh, haha, i remember that set of terminology...much hated :)
15:06SegFaultAXjustin_smith: Yea I know, that's my point. It's all just functions.
15:06vasi don't suppose a tutorial for such an endeavor would exist? (=
15:06SegFaultAXvas: For what?
15:06justin_smithright, one more "design pattern" that's just business as usual once you are in fp world
15:06sobelthe invocation of advisors was usually magical
15:06sobelsame as annotations
15:06sobeljustin_smith: which is why i'm here. in a nutshell.
15:06justin_smithsobel: right, because they don't have our magic they have to invent their own flavor
15:07SegFaultAXWell annotations (as in Java) *are* different.
15:07justin_smithsure, but we can do most of what annotations are used for
15:07SegFaultAXBecause they can be expanded and/or take effect at different times (compile time, run time, etc)
15:07vasfor making a middleware than will check my session values .. and applying the middleware to only a subset of routes.. the principle is clear but i'm not sure what it looks like in practice
15:07justin_smithwithout needing to directly use that feature. And yeah they are weird.
15:08SegFaultAXjustin_smith: I don't know if this is true, but intuitively I'd guess that macros are more or less equivalent to annotations.
15:08SegFaultAXOr at least, you can recreate the effects of annotations with macros.
15:08sobelsomething like that
15:08justin_smithSegFaultAX: some of the features of annotations are also available via metadata
15:08justin_smithin terms of functionality at least
15:08SegFaultAXYea, hmm.
15:09justin_smithbut, of course, macros can put metadata on things at expansion time
15:09justin_smithso it still fits
15:10noonianvas: here's an example of a simple middleware to print requests and responses, the one you want will be inspecting values in request (the :session key in particular) https://www.refheap.com/97320
15:11amalloyyeah, annotations look a lot more like compiler-directed metadata to me
15:11vasnoonian: wow thanks kind sir
15:11justin_smithnoonian: that's a lot of characters to spell out "frob", hehe
15:12nooniana middleware is just a function, so before you pass your handlers to jetty or w/e just have something like (def routes-with-middleware (map spy-middleware my-handlers)) and pass routes-with-middleware to jetty or w/e
15:12benhudahi guys
15:12justin_smithhello
15:12noonianjustin_smith: heh
15:12benhudaso im sketching out a sort of ad-exchange bidding proxy - get a request, and then make N requests to N services in real time - and return a selected best offer back to a user.
15:13benhudai'm wondering how Clojure is fitting this problem space. I can understand Node.js and Go will be good at this because they're both by default using async IO
15:13benhudais there anything in Clojure that can supply an equivalent answer?
15:13sobelClojure is also pretty useful for async IO
15:14SegFaultAXbenhuda: The JVM has first class support for asyncio through nio
15:14sobelgo routines and channels are part of clojure, if you're familiar with those from Go
15:14SegFaultAXAnd netty is pretty great, there are a few wrappers for it.
15:14SegFaultAX(Well, the netty /API/ is complex and sometimes hard to understand. But performance wise, it's awesome)
15:14benhudaSegFaultAX: to be honest - as a matter of personal taste i would like such a thing to come as a facility of the language or a tightly knit library (rather than touch netty API or nio API directly)
15:15justin_smithbenhuda: nio is tightly nit - interop in clojure is trivial
15:15justin_smith*knit
15:15justin_smithand you don't need to touch it's api, there are wrappers using ring
15:15sobelbenhuda: you should search the web for examples of async functionality in clojure.
15:15benhudahow easy will it be to create such a reverse-proxy load balancer?
15:16benhudasobel: i'm aware of clojure async - i just am not sure it's async io
15:16sobelbenhuda: what else would it be?
15:16benhudaa way to abstract threading? a syntactic sugar around promises?
15:16justin_smithbenhuda: we have actual threads - we can do async even when the io can't be async. But via nio / netty we have async io
15:16SegFaultAXsobel: core.async is not about async io at all.
15:17benhudasobel: ^^
15:17noonianbenhuda: core.async is a way to coordinate asynchronous stuff
15:17benhudayes, right. thats why i'm wondering out loud regarding async/io (without really touching nio or netty)
15:17noonianso it could be useful in managing your logic but the actual async io would be performed by different libraries/apis
15:18SegFaultAXbenhuda: What do you mean "without really touching nio". That's the JVMs facility for async io.
15:18justin_smithbenhuda: if you use aleph or http-kit you don't have to touch the netty or nio apis to get async request handling
15:18SegFaultAXPrior to nio, all JVM IO was sync/blocking.
15:18benhudajustin_smith: ah! right, aleph was the library i couldnt recall
15:18justin_smithSegFaultAX: right, but he doesn't have to write code that interacts with the nio api directly
15:18justin_smithhe can just use the ring api
15:19SegFaultAXYup.
15:20justin_smithbenhuda: most ring servers will assign one thread per request (which allows parallelism but not the most efficient possible usage of cores, of course), with aleph or http-kit you get async handling using multiple threads, to make the most of your resources, and best possible response times
15:20benhudayes
15:20justin_smithbut from your handler code's point of view, it's still straightforward
15:21justin_smithno need to write things in terms of callbacks or whatever
15:21benhudaso now im asking myself - if i were to solve this problem - think of building a load balancer, which is also a reverse proxy, is there a way i can do the calls with async io?
15:21tbaldridgethere's also pedestal that accepts core.async channels for async responses
15:21justin_smithbenhuda: sure, we have a couple of good http async libs
15:22benhudaand there's no danger using those libs on ring which runs on, say, Jetty ?
15:22tbaldridgewell ring is sync, so you can't really run async code on it at all
15:23benhudaso i guess i still have a block of blurriness for these use cases in clojure
15:23benhudamaybe i can rephrase
15:24benhudais there a smooth/easy way to do event driven I/O in clojure? like Ruby's EventMachine for example
15:25tbaldridgesure, aleph, http-kit (to some degree) and pedestal all offer that for HTTP, and other libraries offer it for other types of IO
15:26benhudaim curious - what other types of IO?
15:26noonianthe answer to 'can you do X in Clojure' is usually 'Yes' unless X needs to startup fast or run somewhere without a JVM
15:26justin_smithbenhuda: disk IO for example
15:26justin_smithor raw socket IO
15:26benhudaasync IO for files? only windows supplies that
15:27justin_smith?
15:27arohnerbenhuda: no, JVM NIO can do it as well
15:27justin_smiththat's patently false
15:27arohneron unix
15:27benhudais there a kernel facility for async file IO?
15:27arohneryup
15:27arohnerthere are several
15:27tbaldridgeyeah, stuff like Vert.X offers that sort of stuff in an abstracted way
15:27justin_smithbenhuda: it's a system call called "select" that has existed longer than windows has
15:27arohneron linux
15:27benhudaselect works on files too?
15:27arohneryup
15:28justin_smithyes, it was originally designed for watching multiple file descriptors
15:28justin_smithon unix everything is a file descriptor as far as the apis are concerned
15:28benhudahm. someone on the nodejs channel twisted my knowledge then!
15:28tbaldridge(not surprising)
15:28benhudawait ill try to find the log
15:28benhudaah crap. no logs, i had restart
15:28xemdetiaselect is for big data
15:28justin_smithbenhuda: on a linux system even memory regions or the audio device can be accessed as if they were files
15:28justin_smithor the mouse
15:28justin_smithetc.
15:29benhudaok well good to know my memory is still good. i should remember to doublecheck people on IRC myself :)
15:29justin_smithxemdetia: select is used for low level code where you have many potential sources of data in one thread
15:29vasnoonian: thanks man. here's what i have so far, https://www.refheap.com/97322 ... i'm not sure how to align the area by (def app ... ) so that it invokes the middleware "routes-with-sesh-verification"
15:29xemdetiajustin_smith, I was making a bad joke
15:29justin_smithxemdetia: ahh, ok :)
15:29xemdetiaI am on a conference call of sadness and this is all I have going for me
15:29arohnerxemdetia: :-)
15:29justin_smithhaha
15:29justin_smith(inc xemdetia)
15:29lazybot⇒ 2
15:30benhudaim really tempted to run this new venture all-clojure
15:30benhudai just want to make sure i have an async-io escape hatch
15:30justin_smithvas: that's not quite it
15:31benhudai remember from my last clojure project (2013) - i didn't find anything that were nice to work with
15:31tbaldridgebenhuda: what are you trying to build?
15:31justin_smithvas: you need to create the handler (you are probably doing this via compojure) then wrap logged-in-verify around the handler
15:31noonianvas: you have a couple issues here. logged-in-verify looks pretty good, but in the if check if things are good thats where you should put the (let [response (ring-handler request] ...) or just (ring-handler request) and in the else put your error response.
15:32noonianlike justin_smith said your middleware expects a handler so you need to write a function that takes a request and returns a response and thats what you wrap with logged-in-verify
15:32benhudatbaldridge: one part data science, one part user tracking, one part ad server, one part ad exchange.
15:33benhudatbaldridge: i know there are a couple startups in this space that are all clojure so that's nice. i just have no clue how they do scalable async IO, if they do at all. i know at this field i need to be anal about latency and performance
15:38noonianvas: i updated your refheap a little bit to try and make it clearer: https://www.refheap.com/97323
15:40jlewis_is there a way to write an inline macro like you can write an inline function?
15:41amalloyjlewis_: by inline i suspect you mean local or lexical?
15:41amalloythere is clojure.tools.macro/macrolet
15:41michaelr`benhuda: sounds like most of the heavy lifting could happen in the tools you'd use and not necessary in your clojure code..
15:42jlewis_that works, i was wondering about a #() equivalent
15:42amalloyno
15:42sobelmichaelr`: yeah, i was thinking, this has sql/openresty written all over it, from my perpsective
15:46jlewis_i'm trying to abuse the for macro to give me all permutations from a set of sets - like from [1 2] [2 3] i get [[1 2] [1 3] [2 2] [2 3]]
15:47jlewis_i'm wishing i could generate the binding vector inline, but i need to make a macro for it above my for expression
15:47jlewis_(right?)
15:48dmbennettjlewis: kind of like find all the subsets of a given set?
15:48dmbennettfindign*
15:48dmbennettfinding*
15:48dmbennettwow, I hate this keyboard
15:48jlewis_sort of, but each element in my output vector is drawn from a different input set
15:49dmbennettinteresting
15:50vasnoonian: thanks it looks beautiful! =)
16:30ajmagnificoanyone: is there a clever way of doing inner and full outer joins in incanter? Googling around provided some solutions that just looked kind of hackish. Does incanter really not support full outer and inner joins between two DAtasets?
16:34nicferrierjustin_smith: thanks for your help.
16:36gfredericksjlewis_: ##(for [a [1 2], b [2 3]] [a b])
16:36lazybot⇒ ([1 2] [1 3] [2 2] [2 3])
16:36gfredericks^ is that not what you wanted?
16:36gfredericksor is the problem that you have a variable number of sets?
16:37jlewis_yeah variable number of sets
16:37gfredericksyou're describing a cartesian product I think
16:37jlewis_right there you go
16:37gfrederickswhich is in the math.combinatorics lib
16:37gfredericksand also pretty easy to write recursively
16:40gfredericks,(defn cartprod [xss] (if (empty? xss) [[]] (let [things (cartprod (rest xss))] (mapcat (fn [x] (map #(cons x %) things)) (first xss)))))
16:40clojurebot#'sandbox/cartprod
16:41gfredericks,(cartprod [[1 2] [2 3]])
16:41clojurebot((1 2) (1 3) (2 2) (2 3))
16:41gfredericks,(cartprod [[1 2] [2 3] [:a :b :c]])
16:41clojurebot((1 2 :a) (1 2 :b) (1 2 :c) (1 3 :a) (1 3 :b) ...)
16:48justin_smithnicferrier: oh, np
16:49justin_smithnicferrier: so you got your logging thing sorted out?
16:49nicferrierjustin_smith: yep, although it's a bit hacky. it works.
16:50nicferriercurrently investigating using a classloader in leiningen to make that faster.
16:52justin_smithnicferrier: wait, a classloader in leiningen to make what faster? if you mean overall app startup, you should probably be using lein uberjar to make a runnable jar that doesn't use lein at runtime
16:53nicferrierjustin_smith: no. I don't mean that. I mean starting lein and clojure in a jvm and then having compilation and run and package and all that occur in a classloader. so you can throw it all away all the time.
16:53nicferrierapparently the reason it wasn't done like that was "jetty".
16:53justin_smithahh
16:53nicferrierbut it seems like it would be a good thing to do.
16:54nicferrierit would certainly reduce a lot of nrepl madness.
16:54justin_smithnicferrier: see also lein trampoline
16:55jlewis_,(defmacro m [sets] (#(let [syms (repeatedly (count sets) gensym)] `(for [~@(interleave syms sets)] [~@syms]))))
16:55clojurebot#'sandbox/m
16:55nicferrierjustin_smith: that doesn't use classloaders tho I think. it somehow saves the state of the vm?
16:55jlewis_,(m [[1 2 3] [4 5]])
16:55clojurebot([1 4] [1 5] [2 4] [2 5] [3 4] ...)
16:55jlewis_gfredericks: ^^ heh
16:55justin_smithnicferrier: it just avoids starting yet another vm
16:56nicferrierjustin_smith: right. didn't seem as efficient as using a classloader to constantly throw away the project on top of lein.
16:56jlewis_er, don't need that #() either
16:57nicferrierjustin_smith: well. presuming lein has the clojure that the project wants.
16:57jlewis_,(defmacro m [sets] (let [syms (repeatedly (count sets) gensym)] `(for [~@(interleave syms sets)] [~@syms])))
16:57clojurebot#'sandbox/m
16:57jlewis_,(m [[1 2] [4 5]])
16:57clojurebot([1 4] [1 5] [2 4] [2 5])
16:57nicferrierjustin_smith: I'm not really clear why it hasn't been done this way.
16:58justin_smithnicferrier: have you looked at boot at all? it's a fresh approach to this stuff (I haven't used it yet myself, but one of their stated goals is faster startup)
16:58nicferrierjustin_smith: going to look now.
17:00nicferrierjustin_smith: interesting... but also... sigh.
17:00nicferrierwas this the thing that is just programs?
17:00nicferrierthat was the latest build thing a while ago. no more declarative! just programs!
17:01justin_smithyeah, imperative rather than declarative tasks
17:01justin_smithright
17:01nicferrierright. now I'm looking at their bootstrap site rather than their github I see that.
17:03gfredericksjlewis_: that only works when the collections are literals though, which means you still have to know the number of collections at compile-time and may as well have written the for by hand
17:04nicferrierjustin_smith: thing is ... I need windows and I don't need exe's.
17:05nicferrieris a nice idea though.
17:06nicferrierdoes feel like they're onto something.
17:19jlewis_gfredericks: mm that is true
17:19cespareis there an idiomatic way to do required kwargs?
17:21justin_smithcespare: I'd say prismatic/schema if you want real data validation, or roll your own doseq / assert if you don't need schema's other features
17:21hyPiRionrequired kwargs? I'd just make them args.
17:22cesparehyPiRion: i've got some functions with enough args that I'd rather not
17:22hyPiRionDepends on context, of course. If you want to have a similar api then it's probably better to do assertions or something.
17:22cespareit's nasty plumbing stuff like passing connection options around
17:23cespareanyway thanks justin_smith, i'm doing the doseq/assert right now so I'll probably just stick with that
17:23cesparethanks
17:23justin_smith(doseq [required [:a :b :c]] (assert (contains? opts required) (str (pr-str opts) "does not contain" (pr-str required)))
17:24cespareor i could (defmacro defn+ ... ) to allow {:keys [...] :required [...]} ;)
17:24cesparejk
17:24justin_smithwell, you could. I don't know if you need to go that far with it, but it is possible
17:25cespareime you have to exercise a lot of good judgement around the what's good vs. what's possible boundary to write good clojure :D
17:28justin_smithcespare: (defmacro is-required [m ks] `(let [m# ~m] (doseq [k# ~ks] (assert (contains? m# k#) (str (pr-str m#) " should contain " (pr-str k#))))))
17:28justin_smiththen you can do (is-required opts [:x :y :z])
17:29justin_smithactually, that doesn't even need to be a macro
17:30justin_smith,(defn is-required [m ks] (doseq [k ks] (assert (contains? m k) (str (pr-str m) " should contain " (pr-str k)))))
17:30clojurebot#'sandbox/is-required
17:30justin_smith,(is-required {} [:a])
17:30clojurebot#<AssertionError java.lang.AssertionError: Assert failed: {} should contain :a\n(contains? m k)>
17:31justin_smith,(is-required {:a 0} [:a])
17:31clojurebotnil
18:31crash_epwhy is defonce used so much more frequently in clojurescript than in clojure?
19:01AeroNotix,(doc defonce)
19:01clojurebot"([name expr]); defs name to have the root value of the expr iff the named var has no root value, else expr is unevaluated"
19:13justin_smith"No one loves you, for love does not exist. Nothing matters. Enjoy Valentine's Day.
19:13justin_smithYour local Arby's awaits."
19:13justin_smithoops, wrong window, sorry
19:14TEttingerclassic
19:14gfredericksjustin_smith: kind of a cumbersome password if you ask me
19:14justin_smithFriday the 13th eve: test your luck at Arby's. feed the abyss. die anyway. Luck's a pointless abstraction, as is life. Arbys: God hates you.
19:15TEttingernihilist sandwich shop
19:15justin_smithmy new favorite twitter account
19:15justin_smithhttps://twitter.com/nihilist_arbys
19:17justin_smithgfredericks: actually, compared to most passwords that hard to guess, it would be quite easy to memorize
19:18justin_smithSo I only use it for things that need to be super secure, of course
19:18justin_smithlike IRC
19:18arrdemclojurebot: ping
19:22LewixNote that let is implicitly used anywhere locals are required
19:22Lewixwhat does that mean
19:22justin_smithanything that creates locals is either going to call let, or have a macro that expands to a call to let
19:23justin_smiththat would be my interpretation of that statement at least
19:24Lewixjustin_smith: oh I get it now. functions parameter use let implicitly to be bound as locals
19:25tomjackthey don't, though, do they?
19:25Lewixjustin_smith: do you use clojure in your day to day job
19:25Lewixtomjack: apparently yes
19:25justin_smithtomjack: well, they do use let for destructuring
19:25justin_smithLewix: yes
19:26tomjackah, yeah
19:26justin_smithLewix: I work on backend web stuff, using clojure
19:26Lewixjustin_smith: I might job hunt for a job that uses clojure to learn faster
19:26justin_smithLewix: sink or swim can work, yeah :)
19:27Lewixjustin_smith: However, there's no many in Canada =)
19:27justin_smithwhat part? I know of one company up there
19:27justin_smithbut it's a big country
19:30gfrederickssort of
19:31justin_smithgfredericks: regarding let/ fn? yeah, not all function bindings translate to let of course
19:31gfredericksno I meant "big country"
19:31justin_smithahh
19:32Lewixjustin_smith: toronto
19:33Lewixa big country geographically , a small country population wise
19:33justin_smithright, geography is the sense I meant
19:34Lewixhttps://gist.github.com/6ewis/ea8867dab84127495831 can someone explain to me line 2 ( _ )
19:34justin_smithI think living social has an office not far from you
19:34justin_smithLewix: by convention, _ is a name used for values you won't actually reference again
19:34justin_smithit's a way of saying "a binding has to go here, but I won't access that binding"
19:34justin_smithinformally
19:35Lewixright, but why is it needed at all in this case
19:35Lewixcan't we just right it without it?
19:35justin_smithLewix: because otherwise it wouldn't be a valid clause in a let binding
19:35justin_smithbecause let always needs binding / value pairs
19:35justin_smithhow would it line things up properly otherwise?
19:35Lewixahhhh
19:35Lewixthanks justin_smith
19:38Lewixjustin_smith: Also, I'm checkin living social now
19:56themanhi
20:02gfredericksare there any obvious use cases for clojure.core/pr being dynamic?
20:05amalloygfredericks: none that are obvious to me
20:12justin_smithweirdo custom printing code that dynamically rebinds pr?
20:12justin_smithI mean - it makes that potentially possible, but I don't know that anyone would really want to...
20:23gfredericksthe question is if calling pr on e.g. a collection will end up calling it on the elements
20:23gfredericksor if once you hit print-method you stay in print-method
20:23gfredericksin the latter case it seems less useful
20:49gfredericks,(doc *agent*)
20:49clojurebot"; The agent currently running an action on this thread, else nil"
20:49gfredericks^ I've never once used that
20:50gfrederickscan't think of a use for it
20:53justin_smithgfredericks: violating abstraction?
20:55justin_smithgfredericks: since you are around, what's the name for an algorithm that would take, eg. a uniform distribution as input, and output a bell curve distribution of values
20:55justin_smithgfredericks: it can be done with interpolation and table lookup, but I don't know what it is actually called - nonlinear mapping maybe?
20:57justin_smithif the input is -1 to 1, it can be calculated by raising it to some odd power
20:57gfredericksjustin_smith: I don't know nuthin about names of such things
20:58justin_smithOK
20:58gfredericksso gaussificator seems reasonable
20:58justin_smithgausifier
20:58justin_smith"the baby's getting flat again honey, get him is gaussifier"
20:59justin_smitha healthy baby will of course have a nice bell curve of bodyfat
20:59gfredericksj.u.R has a gauss thing
21:00justin_smithit can also be calculated via a polynomial - you take your initial curve, interpolate to a polynomial, then use that polynomial to do the mapping
21:01justin_smithI hate having like 1/4 of a grasp on the concept, but none of the right keywords
21:01benmossis there a way with clojure.test/run-tests to exclude tests based on metadata?
21:01justin_smithbenmoss: this is something lein test will do
21:01benmossthis library im looking at has (deftest ^:benchmark ...) on some
21:01justin_smithbenmoss: but you might have to use lein's code, or write it yourself
21:01benmossbleh, i hate the slowness of lein test
21:03justin_smithbenmoss: you could use a fixture that checks the metadata and decides whether to run the test or not based on said metadata
21:03justin_smithbut that would be per-ns
21:03gfredericksI'd investigate how lein test does it
21:04justin_smithor wait, I think fixtures actually get the function itself as an arg, not the var (which would have the metadata)
21:05gfredericksha software.
21:05benmossmeh ill just comment out all the tests and restart my repl
21:06justin_smithit's faster to just conditionally unmap test vars that have a given metadata
21:06justin_smithand then reloading the file would bring them back again if you want a different set
21:06justin_smith(doc ns-unmap)
21:06clojurebot"([ns sym]); Removes the mappings for the symbol from the namespace."
21:06justin_smiththat's how one deletes vars
21:07justin_smithheh
21:08justin_smith"this shuts down the computer"
21:08gfredericksM-x flamethrower
21:16amalloygfredericks: you made me write https://www.refheap.com/bf192c465dae4b9c01fe0a698
21:17gfredericksmakes sense
21:17justin_smithhaha
21:17justin_smiththat's maybe more like a shotgun
21:18justin_smithI would imagine a flamethrower singing edges (ie. taking random chunks of the end of each line)
21:18justin_smithbonus points if it also makes flame-themed syntax highlighting
21:18amalloyit made me wonder: is this method of choosing a random subregion good, or would it be better to uniformly choose two numbers within the region and then treat one as the start and one as the end
21:18amalloythe second one appealed to me more, but what i actually did was easier
21:19justin_smithwhat you have now is biased toward the end of the document
21:19amalloyjustin_smith: that is what i thought too, but i couldn't actually be sure
21:19justin_smithI have used a similar algo for random placements of sonic events
21:19justin_smithamalloy: instead, pick a width first, and then randomly place the center within the constraints of the width
21:20justin_smiththat will actually be uniform
21:20justin_smith(and of course calculate bounds based on that center)
21:20amalloyjustin_smith: i think my suggested other algorithm is just as good, isn't it?
21:20justin_smithamalloy: yeah, that would actually work too I think, and be simpler
21:21justin_smithbut probabilites are weird, so we should second guess things of course...
21:21amalloyyeah, i guess the problem with the algorithm i actually used is that the start point averages around the center, which means the midpoint averages 75% of the way through
21:21justin_smithexactly
21:22amalloyflamethrower don't care
21:23justin_smithwith common workflows, stuff toward the end of the document is more likely to be missed with a random deletion, right?
21:24amalloymaybe?
21:25justin_smithhere would be a fun one: M-x entropy
21:25justin_smithpicks a random char, and swaps it with a random neighbor
21:25justin_smithN iterations of this
21:25justin_smithbrownian motion within a document
21:26justin_smithdo it just a few times and it is hard to distinguish from typical typos
21:28amalloyjustin_smith: i bet i could write an algorithm to distinguish it from real, human typos would work like 90% of the time, if you gave me a file with either 5 typos or 5 real transpositions and told me which two characters were mis-ordered
21:28justin_smithhmm
21:28justin_smithyeah, you probably could :)
21:30amalloythe algorithm would be, if the two characters are typed with the same finger, it was a computerized transposition, and if typed with different fingers it was a real typo
21:30benmossbleh, is there any way to see a macroexpansion of a deftype's protocol implementation?
21:30benmossi bet that is not super clear let me provide an example
21:31benmosshttps://github.com/ztellman/manifold/blob/master/src/manifold/deferred.clj#L349-L351 implements deref via a macro, https://github.com/ztellman/manifold/blob/master/src/manifold/deferred.clj#L241-L257
21:32benmosshaving a problem with it, trying to debug it, but don't know what I can call macroexpand on here
21:32amalloybenmoss: you can just (macroexpand-1 '(deref-deferred timeout-value time TimeUnit/MILLISECONDS))
21:32amalloythe fact that it's inside a protocol definition has no bearing on how it expands
21:33benmossindeed
21:33benmossthanks
21:41justin_smithamalloy: https://www.refheap.com/97339
21:41justin_smithit works!
21:44justin_smithupdated (there was an off-by-one bug at the end of the buffer)
21:45justin_smithit's oddly soothing to watch a namespace decay into gibberish this way
21:46TEttingerwhat on earth is that, justin_smith?
21:46TEttingerthat refheap
21:46justin_smithTEttinger: it randomly swaps to characters in your current buffer
21:47justin_smithbrownian motion!
21:47TEttingerhahaha
21:48justin_smithI need to make it respect prefix arguments by doing N iterations
21:52gfredericksjustin_smith: how do you loop it?
21:52justin_smithnow prefixed and looped https://www.refheap.com/97339
21:53justin_smithmaybe it would be good to put a delay in too...
21:53justin_smithjust a small one
21:56justin_smithgfredericks: now it is animated, and will stop if you enter any editor command https://www.refheap.com/97339
21:56amalloyjustin_smith: M-100000 M-x entropy really wrecks a file
21:56justin_smithwow, OK, I might make an infinite version of that
21:57justin_smithI bet!
21:57amalloyi ran it on my .emacs
21:57justin_smithnice
21:57justin_smithtry the animated version if you haven
21:57justin_smith't yet
21:57justin_smithhuge improvement I think
22:01amalloyjustin_smith: sit-for is interesting. i think you mean (sit-for 0); (sit-for 0 100) is weird
22:02justin_smithamalloy: first arg is seconds, second is ms
22:02justin_smithI definitely don't want to wait more than a second between redraws
22:03justin_smithoh wait, that's sleep-for
22:03amalloyjustin_smith: sit-for says that form is deprecated and you should just use one fractional arg
22:03justin_smithright
22:03justin_smithbut it also waits for input, which I don't strictly want
22:03justin_smithI want the loop to keep going
22:04amalloyhave you tried it? they both seem to behave the same when given input
22:04justin_smithamalloy: ahh, that's much better
22:04justin_smiththansk!
22:05justin_smithupdated
22:06justin_smithinteresting that the algorithm keeps the cursor on a given character
22:14amalloyjustin_smith: i am still thinking about the randomness of these various algorithms, and i can't see how we conclude that my first algorithm is biased. it chooses uniformly from among all possible start points, and then uniformly among all possible endpoints given that start point
22:15amalloyso it ought to be selecting uniformly from all possible intervals
22:18justin_smithamalloy: think of adding up all stary poimts from which a given end point can be calculated
22:19amalloyi think i see what is going on
22:19justin_smith*starting points
22:20justin_smithalso you can do ot empirically with frequencies
22:20amalloyyeah, i did
22:20amalloyit's obviously not uniform
22:21amalloythe problem is that there are only 1 or 2 possible intervals starting at character 10000, and there are 9000 intervals starting at character 1000, but each are as likely to be selected as a start point
22:22amalloyso the 1 or 2 starting at 10000 get selected far too often
22:22justin_smithwriting a typo simulator right before leaving the house adds a new layer to the typos I do on mobile
22:23amalloyjustin_smith: i tried my suggested other algorithm by the way, and it is biased in a way we didn't think of: empty intervals are half as common
22:24amalloybecause there are two ways to get, say, (0 1), but only one way to get (0 0)
22:24amalloybut it's fine if you just remove those
22:25justin_smithoh, so 0,1 is empty by that method
22:25amalloyno, i mean 0,0 is empty
22:25justin_smithok.... I think I get it
22:26justin_smithpick size, pick center should be a fair method though
22:27djamesData structure question: one (naive) way to keep keys and values is with a hash, e.g. {1 true 2 true 3 true 4 true 5 false 6 true 7 true}
22:28djamesIs there a name for a data structure where the above is represented as {[1 4] true [5] false [6 7] true}?
22:28justin_smithdjames: are you looking for a set?
22:28amalloyjustin_smith: i dunno, i think it will run into the same problem as my original algo
22:28justin_smithoh, n/ m
22:28djamesjustin_smith: :) implementing this is easy, naively. just curious if there is a name for such a thing
22:28justin_smithI misread ay first
22:28amalloythere are 1000 possible sizes for a buffer of size 1000, but for eg size 999 there are only two possible intervals
22:29amalloyso you will over-select those two
22:29djamesno problem, it was a two part question
22:30justin_smithamalloy: mobius world would fix this (and sldo rescue the initisl slgorithm)
22:30amalloymobius?
22:30justin_smithlooped
22:31amalloyPS i just tried your algo empirically and it was biased in the way i predicted
22:31justin_smithmodulus style
22:31amalloyi think the only reasonable way to do it is my second way, picking two independent numbers and choosing the smaller as the start
22:32justin_smithamalloy: cool, I should have thought of that
22:32amalloyrandomness is hard
22:32justin_smithyeah it is
22:33justin_smithdjames: is that skip-list encoding?
22:35djamesjustin_smith: I wasn't intending that. When I last reviewed skip lists, they were probabilistic data structures. I am not saying skip lists are not a possibility, but I don't think they capture the essence of what I need.
22:36djamesI wouldn't be surprised if what I'm talking about isn't particular interesting theoretically speaking. :)
22:36djamesBut I think it probably comes up in practical situations fairly often; e.g. calendar applications and time-based applications. One doesn't want to have to keep a hash map with ALL the keys.
22:37justin_smithyeah, I should have googled first, I get lazy on mobile
22:40justin_smithdjames: I would define a protocol with insert and delete, then try defining a deftype using a list of pairs to represent the domain
22:41justin_smiththen you can easily compare the map baded version (ehere insert snd delete ar assos / dissoc maybe?
22:41djamesjustin_smith: right now, I'm thinking at this level: http://cstheory.stackexchange.com/questions/29516/data-structures-to-compress-similar-values-in-a-map-from-adjacent-keys
22:42djamesbasically, I just want to see what is out there in the same rough problem area
22:44justin_smithahh, so falsr and not present are distinct here
22:46djamesjustin_smith: right
22:46djameshttp://en.wikipedia.org/wiki/Interval_tree is interesting but not quite what I want
22:47djamesactually, it could be what i want
22:49dnolenif you're feeling adventurous just landed Google Closure Module support into master https://github.com/clojure/clojurescript/wiki/Compiler-Options#modules
22:52justin_smithdjames: interval tree was actually the thing I was trying to remember
22:53djamesjustin_smith: I think a binary search tree will work fine -- I put that as my answer. Maybe someone will come along with a better idea. Back to coding!
22:54l1xhey
22:54djamesdnolen: thanks for the recent work on the 'logistical' aspects of CLJS. very helpful.
22:55dnolendjames: np, long out standing enhancement, glad to be finally getting to them.
22:55l1xwhat is the idiomatic way of waiting on a channel operation with a timeout in Clojure?
22:55djamese.g. less "sexy" but valuable
22:55djamesl1x: do you mean with core.async? or some other reference type?
22:55l1xyes, core.async
22:56l1xi found only this -> [[result source] (alts! [stat-chan (timeout channel-timeout)])]
22:56djamesl1x: i was just about to point you to http://clojure.github.io/core.async/#clojure.core.async/timeout
22:57djamesbut I think there are other ways... thinking
22:57l1xthat is the function definition that i am aware of
22:57l1xi am curious about its idiomatic use
23:00djamesl1x: I skimmed some online discussions. have you seen this? http://stackoverflow.com/questions/26487118/more-elegant-way-to-handle-error-and-timeouts-in-core-async
23:00l1xdjames: thanks, i went through all of these
23:01djamesl1x: are you sure the timeout needs to be handled at the core.async level? what kind of timeout are you handling? waiting on an external service?
23:01benmossyeah, what comes to my mind would just be some deref
23:02l1xdjames: exactly waiting on a queue to send a message
23:02djamesl1x: as in, you are waiting on an external message queue?
23:02l1xyes
23:03l1xok, here is how i use it now
23:03l1xhttps://gist.github.com/l1x/e573595307667dfb968f
23:03arrdem$seen bbloom
23:03lazybotbbloom was last seen quittingQuit: Textual IRC Client: www.textualapp.com 4 days and 4 hours ago.
23:03djamesanyhow, I'm not an expert on core.async timeouts, but it seemed like the SO question made sense.
23:03l1xif you found a better way let me know
23:03l1xthanks
23:03djamesl1x: that seems reasonable -- and IIRC is a normal pattern for alts! and timeout
23:04l1xdjames: thanks bro!
23:04l1xi was hoping that somebody collapsed it into a macro
23:05djamesl1x: possibly, but your style is certainly used by others. see https://github.com/search?l=clojure&amp;q=alts%21+timeout&amp;type=Code&amp;utf8=%E2%9C%93
23:06l1xinteresting
23:38l1xhttps://github.com/halgari/clojure-conj-2013-core.async-examples/blob/master/src/clojure_conj_talk/core.clj
23:38l1xthis is so far the best in the subject
23:43l1xeasiest to do something like this, for blocking writes with timeouts -> (alts!! [[channel message] (timeout 150)])
23:44l1xthe return value is [true|nil channel]